Index: apps/plugins/viewers.config
===================================================================
--- apps/plugins/viewers.config	(revision 13360)
+++ apps/plugins/viewers.config	(working copy)
@@ -1,3 +1,4 @@
+pla,viewers/Playlist_Converter,7
 ch8,viewers/chip8,0
 txt,viewers/viewer,1
 nfo,viewers/viewer,1
Index: apps/plugins/Playlist_Converter.c
===================================================================
--- apps/plugins/Playlist_Converter.c	(revision 0)
+++ apps/plugins/Playlist_Converter.c	(revision 0)
@@ -0,0 +1,559 @@
+/*****************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id: Playlist-Converter$
+ *
+ * Copyright (C) 2007 Gerritt Gonzales
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "plugin.h"
+
+/* This macros must always be included. Should be placed at the top by
+   convention, although the actual position doesn't matter */
+PLUGIN_HEADER
+
+/* here is a global api struct pointer. while not strictly necessary,
+   it's nice not to have to pass the api pointer in all function calls
+   in the plugin */
+static struct plugin_api* rb;
+#define plug_QUIT BUTTON_POWER
+#define plug_DISPLAY_YES BUTTON_UP
+#define plug_DISPLAY_NO BUTTON_DOWN
+#define plug_DISPLAY_SPIN_ON BUTTON_RIGHT
+#define plug_DISPLAY_SPIN_OFF BUTTON_LEFT
+#define EXT_UNKNOWN -1
+#define EXT_8 0
+#define EXT_u 1
+#define EXT_a 2
+
+void cleanup(void *parameter)
+{
+    (void)parameter;
+    rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
+}
+
+static int getExt(char *filename)
+{   
+    /* requires additional extention checking here */
+    switch (filename[rb->strlen(filename)-1])
+    {
+        /*m3u8*/
+        case '8': return EXT_8;
+        /*m3u*/
+        case 'u': return EXT_u;
+        /*pla*/
+        case 'a': return EXT_a;
+        /*anything else*/
+        default: return EXT_UNKNOWN;
+    }
+    return EXT_UNKNOWN; /*error*/
+}
+
+int pla2m3u(char *param, char *newparam)
+{
+    int f, f3, fd1, fd3;
+    int button;
+    int SDMMC=0;
+    int WMA=0;
+    int SKIP=0;
+    int size_of=1024; 
+    int size_of_file=0; 
+    int len4, len2, length3, q, r;
+    int A=0;
+    int count=0;
+    int countreturns=0; 
+    int hardcodecount=0; 
+    int minuscount=0; 
+    bool conf=false;
+    bool conf1=false;
+    char buff[256];
+    char intbuff[4];
+    char buffer4[256];
+    char newparam1[256];
+    const char tempy[]={NULL};
+    int inc=0;
+    int dec=0;
+    int len5=0;
+    int Discount=0;
+    int v;
+
+    f = rb->open(param, O_RDONLY);
+    size_of_file=rb->filesize(f);
+    if(size_of>size_of_file)
+    {
+    size_of=size_of_file;
+    }
+    char buffer[size_of+1];
+    char buffertwin[size_of+2];
+    char newbuffertwin[size_of+1];
+    if(f < 0 && size_of<=0) 
+    {
+        rb->splash(HZ*2, " 1 Can't open file %s", param);
+    } else {
+        /*rb->splash(HZ*1, "File opened %s", param);*/
+        button = rb->button_get(false);
+        switch(button)
+        {
+            case(plug_QUIT):
+                rb->close(f);
+                rb->lcd_clear_display();
+                return PLUGIN_OK;
+                break;
+            default:
+                if (rb->default_event_handler_ex(button, cleanup, NULL)
+                    == SYS_USB_CONNECTED)
+                    return PLUGIN_USB_CONNECTED;
+                break;
+        }
+        fd1 = rb->open(newparam, O_CREAT|O_WRONLY|O_TRUNC); 
+        if(fd1 < 0) 
+        {
+            rb->splash(HZ*2, " 2 Can't open file %s", newparam);
+        }else{
+            while(inc<size_of_file)/* keep reading file */
+            { 
+                /* clear arrays of characters */
+                for( v=0; v<size_of+1; v++ )
+                {
+                    newbuffertwin[v] =(char)*tempy;
+                    buffertwin[v] =(char)*tempy;
+                    buffer[v] =(char)*tempy;
+                }
+                dec=rb->read(f, buffer, size_of);
+                if(dec>0)
+                {
+                    rb->utf16LEdecode(buffer, newbuffertwin, dec);
+
+                    len5=(rb->strlen(newbuffertwin));
+                    newbuffertwin[len5+1] =(char)*tempy;
+                    rb->snprintf(buffertwin, len5+1, "%s", newbuffertwin);
+                    buffertwin[len5+1] =(char)*tempy;
+                    inc=inc+dec;
+
+                    len2=(rb->strlen(buffertwin));
+                    for( r=0; r<=len2; r++ )
+                    {
+                        /* change sansa \ to rockbox / */
+                        if( buffertwin[r] == '\\')
+                        {buffertwin[r] = '/';}
+                        /* line count */
+                        if( buffertwin[r] == '\n')
+                        {countreturns++;}
+                    }
+                    /*rb->splash(HZ*1, buffertwin);*/
+                    rb->fdprintf(fd1, "%s", buffertwin);
+                }
+            }
+        }
+            rb->close(f);
+            rb->close(fd1);
+            /* sleep after closing files before opening again */
+            rb->sleep(HZ*1);
+            /* rockbox playlist from here down */
+            length3=rb->strlen(newparam);
+            rb->snprintf(newparam1, length3+2, "%s8", newparam);
+            /* rb->splash(HZ*2, "File EXT changed %s", newparam1);*/
+
+            f3 = rb->open(newparam, O_RDONLY);
+            if(f3 < 0) 
+            {
+                rb->splash(HZ*2, "Can't Open File %s ", newparam);
+            } 
+            fd3 = rb->open(newparam1, O_CREAT|O_WRONLY|O_TRUNC); 
+            if(fd3 < 0) 
+            {
+                rb->splash(HZ*2, "Can't Open File %s ", newparam1);
+            }else{ 
+                rb->lcd_puts_scroll(0,7, newparam1);
+                /* rb->lcd_update();*/
+                while(rb->read_line(f3, buffer4, 256))
+                {
+                    hardcodecount++;
+                    /* skip first 3 lines here */
+                    if (hardcodecount>3)
+                    {
+                        count++;
+                        /* skip leading "HARP, " */
+                        if(buffer4[0] == 'H')
+                        {
+                            A=6;
+                            /* rb->splash(HZ*1, "HARP"); */
+			    SKIP=1;
+                        }
+                        /* check for "SDMMC, " as well  */
+                        if(buffer4[0] == 'S')
+                        {
+                            A=7;
+                            /* rb->splash(HZ*1, "SDMMC"); */
+                            /* to skip music on the card until it works */
+                            /* will aslo be able to add whatever prefix */
+                            /* required for the card */
+                            /* Do not write out files frome the SD */
+                            /* card as not working yet */  
+                            SDMMC=1;
+			    SKIP=1;
+                        }
+
+                        len4=rb->strlen(buffer4);
+if (buffer4[rb->strlen(buffer4)-3]=='w'|| buffer4[rb->strlen(buffer4)-3]=='W')
+                        {
+                            /* rb->splash(HZ*2, "WMA file"); */ 
+                            WMA=1;
+			    SKIP=1;
+                        }
+                        for(q=A; q< len4 && q<256; q++ )
+                        {
+                            buff[q-A]=buffer4[q];
+                        }
+                        buff[q-A]=(char)*tempy;
+
+                        if((WMA==0)&&(SKIP!=0))
+                        {
+                            if(count<=(countreturns-2)){
+                                button = rb->button_get(false);
+                                switch(button){
+                                    case (plug_DISPLAY_NO):
+                                        conf=false;
+                                        rb->lcd_puts(8,9, "OFF");
+                                        break;
+                                    case (plug_DISPLAY_YES):
+                                        conf=true;
+                                        rb->lcd_puts(8,9, "ON");
+                                        break;
+                                    case (plug_DISPLAY_SPIN_OFF):
+                                        conf1=false;
+                                        rb->lcd_puts(8,9, "OFF");
+                                        break;
+                                    case (plug_DISPLAY_SPIN_ON):
+                                        conf1=true;
+                                        rb->lcd_puts(8,9, "SPIN ON");
+                                        break;
+                                }
+                                if (conf==true){
+                                    rb->splash(HZ*1, buff);
+                                }
+                                if(conf1==true){
+                                    rb->splash(HZ*0, "-");
+                                    rb->splash(HZ*0, "\\");
+                                    rb->splash(HZ*0, "-");
+                                    rb->splash(HZ*0, "/");
+                                }
+                                if(SDMMC==1){
+				SDMMC=0;
+				/* write out prefix for SD card */
+                                rb->fdprintf(fd3, "/<MMC1>/%s\n", buff);
+				}else{
+                                /* print song path to m3u8 file */
+                                rb->fdprintf(fd3, "/%s\n", buff);
+				}
+                                /* song count display here */
+                                Discount++;
+                                rb->snprintf(intbuff, 4, "%d", Discount);
+                                rb->lcd_puts(7,8,  intbuff);
+                                rb->lcd_update();
+                            }
+                        }
+			WMA=0;
+			SKIP=0;
+                    }
+                }
+            }
+            rb->close(f3);
+            rb->remove(newparam); 
+            rb->close(fd3);
+            if(fd3<0)
+            {
+                rb->splash(HZ*2, "Unable to writer file %s !", newparam1);
+            }else{
+               if((count-1)==minuscount)
+               {
+                   rb->splash(HZ*2, "No Files in Playlist");
+                   rb->remove(newparam1); 
+               }
+         }
+    }
+    rb->button_get_w_tmo(250);
+    return 1;
+}
+
+int m3u2pla(char *param, char *newparam){
+    int f;
+    int fd1=0;
+    int len;
+    int len2;
+    int button;
+    int count=0;
+    int offset=0;
+    int y, j, k, t, q;
+    int size_of_file=0; 
+    bool conf=false;
+    bool conf1=false;
+    char buff[256];
+    char intbuff[4];
+    char buffprx[9];
+    char buff_card[10];
+    char buffer[256];
+    char buffheader[31];
+    char buffertwin[256];
+    const char tempy[]={NULL};
+
+    f = rb->open(param, O_RDONLY);
+
+    if(f < 0) 
+    {
+        rb->splash(HZ*2, "Can't open file %s", param);
+    } else {
+        size_of_file=rb->filesize(f);
+        /* rb->splash(HZ*1, "%s File opened", param); */
+        button = rb->button_get(false);
+        switch(button)
+        {
+            case(plug_QUIT):
+                cleanup(NULL);
+                rb->close(f);
+                rb->lcd_clear_display();
+                return PLUGIN_OK;
+                break;
+                
+            default:
+                if (rb->default_event_handler_ex(button, cleanup, NULL)
+                    == SYS_USB_CONNECTED)
+                    return PLUGIN_USB_CONNECTED;
+                break;
+        }
+        fd1 = rb->open(newparam, O_CREAT|O_WRONLY|O_TRUNC); 
+        
+        /* build header and prefix */
+        rb->snprintf(buffprx, 9, "HARP, \r\n" );
+        rb->snprintf(buff_card, 10, "SDMMC, \r\n" );
+        rb->snprintf(buffheader, 31, "PLP PLAYLIST\r\nVERSION 1.20\r\n\r\n");
+        
+        /*rb->splash(HZ*1, "Header being output...");*/
+        for( t=0; t< 30; t++ )
+        {
+            rb->write(fd1, &buffheader[t], 1);
+            rb->write(fd1, tempy, sizeof(tempy));
+
+        }
+        rb->lcd_puts_scroll(0,7, newparam);
+        while(rb->read_line(f, buffer, 256))
+        {
+        button = rb->button_get(false);
+        switch(button)
+        {
+            case (plug_DISPLAY_NO):
+                conf=false;
+                rb->lcd_puts(8,9, "OFF");
+                break;
+            case (plug_DISPLAY_YES):
+                conf=true;
+                rb->lcd_puts(8,9, "ON");
+                break;
+            case (plug_DISPLAY_SPIN_OFF):
+                conf1=false;
+                rb->lcd_puts(8,9, "OFF");
+                break;
+            case (plug_DISPLAY_SPIN_ON):
+                conf1=true;
+                rb->lcd_puts(8,9, "SPIN ON");
+                break;
+        }
+            /* only really neaded to convert m3u files with tag info in them */
+            if( buffer[0] != '#')
+            {
+                if (conf==true)
+                {
+                    rb->splash(HZ*1, buffer);
+                }
+                if(conf1==true)
+                {
+                    rb->splash(HZ*0, "-");
+                    rb->splash(HZ*0, "\\");
+                    rb->splash(HZ*0, "-");
+                    rb->splash(HZ*0, "/");
+                }
+                
+                len2=(rb->strlen(buffer));
+                for( y=0; y< len2-1; y++ )
+                {
+                /* change unix / to sansa \    */
+                    if( buffer[y] == '/')
+                    {buffer[y] = '\\';}
+                }
+                rb->snprintf(buffertwin, len2+3, "%s\r\n", buffer);
+                len=rb->strlen(buffertwin);
+		/* set up for card or main  memory*/
+                if ((buffertwin[1]=='<')&&(buffertwin[2]=='M')){
+		    offset=8;
+                    /* prefix to file 'SDMMC, ' */
+                    for( k=0; k< 7; k++ ){
+                        rb->write(fd1, &buff_card[k], 1);
+                        rb->write(fd1, tempy, sizeof(tempy));
+                    }
+                }else{
+		    offset=1;
+                    /* prefix to file 'HARP, ' */
+                    for( k=0; k< 6; k++ ){
+                        rb->write(fd1, &buffprx[k], 1);
+                        rb->write(fd1, tempy, sizeof(tempy));
+                    }
+                }
+                /* skip leading slash and <MMC1>/ if required */
+                for(q=offset; q< len && q<256; q++ )
+                {
+                    buff[q-offset] = buffertwin[q];
+                }
+                buff[q-offset]=(char)*tempy;
+
+                len=rb->strlen(buff);
+                for( j=0; j< len; j++ )
+                {
+                    rb->write(fd1, &buff[j], 1);
+                    rb->write(fd1, tempy, sizeof(tempy));
+                }
+                count++;
+                rb->snprintf(intbuff, 6, "%d", count);
+                rb->lcd_puts(7,8,  intbuff);
+                rb->lcd_update();
+            }
+        }
+    }
+    rb->close(f);
+    rb->close(fd1);
+    if(fd1<0)
+    {
+        rb->splash(HZ*2, "Unable to write file!");
+    }
+    rb->button_get_w_tmo(250);
+    return 1;
+}
+
+/* this is the plugin entry point */
+enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
+{
+
+    rb = api;
+    const char tempy[]={NULL};
+    char newparameter[256];
+    int length, button, w, h;
+    bool conf=false;
+    bool prev_show_statusbar;
+
+    prev_show_statusbar = rb->global_settings->statusbar;
+    rb->global_settings->statusbar = false;
+
+    if (!parameter) 
+    {  
+        rb->splash(HZ*2, "Select a file to convert and use Open With..."); 
+    }else{
+
+        rb->lcd_getstringsize("A",&w,&h);
+        length=rb->strlen((char*)parameter);
+        rb->snprintf(newparameter, length+1, "%s", (char*)parameter);
+        rb->show_logo();
+        rb->lcd_clear_display();
+        rb->lcd_puts(0,0,"* Sansa Playlist Converter *");
+        rb->lcd_drawline(0,h+5,LCD_WIDTH-1,h+5);
+        rb->lcd_puts(0,2,"* Up     Display ON");
+        rb->lcd_puts(0,3,"* Down   Display OFF");
+        rb->lcd_puts(0,4,"* Power  QUIT");
+        rb->lcd_puts(0,6, "File Name:");
+        rb->lcd_puts(0,8, "Song #:");
+        rb->lcd_puts(0,9, "Display:");
+        rb->lcd_puts(9,9, "OFF");
+
+        rb->lcd_drawline(0,LCD_HEIGHT-h-7,LCD_WIDTH-1,LCD_HEIGHT-h-7);
+        rb->lcd_putsxy(62,(LCD_HEIGHT-h-5), " * By GRaTT *");
+
+        rb->lcd_update();
+        rb->button_get_w_tmo(250);
+
+        button = rb->button_get(false);
+        switch(button)
+        {
+            case(plug_QUIT):
+                cleanup(NULL);
+                rb->lcd_clear_display();
+                return PLUGIN_OK;
+                break;
+
+            case (plug_DISPLAY_NO):
+                conf=false;
+                rb->lcd_puts(8,9, "OFF");
+                break;
+
+            case (plug_DISPLAY_YES):
+                conf=true;
+                rb->lcd_puts(8,9, "ON");
+                break;
+
+            case (plug_DISPLAY_SPIN_OFF):
+                conf=false;
+                rb->lcd_puts(8,9, "OFF");
+                break;
+
+            case (plug_DISPLAY_SPIN_ON):
+                conf=true;
+                rb->lcd_puts(8,9, "SPIN ON");
+                break;
+
+            default:
+                if (rb->default_event_handler_ex(button, cleanup, NULL)
+                    == SYS_USB_CONNECTED)
+                    return PLUGIN_USB_CONNECTED;
+                break;
+
+        }
+        switch (getExt(parameter))
+        {
+            case EXT_8:rb->lcd_putsxy(0,(LCD_HEIGHT-h-5), "* Converting m3u8 to pla *");
+            /* change ext to .pla */
+            newparameter[rb->strlen(newparameter)-4]='p';
+            newparameter[rb->strlen(newparameter)-3]='l';
+            newparameter[rb->strlen(newparameter)-2]='a';
+            newparameter[rb->strlen(newparameter)-1]=(char)*tempy;
+            /* function call here for conversion */
+            m3u2pla(parameter, newparameter);
+            break;
+
+            case EXT_u:rb->lcd_putsxy(0,(LCD_HEIGHT-h-5), "* Converting m3u to pla *");
+            /* chnage ext to .pla */
+            newparameter[rb->strlen(newparameter)-3]='p';
+            newparameter[rb->strlen(newparameter)-2]='l';
+            newparameter[rb->strlen(newparameter)-1]='a';
+            newparameter[rb->strlen(newparameter)-0]=(char)*tempy;
+            /* function call here for conversion */
+            m3u2pla(parameter, newparameter);
+            break;
+
+            case EXT_a:rb->lcd_putsxy(0,(LCD_HEIGHT-h-5), "* Converting pla to m3u8 *");
+            /* chnage ext to .m3u */
+            newparameter[rb->strlen(newparameter)-3]='m';
+            newparameter[rb->strlen(newparameter)-2]='3';
+            newparameter[rb->strlen(newparameter)-1]='u';
+            newparameter[rb->strlen(newparameter)-0]=(char)*tempy;
+            /* function call here for conversion */
+            pla2m3u(parameter, newparameter);
+            break;
+
+            case EXT_UNKNOWN:rb->splash(HZ*2, "Select a (.m3u/8) or (.pla)"); 
+            return PLUGIN_OK;
+        }
+    }
+    rb->lcd_putsxy(0,(LCD_HEIGHT-h-5), " * Convertion * By GRaTT  ");
+    rb->lcd_update();
+    rb->global_settings->statusbar = prev_show_statusbar;
+    rb->button_get_w_tmo(250);
+    return PLUGIN_OK;
+}
Index: apps/plugins/SOURCES
===================================================================
--- apps/plugins/SOURCES	(revision 13360)
+++ apps/plugins/SOURCES	(working copy)
@@ -1,4 +1,5 @@
 /* plugins common to all models */
+Playlist_Converter.c
 battery_bench.c
 chessclock.c
 credits.c
