Subversion Repositories mdb

Rev

Rev 30 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2015 by Andreas Theofilu <andreas@theosys.at>
 *
 * All rights reserved. No warranty, explicit or implicit, provided.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Andreas Theofilu and his suppliers, if any.
 * The intellectual and technical concepts contained
 * herein are proprietary to Andreas Theofilu and its suppliers and
 * may be covered by European and Foreign Patents, patents in process,
 * and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Andreas Theofilu.
 */
MODULE_NAME='MDB_UI'    (dev dvTPs[], dev vdvMDB, char IP[], char path[], integer nIndex[])

#include 'mSNAPI'

DEFINE_TYPE
        struct ST_SONG
        {
                integer nID;
                char sTitle[128];
                char sArtist[128];
                char sAlbum[128];
                char sGenre[128];
                char sCover[64];
        };

DEFINE_CONSTANT
        constant integer MAX_LINES =            5;

        constant char sPopupList[] =            'MFp_MDB_list';
        constant char sPopupAudio[] =           'MFp_MDB_audio';
        constant char sPopupDetail[] =          'MFp_MDB_detail';
        constant char sPopupMenu[] =            'MFp_MDB_menu';
        constant char sPopupUsers[] =           'MFp_MDB_users';
        constant char sPopupSelUser[] =         'MFp_MDB_select_user';

        constant integer BTN_SCROLLBAR =        256;

        constant integer BTN_SAVE =                     340;
        constant integer BTN_DELETE =           341;
        constant integer BTN_NOW_PLAYING =      342;
        constant integer BTN_SEARCH =           343;
        constant integer BTN_QUEUE =            349;

        constant integer BTN_TITLE =            350;
        constant integer BTN_ARTIST =           351;
        constant integer BTN_GENRE =            352;
        constant integer BTN_ALBUM =            353;
        constant integer BTN_PLAYLIST =         354;
        constant integer BTN_RETURN =           355;
        constant integer BTN_RESET =            356;

        constant integer BTN_LINE1_PIC =        301;
        constant integer BTN_LINE1_LINE =       321;
        constant integer BTN_LINE2_PIC =        302;
        constant integer BTN_LINE2_LINE =       322;
        constant integer BTN_LINE3_PIC =        303;
        constant integer BTN_LINE3_LINE =       323;
        constant integer BTN_LINE4_PIC =        304;
        constant integer BTN_LINE4_LINE =       324;
        constant integer BTN_LINE5_PIC =        305;
        constant integer BTN_LINE5_LINE =       325;
        constant integer BTN_LINE6_PIC =        306;
        constant integer BTN_LINE6_LINE =       326;
        constant integer BTN_LINE7_PIC =        307;
        constant integer BTN_LINE7_LINE =       327;
        constant integer BTN_LINE8_PIC =        308;
        constant integer BTN_LINE8_LINE =       328;
        constant integer BTN_LINE9_PIC =        309;
        constant integer BTN_LINE9_LINE =       329;
        constant integer BTN_LINE10_PIC =       310;
        constant integer BTN_LINE10_LINE =      330;

        constant integer BTN_MENU1 =            261;
        constant integer BTN_MENU2 =            262;
        constant integer BTN_MENU3 =            263;
        constant integer BTN_MENU4 =            264;
        constant integer BTN_MENU5 =            265;
        constant integer BTN_MENU6 =            266;
        constant integer BTN_MENU7 =            267;
        constant integer BTN_MENU8 =            268;
        constant integer BTN_MENU9 =            269;
        constant integer BTN_MENU10 =           270;

        constant integer BTN_DETAIL_BACK =      400;
        constant integer BTN_USER_OK =          401;
        constant integer BTN_USER_CANCEL =      402;

        constant integer TEXT_TITLE =           1001;
        constant integer TEXT_PROGRES =         1002;
        constant integer TEXT_MENU_TITLE =      1003;

        constant integer TEXT_DETAIL_TITLE =    1011;
        constant integer TEXT_DETAIL_ARTIST =   1012;
        constant integer TEXT_DETAIL_ALBUM =    1013;
        constant integer TEXT_DETAIL_GENRE =    1014;
        constant integer TEXT_DETAIL_TIME_PROG =1015;
        constant integer TEXT_DETAIL_TIME_TOTAL=1016;

        constant integer TEXT_INPUT_UNAME =             1021;
        constant integer TEXT_INPUT_PLAYLIST =  1022;
        constant integer TEXT_INPUT_SEARCH =    1023;

        constant integer PIC_COVER =                    300;
        constant integer PIC_BASE =                             300;

        constant integer LVL_PROGRES =                  1;
        constant integer LVL_SCROLLBAR =                7;

        constant char TOK_TXT_NONE[] =                  'NONE';
        constant char TOK_TXT_TITLE[] =                 'TITLE';
        constant char TOK_TXT_ARTIST[] =                'ARTIST';
        constant char TOK_TXT_ALBUM[] =                 'ALBUM';
        constant char TOK_TXT_GENRE[] =                 'GENRE';
        constant char TOK_TXT_QUEUE[] =                 'QUEUE';
        constant char TOK_TXT_PLAYLIST[] =              'PLAYLIST';
        constant char TOK_TXT_SEARCH[] =                'SEARCH';

        constant integer TOK_NONE =                             0;
        constant integer TOK_TITLE =                    1;
        constant integer TOK_ARTIST =                   2;
        constant integer TOK_ALBUM =                    3;
        constant integer TOK_GENRE =                    4;
        constant integer TOK_QUEUE =                    5;
        constant integer TOK_PLAYLIST =                 6;
        constant integer TOK_SEARCH =                   7;

        constant integer TODO_USER_SELECT =             1;              // select a user
        constant integer TODO_USER_LIST_PLAYLIST =      2;              // List the playlist
        constant integer TODO_USER_SAVE_PLAYLIST =      3;              // Save queue to playlist
        constant integer TODO_USER_PLAYLIST_QUEUE = 4;          // Move a playlist to the queue
        constant integer TODO_SEARCH =                          5;              // Search for titles, artists, ...

        constant integer DIR_OPEN =                             1;
        constant integer DIR_CLOSE =                    2;

        constant integer nNavigation[] =
        {
                BTN_SAVE,
                BTN_DELETE,
                BTN_NOW_PLAYING,
                BTN_QUEUE,
                BTN_TITLE,
                BTN_ARTIST,
                BTN_GENRE,
                BTN_ALBUM,
                BTN_PLAYLIST,
                BTN_SEARCH,
                BTN_RESET
        };

        constant integer nMenu[] =
        {
                BTN_MENU1,
                BTN_MENU2,
                BTN_MENU3,
                BTN_MENU4,
                BTN_MENU5,
                BTN_MENU6,
                BTN_MENU7,
                BTN_MENU8,
                BTN_MENU9,
                BTN_MENU10
        };

        constant integer nBtns[] =
        {
                PLAY,
                STOP,
                PAUSE,
                FFWD,                                           // Jump forward
                REW,                                            // jump backward
                SREV,                                           // Skip backward
                SFWD,                                           // Skip forward
                MENU_THUMBS_DN,
                MENU_THUMBS_UP,
                MEDIA_RANDOM,
                MEDIA_REPEAT,
                MENU_BACK,
                BTN_RETURN
        };

        constant integer nBtnUser[] =
        {
                BTN_DETAIL_BACK,
                BTN_USER_OK,
                BTN_USER_CANCEL,
                TEXT_INPUT_UNAME,
                TEXT_INPUT_PLAYLIST
        };

        constant integer nLines[] =
        {
                BTN_LINE1_PIC,
                BTN_LINE1_LINE,
                BTN_LINE2_PIC,
                BTN_LINE2_LINE,
                BTN_LINE3_PIC,
                BTN_LINE3_LINE,
                BTN_LINE4_PIC,
                BTN_LINE4_LINE,
                BTN_LINE5_PIC,
                BTN_LINE5_LINE,
                BTN_LINE6_PIC,
                BTN_LINE6_LINE,
                BTN_LINE7_PIC,
                BTN_LINE7_LINE,
                BTN_LINE8_PIC,
                BTN_LINE8_LINE,
                BTN_LINE9_PIC,
                BTN_LINE9_LINE,
                BTN_LINE10_PIC,
                BTN_LINE10_LINE
        };

        constant integer PLAYER_PLAY =          1;
        constant integer PLAYER_STOP =          2;
        constant integer PLAYER_PAUSE =         3;

        constant char sIconTitle[] = 'Song_45x45';
        constant char sIconAlbum[] = 'Album_45x45';
        constant char sIconGenre[] = 'Genre_45x45';
        constant char sIconArtist[] = 'Artist_45x45';
        constant char sIconQueue[] = 'Queue_45x45';
        constant char sIconPlaylist[] = 'Playlist_45x45';

/*      constant char sIconsMusic[7][24] =
        {
                sIconTitle,
                sIconArtist,
                sIconAlbum,
                sIconGenre,
                sIconQueue,
                sIconPlaylist,
                sIconTitle
        };
*/
        constant char sIconsMusic[7][24] =
        {
                'Song_45x45',
                'Artist_45x45',
                'Album_45x45',
                'Genre_45x45',
                'Queue_45x45',
                'Playlist_45x45',
                'Song_45x45'
        };

DEFINE_VARIABLE
        volatile integer nStart;                                // Index position of current position in list.
        volatile integer nOldStart;                             // Saves the previous value of nStart if a folder is opened
        volatile integer nTotal;                                // Total number of data
        volatile integer nPage;                                 // The type of the page: TOK_TITLE, ...
        volatile integer nOldPage;                              // The type of the previous page. Needed for search.
        volatile integer nSearch;                               // 1 = Search is active
        volatile char    sSearchFor[128];               // The expression to search for
        volatile integer nPlayStatus;                   // Status of the player
        volatile ST_SONG stSong[MAX_LINES];             // The register of currently showed songs
        volatile integer nSongIdx;                              // The index of the song pointer
        volatile char    sActPlaylist[128];             // The name of the actual playlist
        volatile integer nLastPressedLine;              // The number of the line pressed last
        volatile integer nLastPressedMenu;              // The number of the menu line pressed last
        volatile integer nKeyboard[50];                 // 1 = Keyboard active
        volatile char    sActUser[128];                 // The name of the actual loaded user
        volatile char    sInputUser[128];               // Username in user dialog popup
        volatile char    sInputPlaylist[128];   // Name of playlist in user dialog popup
        volatile integer nFolder;                               // 0 = Top level of list, 1 = Folder opened
        volatile char    sActFolder[128];               // The name of the actual selected folder
        volatile integer nScrollbarPressed[50]; // 1 = User is sliding the scrollbar
        volatile integer nScrollbarLvl;                 // The level of the scrollbar when user releases the scrollbar
        volatile integer nRepeat;                               // 1 = repeat on, 0 = repeat off
        volatile integer nRandom;                               // 1 = random on, 0 = random off
        volatile integer nToDo;                                 // What to do next
        volatile char _strTok[10][256];


// DecodeURL: Undo URL encoding on a data segment as necessary for CLI protocol
//      (Note: Distructive for input; copy str before call if needed)
//   str: String to be decoded
define_function char[1024] DecodeURL(char oldStr[])
{
stack_var char str[1024];
stack_var char newStr[1024];
stack_var char strSegment[1024];
stack_var char strHex[2];

    str = oldStr;
    // Loop through string looking for '%' prefix characters
    strSegment = remove_string(str, '%', 1);

    while (length_array(strSegment) != 0) 
        {
                // Strip off '%' character from string segment, fetch HEX ASCII byte, reconstruct
                set_length_array(strSegment, length_array(strSegment) - 1);
                strHex = Left_String(str, 2);
                str = Right_String(str, length_array(str) - 2);
                newStr = "newStr,strSegment,HexToI(strHex)";

                strSegment = remove_string(str, '%', 1);
    }

    newStr = "newStr,str";
    return newStr;
}

define_function char[1024] EncodeURL(char oldStr[])
{
stack_var char str[1024];
stack_var char replace[64];
stack_var integer len;
stack_var integer i;
stack_var integer j;
stack_var integer flag;

        replace = "':;<>"% ',$27";
        len = length_string(oldStr);
        str = '';

        for (i = 1; i <= len; i++)
        {
                flag = false;

                for (j = 1; j <= length_string(replace); j++)
                {
                        if (oldStr[i] == replace[j])
                        {
                                str = "str,'%',format('%02X', oldStr[i])";
                                flag = true;
                                break;
                        }
                }

                if (!flag)
                        str = "str,mid_string(oldStr, i, 1)";
        }

        return str;
}

define_function integer strtok(char str[], char tok[])
{
stack_var integer i;
stack_var integer idx;

        idx = 1;

        for (i = 1; i <= 10; i++)
                _strTok[i] = '';

        i = find_string(str, tok, 1);

        while (i && idx <= 10)
        {
                if (i > 1)
                        _strTok[idx] = left_string(str, i - length_string(tok));
                else
                        _strTok[idx] = '';

                remove_string(str, tok, 1);
                i = find_string(str, tok, 1);
                idx++;
        }

        if (idx <= 10)
                _strTok[idx] = str;

        return idx;
}

define_function char[256] getStrTok(integer idx)
{
        if (idx && idx <= 10)
                return _strTok[idx];

        return '';
}

define_function displayProgresBar(char sTimeA[], char sTimeB[])
{
stack_var double secA;
stack_var double secB;
stack_var integer pos;
stack_var integer hour;
stack_var integer min;
stack_var integer sec;

        if (length_string(sTimeA) > 5)
        {
                hour = atoi(left_string(sTimeA, 2));
                min = atoi(mid_string(sTimeA, 4, 2));
                sec = atoi(mid_string(sTimeA, 7, 2));
                secA = type_cast(hour * 3600 + min * 60 + sec);
        }
        else
        {
                min = atoi(mid_string(sTimeA, 1, 2));
                sec = atoi(mid_string(sTimeA, 4, 2));
                secA = type_cast(min * 60 + sec);
        }

        if (length_string(sTimeB) > 5)
        {
                hour = atoi(left_string(sTimeB, 2));
                min = atoi(mid_string(sTimeB, 4, 2));
                sec = atoi(mid_string(sTimeB, 7, 2));
                secB = type_cast(hour * 3600 + min * 60 + sec);
        }
        else
        {
                min = atoi(mid_string(sTimeB, 1, 2));
                sec = atoi(mid_string(sTimeB, 4, 2));
                secB = type_cast(min * 60 + sec);
        }

        pos = type_cast(100.0 / secB * secA);
        send_level dvTPs, LVL_PROGRES, pos;
}

define_function setPopup(integer dir, char sPg[])
{
stack_var char pop[16];
stack_var integer i;
stack_var integer anz;

        if (DIR_OPEN)
                pop = '@PPN-';
        else
                pop = '@PPF-';

        anz = max_length_string(nIndex);

        for (i = 1; i <= anz; i++)
        {
                if (nIndex[i])
                        send_command dvTPs[i],"pop,sPg";
        }
}

define_function clearAllLogos()
{
        send_command dvTPs,"'^SHO-',itoa(BTN_LINE1_PIC),'.',itoa(BTN_LINE1_PIC+MAX_LINES-1),',0'";
}

define_function clearLogo(integer pos)
{
        if (!pos || pos > MAX_LINES)
                return;

        send_command dvTPs,"'^SHO-',itoa(BTN_LINE1_PIC+pos-1),',0'";
}

define_function setLogo(char sFile[], integer pos)
{
stack_var char sHost[64];
stack_var char sPath[512];
stack_var integer i;

        if (pos > MAX_LINES)
                return;

        sHost = IP;
        sPath = path;
        send_command dvTPs,"'^SHO-',itoa(PIC_BASE+pos),',1'";

        if (!length_string(sFile))
        {
                if (nPage && pos && nPage != TOK_QUEUE)
                        send_command dvTPs,"'^BBR-',itoa(PIC_BASE+pos),',0,',sIconsMusic[nPage]";
                else if (nPage && pos)
                        send_command dvTPs,"'^BBR-',itoa(PIC_BASE+pos),',0,',sIconsMusic[1]";
                else
                        send_command dvTPs,"'^BBR-',itoa(PIC_COVER),',0,',sIconsMusic[1]";

                return;
        }

        if (pos && pos <= MAX_LINES)
        {
                send_command dvTPs,"'^RMF-XBMC_Audio',itoa(pos),',%H',sHost,'%A',sPath,'%F',sFile";
                send_command dvTPs,"'^BBR-',itoa(PIC_BASE+pos),',0,XBMC_Audio',itoa(pos)";
        }
        else
        {
                send_command dvTPs,"'^RMF-XBMC_AudioCover,%H',sHost,'%A',sPath,'%F',sFile";
                send_command dvTPs,"'^BBR-',itoa(PIC_COVER),',0,XBMC_AudioCover'";
        }
}

define_function clearPage()
{
        clearAllLogos();
        send_command dvTPs,"'^TXT-',itoa(BTN_LINE1_LINE),'.',itoa(BTN_LINE1_LINE+MAX_LINES-1),',0,'";
}

define_function char[32] requestActualPage()
{
        return requestPage(nPage);
}

define_function char[32] requestPage(integer pg)
{
stack_var char sPage[32];

        sPage = '';

        if (pg == TOK_NONE)
                return sPage;

        switch(pg)
        {
                case TOK_TITLE:         sPage = TOK_TXT_TITLE;
                case TOK_ALBUM:         sPage = TOK_TXT_ALBUM;
                case TOK_ARTIST:        sPage = TOK_TXT_ARTIST;
                case TOK_GENRE:         sPage = TOK_TXT_GENRE;
                case TOK_QUEUE:         sPage = TOK_TXT_QUEUE;
                case TOK_PLAYLIST:      sPage = TOK_TXT_PLAYLIST;
                case TOK_SEARCH:        sPage = TOK_TXT_SEARCH;
        }

        return sPage;
}

define_function char[32] requestTitle(integer tok)
{
stack_var char sPage[32];

        sPage = '';

        switch(nPage)
        {
                case TOK_NONE:          sPage = 'No list';
                case TOK_TITLE:         sPage = 'Title list';
                case TOK_ALBUM:         sPage = 'Album list';
                case TOK_ARTIST:        sPage = 'Artist list';
                case TOK_GENRE:         sPage = 'Genre list';
                case TOK_QUEUE:         sPage = 'Queue';
                case TOK_PLAYLIST:      sPage = 'Playlists';
                case TOK_SEARCH:        sPage = "'Search for ',sSearchFor";
        }

        return sPage;
}

define_function char[256] getPageLine(integer line)
{
        if (!line || line > MAX_LINES)
                return '';

        switch(nPage)
        {
                case TOK_TITLE:         return stSong[line].sTitle;
                case TOK_ARTIST:        return stSong[line].sArtist;
                case TOK_ALBUM:         return stSong[line].sAlbum;
                case TOK_GENRE:         return stSong[line].sGenre;
        }

        return '';
}

define_function setPageLine(integer line, char str[])
{
        if (!line || line > MAX_LINES)
                return;

        switch(nPage)
        {
                case TOK_TITLE:         stSong[line].sTitle = str;
                case TOK_ARTIST:        stSong[line].sArtist = str;
                case TOK_ALBUM:         stSong[line].sAlbum = str;
                case TOK_GENRE:         stSong[line].sGenre = str;
        }
}

define_function clearPageLine(integer line)
{
        if (!line || line > MAX_LINES)
                return;

        stSong[line].nID = 0;
        stSong[line].sTitle = '';
        stSong[line].sArtist = '';
        stSong[line].sAlbum = '';
        stSong[line].sGenre = '';
        stSong[line].sCover = '';
}

define_function integer setActualPage(char pg[])
{
        nPage = TOK_NONE;

        select
        {
                active (pg == TOK_TXT_TITLE):           nPage = TOK_TITLE;
                active (pg == TOK_TXT_ARTIST):          nPage = TOK_ARTIST;
                active (pg == TOK_TXT_ALBUM):           nPage = TOK_ALBUM;
                active (pg == TOK_TXT_GENRE):           nPage = TOK_GENRE;
                active (pg == TOK_TXT_QUEUE):           nPage = TOK_QUEUE;
                active (pg == TOK_TXT_PLAYLIST):        nPage = TOK_PLAYLIST;
                active (pg == TOK_TXT_SEARCH):          nPage = TOK_SEARCH;
        }

        switch(nPage)
        {
                case TOK_TITLE:
                case TOK_ALBUM:
                case TOK_ARTIST:
                case TOK_GENRE:
                case TOK_PLAYLIST:
                case TOK_SEARCH:
                        setPopup(DIR_OPEN, sPopupAudio);
                break;

                case TOK_QUEUE:
                        setPopup(DIR_OPEN, sPopupList);
                break;
        }

        switch(nPage)
        {
                case TOK_TITLE:         send_command dvTPs, "'^TXT-',itoa(TEXT_TITLE),',0,Titles'";
                case TOK_ARTIST:        send_command dvTPs, "'^TXT-',itoa(TEXT_TITLE),',0,Artists'";
                case TOK_ALBUM:         send_command dvTPs, "'^TXT-',itoa(TEXT_TITLE),',0,Albums'";
                case TOK_GENRE:         send_command dvTPs, "'^TXT-',itoa(TEXT_TITLE),',0,Genres'";
                case TOK_QUEUE:         send_command dvTPs, "'^TXT-',itoa(TEXT_TITLE),',0,Queue'";
                case TOK_PLAYLIST:      send_command dvTPs, "'^TXT-',itoa(TEXT_TITLE),',0,Playlist'";
                case TOK_SEARCH:        send_command dvTPs, "'^TXT-',itoa(TEXT_TITLE),',0,Search for ',sSearchFor";
        }

        return nPage;
}

define_function displayPageInfo(integer st, integer tot)
{
stack_var integer bis;

        if (st)
        {
                bis = st + MAX_LINES - 1;
                send_command dvTPs, "'^TXT-',itoa(TEXT_PROGRES),',0,',itoa(st),' to ',itoa(bis),' of ',itoa(tot)";
        }
        else
                send_command dvTPs, "'^TXT-',itoa(TEXT_PROGRES),',0,'";

        // Scrollbar initialisieren
        if (tot && st <= tot)
                bis = type_cast(100.0 / tot * st);
        else
                bis = 0;

        send_level dvTPs, LVL_SCROLLBAR, bis;
}

define_function displaySong(integer idx)
{
        if (!idx || idx > MAX_LINES)
                return;

        send_command dvTPs, "'^TXT-',itoa(BTN_LINE1_LINE+idx-1),',0,',stSong[idx].sTitle,$0d,$0a,stSong[idx].sArtist";
}

define_function askMenuList()
{
        switch(nPage)
        {
                case TOK_TITLE:
                case TOK_ARTIST:
                case TOK_ALBUM:
                case TOK_GENRE:
                        setPopup(DIR_OPEN, sPopupMenu);
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU1),'.',itoa(BTN_MENU1+MAX_LINES-1),',0,'";    // Clear all lines
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU1),',0,Move to queue and play'";
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU2),',0,Add to queue'";

                        if (nPage != TOK_TITLE && !nFolder)
                                send_command dvTPs, "'^TXT-',itoa(BTN_MENU3),',0,Open folder'";
                break;

                case TOK_PLAYLIST:
                        setPopup(DIR_OPEN, sPopupMenu);
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU1),'.',itoa(BTN_MENU1+MAX_LINES-1),',0,'";    // Clear all lines
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU1),',0,Move to queue and play'";
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU2),',0,Add to queue'";

                        if (!nFolder)
                        {
                                send_command dvTPs, "'^TXT-',itoa(BTN_MENU3),',0,Show content'";
                                send_command dvTPs, "'^TXT-',itoa(BTN_MENU4),',0,Delete playlist'";
                        }
                        else
                                send_command dvTPs, "'^TXT-',itoa(BTN_MENU3),',0,Delete entry'";
                break;

                case TOK_QUEUE:
                        setPopup(DIR_OPEN, sPopupMenu);
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU1),'.',itoa(BTN_MENU1+MAX_LINES-1),',0,'";    // Clear all lines
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU1),',0,Play this now'";
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU2),',0,Save this to a playlist'";
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU3),',0,Delete from queue'";
                break;

                case TOK_SEARCH:
                        setPopup(DIR_OPEN, sPopupMenu);
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU1),'.',itoa(BTN_MENU1+MAX_LINES-1),',0,'";    // Clear all lines
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU1),',0,Move to queue and play'";
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU2),',0,Add to queue'";
                break;
        }

        switch(nPage)
        {
                case TOK_TITLE:         send_command dvTPs, "'^TXT-',itoa(TEXT_MENU_TITLE),',0,Title menu'";
                case TOK_ARTIST:        send_command dvTPs, "'^TXT-',itoa(TEXT_MENU_TITLE),',0,Artist menu'";
                case TOK_ALBUM:         send_command dvTPs, "'^TXT-',itoa(TEXT_MENU_TITLE),',0,Album menu'";
                case TOK_GENRE:         send_command dvTPs, "'^TXT-',itoa(TEXT_MENU_TITLE),',0,Genre menu'";
                case TOK_QUEUE:         send_command dvTPs, "'^TXT-',itoa(TEXT_MENU_TITLE),',0,Queue menu'";
                case TOK_PLAYLIST:      send_command dvTPs, "'^TXT-',itoa(TEXT_MENU_TITLE),',0,Playlist menu'";
                case TOK_SEARCH:        send_command dvTPs, "'^TXT-',itoa(TEXT_MENU_TITLE),',0,Search menu'";
        }
}

define_function lineSelect(integer pl)
{
        nLastPressedLine = pl;

        if (nPage == TOK_PLAYLIST && !nFolder)
                sActPlaylist = stSong[pl].sTitle;

        askMenuList();
}

DEFINE_START
        nStart = 1;
        nPage = TOK_NONE;

DEFINE_EVENT
        data_event[dvTPs]
        {
                /*
                 * Whenever a panel comes online, it'll be initialized. The actual
                 * popup is shown and the pressed (or not pressed) button stated
                 * are set.
                 */
                online:
                {
                        stack_var integer pan;

                        pan = get_last(dvTPs);

                        switch(nPage)
                        {
                                case TOK_TITLE:
                                case TOK_PLAYLIST:
                                        send_command dvTPs[pan], "'@PPN-',sPopupAudio";
                                        send_command vdvMDB, "'LIST:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                break;

                                case TOK_ALBUM:
                                case TOK_ARTIST:
                                case TOK_GENRE:
                                        send_command dvTPs[pan], "'@PPN-',sPopupAudio";
                                        send_command vdvMDB, "'FOLDER:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                break;

                                case TOK_QUEUE:
                                        send_command dvTPs[pan], "'@PPN-',sPopupList";
                                        send_command vdvMDB, "'LIST:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                break;
                                
                                default:
                                        send_command dvTPs[pan], "'@PPN-',sPopupAudio";
                                        nStart = 1;
                                        send_command vdvMDB, "'LIST:TITLE:',itoa(nStart),':',itoa(MAX_LINES),';'";
                        }
                }
        }

        /*
         * The navigation buttons are for setting the wanted views.
         */
        button_event[dvTPs, nNavigation]
        {
                push:
                {
                stack_var integer pan;

                        pan = get_last(dvTPs);

                        switch(BUTTON.INPUT.CHANNEL)
                        {
                                case BTN_TITLE:         
                                        send_command vdvMDB, "'LIST:TITLE:1:',itoa(MAX_LINES),';'"; 
                                        nFolder = 0; 
                                        nStart = 1;
                                        nSearch = 0;
                                        nPage = TOK_TITLE;
                                break;

                                case BTN_ARTIST:        
                                        send_command vdvMDB, "'FOLDER:ARTIST:1:',itoa(MAX_LINES),';'"; 
                                        nFolder = 0; 
                                        nStart = 1;
                                        nSearch = 0;
                                        nPage = TOK_ARTIST;
                                break;

                                case BTN_ALBUM:         
                                        send_command vdvMDB, "'FOLDER:ALBUM:1:',itoa(MAX_LINES),';'"; 
                                        nFolder = 0; 
                                        nStart = 1;
                                        nSearch = 0;
                                        nPage = TOK_ALBUM;
                                break;

                                case BTN_GENRE:         
                                        send_command vdvMDB, "'FOLDER:GENRE:1:',itoa(MAX_LINES),';'"; 
                                        nFolder = 0; 
                                        nStart = 1;
                                        nSearch = 0;
                                        nPage = TOK_GENRE;
                                break;

                                case BTN_QUEUE: 
                                        send_command vdvMDB, "'LIST:QUEUE:1:',itoa(MAX_LINES),';'"; 
                                        nFolder = 0; 
                                        nStart = 1;
                                        nSearch = 0;
                                        nPage = TOK_QUEUE;
                                break;

                                case BTN_PLAYLIST:
                                        send_command dvTPs[pan], "'@PPN-',sPopupSelUser";

                                        if (!length_string(sActUser))
                                        {
                                                send_command dvTPs[pan], "'@AKB-',sActUser,';Enter name of user'";
                                                nKeyboard[pan] = TEXT_INPUT_UNAME;
                                        }
                                        else
                                        {
                                                send_command dvTPs[pan], "'@AKB-',sActPlaylist,';Enter name of playlist'";
                                                nKeyboard[pan] = TEXT_INPUT_PLAYLIST;
                                        }

                                        nToDo = TODO_USER_SELECT;
                                break;

                                case BTN_NOW_PLAYING:
                                        if (nPlayStatus == PLAYER_PLAY || nPlayStatus == PLAYER_PAUSE)
                                                setPopup(DIR_OPEN, sPopupDetail);
                                break;

                                case BTN_SAVE:
                                        send_command dvTPs[pan], "'@PPN-',sPopupSelUser";
                                        sInputUser = sActUser;
                                        sInputPlaylist = '';
                                        send_command dvTPs[pan], "'^TXT-',itoa(TEXT_INPUT_UNAME),',0,',sActUser";
                                        send_command dvTPs[pan], "'^TXT-',itoa(TEXT_INPUT_PLAYLIST),',0,'";
                                        send_command dvTPs[pan], "'@AKB-',sActPlaylist,';Enter name of playlist'";
                                        nToDo = TODO_USER_SAVE_PLAYLIST;
                                        nKeyboard[pan] = TEXT_INPUT_PLAYLIST;
                                break;

                                case BTN_DELETE:
                                        send_command vdvMDB, "'DELETE:QUEUE:-1;'";
                                        nStart = 1;
                                        send_command vdvMDB, "'LIST:QUEUE:',itoa(nStart),':',itoa(MAX_LINES),';'";
                                break;

                                case BTN_SEARCH:
                                        if (!nSearch)
                                        {
                                                send_command dvTPs[pan], "'@AKB-;Search for a ',requestActualPage()";
                                                nToDo = TODO_SEARCH;
                                                nKeyboard[pan] = TEXT_INPUT_SEARCH;
                                        }
                                break;

                                case BTN_RESET:
                                        send_command vdvMDB, 'RESET;';
                                break;
                        }
                }
        }

        /*
         * This buttons control mostly the player. With them you can play, stop
         * pause, etc. the player and scroll through lists.
         * Common to this buttons is, that they conform to the AMX SNAPI standard.
         * All of them are declared in the file "mSNAPI.axi".
         */
        button_event[dvTPs, nBtns]
        {
                push:
                {
                        switch(BUTTON.INPUT.CHANNEL)
                        {
                                case PLAY:                      send_command vdvMDB, 'PLAY;';
                                case PAUSE:                     send_command vdvMDB, 'PLAYPAUSE;';
                                case STOP:                      send_command vdvMDB, 'STOP;';
                                case FFWD:                      send_command vdvMDB, 'FORWARD;';
                                case REW:                       send_command vdvMDB, 'REWIND;';
                                case SREV:                      send_command vdvMDB, 'SKIPREW;';
                                case SFWD:                      send_command vdvMDB, 'SKIPFWD;';
                                case MEDIA_RANDOM:      send_command vdvMDB, 'RANDOM;';
                                case MEDIA_REPEAT:      send_command vdvMDB, 'REPEAT;';

                                case MENU_THUMBS_UP:
                                        if (nStart > MAX_LINES)
                                        {
                                                nStart = nStart - MAX_LINES;

                                                if (nPage == TOK_TITLE || nPage == TOK_QUEUE)
                                                        send_command vdvMDB, "'LIST:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                else if (nPage == TOK_SEARCH)
                                                        send_command vdvMDB, "'SEARCH:',requestPage(nOldPage),':',EncodeURL(sSearchFor),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                else if (nPage == TOK_PLAYLIST)
                                                {
                                                        if (!nFolder)
                                                                send_command vdvMDB, "'LIST:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                        else
                                                                send_command vdvMDB, "'PLIST:',EncodeURL(sActUser),':',EncodeURL(sActPlaylist),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                }
                                                else
                                                {
                                                        if (!nFolder)
                                                                send_command vdvMDB, "'FOLDER:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                        else
                                                                send_command vdvMDB, "'LISTFOLDER:',requestActualPage(),':',EncodeURL(sActFolder),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                }
                                        }
                                break;

                                case MENU_THUMBS_DN:
                                        if (nTotal && (nStart+MAX_LINES) <= nTotal)
                                        {
                                                nStart = nStart + MAX_LINES;

                                                if (nPage == TOK_TITLE || nPage == TOK_QUEUE)
                                                        send_command vdvMDB, "'LIST:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                else if (nPage == TOK_SEARCH)
                                                        send_command vdvMDB, "'SEARCH:',requestPage(nOldPage),':',EncodeURL(sSearchFor),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                else if (nPage == TOK_PLAYLIST)
                                                {
                                                        if (!nFolder)
                                                                send_command vdvMDB, "'LIST:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                        else
                                                                send_command vdvMDB, "'PLIST:',EncodeURL(sActUser),':',EncodeURL(sActPlaylist),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                }
                                                else
                                                {
                                                        if (!nFolder)
                                                                send_command vdvMDB, "'FOLDER:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                        else
                                                                send_command vdvMDB, "'LISTFOLDER:',requestActualPage(),':',EncodeURL(sActFolder),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                }
                                        }
                                break;

                                case MENU_BACK:
                                case BTN_RETURN:
                                        if (nFolder)
                                        {
                                                nStart = nOldStart;
                                                nFolder = 0;
                                        }
                                        else if (nSearch)
                                        {
                                                nStart = nOldStart;
                                                nPage = nOldPage;
                                                nSearch = 0;
                                        }

                                        if (nPage == TOK_TITLE || nPage == TOK_QUEUE || nPage == TOK_PLAYLIST)
                                                send_command vdvMDB, "'LIST:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                        else
                                                send_command vdvMDB, "'FOLDER:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                break;
                        }
                }

                hold[2,repeat]:
                {
                        switch(BUTTON.INPUT.CHANNEL)
                        {
                                case FFWD:                      send_command vdvMDB, 'FORWARD;';
                                case REW:                       send_command vdvMDB, 'REWIND;';
                        }
                }
        }

        button_event[dvTPs,nLines]
        {
                push:
                {
                        switch(BUTTON.INPUT.CHANNEL)
                        {
                                case BTN_LINE1_PIC:
                                case BTN_LINE1_LINE:
                                        lineSelect(1);
                                break;

                                case BTN_LINE2_PIC:
                                case BTN_LINE2_LINE:
                                        lineSelect(2);
                                break;

                                case BTN_LINE3_PIC:
                                case BTN_LINE3_LINE:
                                        lineSelect(3);
                                break;

                                case BTN_LINE4_PIC:
                                case BTN_LINE4_LINE:
                                        lineSelect(4);
                                break;

                                case BTN_LINE5_PIC:
                                case BTN_LINE5_LINE:
                                        lineSelect(5);
                                break;

                                case BTN_LINE6_PIC:
                                case BTN_LINE6_LINE:
                                        lineSelect(6);
                                break;

                                case BTN_LINE7_PIC:
                                case BTN_LINE7_LINE:
                                        lineSelect(7);
                                break;

                                case BTN_LINE8_PIC:
                                case BTN_LINE8_LINE:
                                        lineSelect(8);
                                break;

                                case BTN_LINE9_PIC:
                                case BTN_LINE9_LINE:
                                        lineSelect(9);
                                break;

                                case BTN_LINE10_PIC:
                                case BTN_LINE10_LINE:
                                        lineSelect(10);
                                break;
                        }
                }
        }

        button_event[dvTPs,nMenu]
        {
                push:
                {
                stack_var integer pan;

                        pan = get_last(dvTPs);

                        switch(BUTTON.INPUT.CHANNEL)
                        {
                                case BTN_MENU1:
                                        if (nPage != TOK_PLAYLIST && nPage != TOK_QUEUE)        // Move to queue and play
                                        {
                                                if (nPlayStatus == PLAYER_PLAY || nPlayStatus == PLAYER_PAUSE)
                                                        send_command vdvMDB, 'STOP;';

                                                send_command vdvMDB, 'DELETE:QUEUE:-1;';
                                                
                                                if (nPage == TOK_TITLE || nPage == TOK_SEARCH || nFolder)
                                                        send_command vdvMDB, "'PLAY:ID:',itoa(stSong[nLastPressedLine].nID),';'";
                                                else
                                                        send_command vdvMDB, "'PLAY:',requestActualPage(),':',stSong[nLastPressedLine].sTitle,';'";

                                                nFolder = 0;
                                                nStart = 1;
                                                nSearch = 0;
                                                nPage = TOK_QUEUE;
                                                send_command vdvMDB, "'LIST:QUEUE:',itoa(nStart),':',itoa(MAX_LINES),';'";
                                        }
                                        else if (nPage == TOK_PLAYLIST)
                                        {
                                                if (length_string(sActUser) && length_string(sActPlaylist))
                                                {
                                                        if (nPlayStatus == PLAYER_PLAY || nPlayStatus == PLAYER_PAUSE)
                                                                send_command vdvMDB, 'STOP;';
        
                                                        send_command vdvMDB, 'DELETE:QUEUE:-1;';

                                                        if (!nFolder)
                                                                send_command vdvMDB, "'PLAY:PLAYLIST:',EncodeURL(sActPlaylist),';'";
                                                        else
                                                                send_command vdvMDB, "'PLAY:ID:',itoa(stSong[nLastPressedLine].nID),';'";

                                                        nFolder = 0;
                                                        nStart = 1;
                                                        nSearch = 0;
                                                        nPage = TOK_QUEUE;
                                                        send_command vdvMDB, "'LIST:QUEUE:',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                }
                                        }
                                        else if (nPage == TOK_QUEUE)
                                                send_command vdvMDB, "'PLAY:QUEUE:',itoa(nStart+nLastPressedLine-1),';'";
                                break;

                                case BTN_MENU2:
                                        if (nPage != TOK_PLAYLIST && nPage != TOK_QUEUE)        // Add to queue
                                        {
                                                if (nPage == TOK_TITLE || nPage == TOK_SEARCH || nFolder)
                                                        send_command vdvMDB, "'ADD:ID:',itoa(stSong[nLastPressedLine].nID),';'";
                                                else
                                                        send_command vdvMDB, "'ADD:',requestActualPage(),':',stSong[nLastPressedLine].sTitle,';'";
                                        }
                                        else if (nPage == TOK_PLAYLIST)
                                        {
                                                if (!nFolder)
                                                        send_command vdvMDB, "'ADD:PLAYLIST:',EncodeURL(sActPlaylist),';'";
                                                else
                                                        send_command vdvMDB, "'ADD:ID:',itoa(stSong[nLastPressedLine].nID),';'";
                                        }
                                        else if (nPage == TOK_QUEUE)
                                        {
                                                setPopup(DIR_OPEN, sPopupSelUser);
                                                sInputUser = sActUser;
                                                sInputPlaylist = '';
                                                send_command dvTPs[pan], "'^TXT-',itoa(TEXT_INPUT_UNAME),',0,',sActUser";
                                                send_command dvTPs[pan], "'@AKB-',sActPlaylist,';Enter name of playlist'";
                                                nToDo = TODO_USER_PLAYLIST_QUEUE;
                                                nKeyboard[pan] = TEXT_INPUT_PLAYLIST;
                                        }
                                break;
                                
                                case BTN_MENU3:
                                        if (nPage != TOK_TITLE && nPage != TOK_PLAYLIST && nPage != TOK_QUEUE && nPage != TOK_SEARCH)   // Open folder
                                        {
                                                sActFolder = stSong[nLastPressedLine].sTitle;   // Get name of folder
                                                nFolder = true;                                                                 // Set marker for folder
                                                nOldStart = nStart;                                                             // Save current position
                                                nStart = 1;                                                                             // Reset start position
                                                send_command vdvMDB, "'LISTFOLDER:',requestActualPage(),':',stSong[nLastPressedLine].sTitle,':1:',itoa(MAX_LINES),';'";
                                        }
                                        else if (nPage == TOK_PLAYLIST)
                                        {
                                                if (!nFolder)
                                                {
                                                        sActUser = sInputUser;
                                                        sActPlaylist = stSong[nLastPressedLine].sTitle;
                                                        nOldStart = nStart;
                                                        nFolder = 1;
                                                        nStart = 1;
                                                        send_command vdvMDB, "'PLIST:',EncodeURL(sActUser),':',EncodeURL(stSong[nLastPressedLine].sTitle),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                }
                                                else            // Delete entry
                                                {
                                                        send_command vdvMDB, "'DELETE:PTITLE:',itoa(stSong[nLastPressedLine].nID),';'";
                                                        nStart = 1;
                                                        send_command vdvMDB, "'PLIST:',EncodeURL(sActUser),':',EncodeURL(stSong[nLastPressedLine].sTitle),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                }
                                        }
                                        else if (nPage == TOK_QUEUE)
                                        {
                                                send_command vdvMDB, "'DELETE:QUEUE:',itoa(stSong[nLastPressedLine].nID),';'";
                                                nStart = 1;
                                                send_command vdvMDB, "'LIST:QUEUE:',itoa(nStart),':',itoa(MAX_LINES),';'";
                                        }
                                break;

                                case BTN_MENU4:
                                        if (nPage == TOK_PLAYLIST && !nFolder)
                                        {
                                                send_command vdvMDB, "'DELETE:PLAYLIST:',itoa(stSong[nLastPressedLine].nID),';'";
                                                nStart = 1;
                                                send_command vdvMDB, "'LIST:PLAYLIST:',itoa(nStart),':',itoa(MAX_LINES),';'";
                                        }
                                break;
                        }

                        if (nPage != TOK_QUEUE)
                                setPopup(DIR_OPEN, sPopupAudio);
                        else
                                setPopup(DIR_OPEN, sPopupList);
                }
        }

        button_event[dvTPs,nBtnUser]
        {
                push:
                {
                        stack_var integer pan;

                        pan = get_last(dvTPs);

                        switch(BUTTON.INPUT.CHANNEL)
                        {
                                case TEXT_INPUT_UNAME:
                                        if (!nKeyboard[pan])
                                        {
                                                nKeyboard[pan] = TEXT_INPUT_UNAME;
                                                send_command dvTPs[pan],"'@AKB-',sActUser,';Enter user name'";
                                        }
                                break;

                                case TEXT_INPUT_PLAYLIST:
                                        if (!nKeyboard[pan])
                                        {
                                                nKeyboard[pan] = TEXT_INPUT_PLAYLIST;
                                                send_command dvTPs[pan],"'@AKB-',sActPlaylist,';Enter name of playlist'";
                                        }
                                break;

                                case BTN_USER_OK:
                                        send_command dvTPs[pan],"'@PPF-',sPopupSelUser";

                                        switch(nToDo)
                                        {
                                                case TODO_USER_SELECT:
                                                        sActUser = sInputUser;
                                                        send_command vdvMDB, "'USER:',EncodeURL(sInputUser),':;'";
                                                        nStart = 1;
                                                        nPage = TOK_PLAYLIST;
                                                        nFolder = 0;
                                                        nSearch = 0;
                                                        send_command vdvMDB, "'LIST:PLAYLIST:',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                break;

                                                case TODO_USER_LIST_PLAYLIST:
                                                        sActPlaylist = sInputPlaylist;
                                                        nOldStart = nStart;
                                                        nFolder = 1;
                                                        nStart = 1;
                                                        send_command vdvMDB, "'PLIST:',EncodeURL(sActUser),':',EncodeURL(stSong[nLastPressedLine].sTitle),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                                break;

                                                case TODO_USER_SAVE_PLAYLIST:
                                                        sActUser = sInputUser;
                                                        sActPlaylist = sInputPlaylist;

                                                        if (length_string(sActUser) && length_string(sActPlaylist))
                                                                send_command vdvMDB, "'SAVEQUEUE:',EncodeURL(sActUser),':',EncodeURL(sActPlaylist),';'";
                                                break;

                                                case TODO_USER_PLAYLIST_QUEUE:
                                                        sActUser = sInputUser;
                                                        sActPlaylist = stSong[nLastPressedLine].sTitle;

                                                        if (length_string(sActUser) && length_string(sActPlaylist))
                                                                send_command vdvMDB, "'ADD:PLAYLIST:',EncodeURL(stSong[nLastPressedLine].sTitle),';'";
                                                break;
                                        }

                                        nToDo = 0;
                                break;

                                case BTN_USER_CANCEL:
                                        nToDo = 0;
                                        send_command dvTPs[pan],"'@PPF-',sPopupSelUser";
                                break;

                                case BTN_DETAIL_BACK:
                                        if (nPage == TOK_QUEUE)
                                                setPopup(DIR_OPEN, sPopupAudio);
                                        else
                                                setPopup(DIR_OPEN, sPopupList);
                                break;
                        }
                }
        }

        /*
         * This event catches everything comming from the COMM - module. Here the
         * AMX part of the COMM - module only makes a network connection to the
         * player. The API of the player is made to replace a heavy AMX COMM -
         * module. Everything normally is done inside an AMX COMM - module, is
         * done by the player itself, running on a Linux platform. This makes the
         * communication with it fairly easy.
         */
        data_event[vdvMDB]
        {
                string:
                {
                        stack_var char buf[8192];

                        while (find_string(DATA.TEXT, ';', 1))
                        {
                                buf = remove_string(DATA.TEXT, ';', 1);
                                set_length_string(buf, length_string(buf) - 1);

                                select
                                {
                                        /*
                                         * This is send by the player whenever the UI should
                                         * display a list with song details.
                                         * The correct popup must be displayed and the contents
                                         * should be filled with the data from the player.
                                         */
                                        active(find_string(buf, 'LINE:', 1)):
                                        {
                                        stack_var char sPg[32];
                                        stack_var integer nSongID;
                                        stack_var integer nLine;
                                        stack_var integer anz;
                                        stack_var integer i;

                                                remove_string(buf, 'LINE:', 1);
                                                anz = strtok(buf, ':');

                                                for (i = 1; i <= anz; i++)
                                                {
                                                        switch (i)
                                                        {
                                                                case 1: sPg = getStrTok(i);
                                                                case 2: nSongID = atoi(getStrTok(i));

                                                                case 3:
                                                                        nLine = atoi(getStrTok(i));
                                                                        clearPageLine(nLine);
                                                                        stSong[nLine].nID = nSongID;
                                                                break;

                                                                case 4: stSong[nLine].sTitle = DecodeURL(getStrTok(i));
                                                                case 5: stSong[nLine].sArtist = DecodeURL(getStrTok(i));
                                                                case 6: stSong[nLine].sAlbum = DecodeURL(getStrTok(i));
                                                                case 7: stSong[nLine].sGenre = DecodeURL(getStrTok(i));
                                                                case 8: stSong[nLine].sCover = DecodeURL(getStrTok(i));
                                                        }
                                                }

                                                if (nLine == 1)
                                                {
                                                        setActualPage(sPg);
                                                        clearPage();
                                                }

                                                displaySong(nLine);
                                                setLogo(stSong[nline].sCover, nLine);
                                        }

                                        active(find_string(buf, 'FOLDER:', 1)):
                                        {
                                        stack_var char sPg[32];
                                        stack_var integer nLine;
                                        stack_var integer anz;
                                        stack_var integer i;

                                                remove_string(buf, 'FOLDER:', 1);
                                                anz = strtok(buf, ':');

                                                for (i = 1; i <= anz; i++)
                                                {
                                                        switch(i)
                                                        {
                                                                case 1: sPg = getStrTok(i);

                                                                case 2:
                                                                        nLine = atoi(getStrTok(i));
                                                                        clearPageLine(nLine);
                                                                break;

                                                                case 3: stSong[nLine].sTitle = DecodeURL(getStrTok(i));
                                                                case 4: stSong[nLine].sCover = DecodeURL(getStrTok(i));
                                                        }
                                                }

                                                stSong[nLine].nID = 0;
                                                stSong[nLine].sAlbum = '';
                                                stSong[nLine].sArtist = '';
                                                stSong[nLine].sGenre = '';

                                                if (nLine == 1)
                                                {
                                                        setActualPage(sPg);
                                                        clearPage();
                                                }

                                                displaySong(nLine);
                                                setLogo(stSong[nline].sCover, nLine);
                                        }

                                        active(find_string(buf, 'PLAYLIST:', 1)):
                                        {
                                        stack_var integer nLine;
                                        stack_var integer id;
                                        stack_var integer anz;
                                        stack_var integer i;

                                                remove_string(buf, 'PLAYLIST:', 1);
                                                anz = strtok(buf, ':');

                                                for (i = 1; i <= anz; i++)
                                                {
                                                        switch(i)
                                                        {
                                                                case 1: 
                                                                        nLine = atoi(getStrTok(i));
                                                                        clearPageLine(nLine);
                                                                break;

                                                                case 2: stSong[nLine].nID = atoi(getStrTok(i));
                                                                case 3: sActUser = DecodeURL(getStrTok(i));
                                                                case 4: stSong[nLine].sTitle = DecodeURL(getStrTok(i));
                                                        }
                                                }

                                                if (nLine == 1)
                                                {
                                                        setActualPage(TOK_TXT_PLAYLIST);
                                                        clearPage();
                                                }

                                                displaySong(nLine);
                                        }

                                        // SEARCH:<type>:<id>:<line>:<title>:<artist>:<album>:<genre>;
                                        active(find_string(buf, 'SEARCH:', 1)):
                                        {
                                        stack_var char sPg[32];
                                        stack_var integer id;
                                        stack_var integer nLine;
                                        stack_var integer anz;
                                        stack_var integer i;

                                                remove_string(buf, 'SEARCH:', 1);
                                                anz = strtok(buf, ':');

                                                for (i = 1; i <= anz; i++)
                                                {
                                                        switch(i)
                                                        {
                                                                case 1: sPg = getStrTok(i);
                                                                case 2: id = atoi(getStrTok(i));

                                                                case 3:
                                                                        nLine = atoi(getStrTok(i));
                                                                        clearPageLine(nLine);
                                                                        stSong[nLine].nID = id;
                                                                break;

                                                                case 4: stSong[nLine].sTitle = DecodeURL(getStrTok(i));
                                                                case 5: stSong[nLine].sArtist = DecodeURL(getStrTok(i));
                                                                case 6: stSong[nLine].sAlbum = DecodeURL(getStrTok(i));
                                                                case 7: stSong[nLine].sGenre = DecodeURL(getStrTok(i));
                                                                case 8: stSong[nLine].sCover = DecodeURL(getStrTok(i));
                                                        }
                                                }

                                                if (nLine == 1)
                                                {
                                                        setActualPage(TOK_TXT_SEARCH);
                                                        clearPage();
                                                }

                                                displaySong(nLine);
                                        }

                                        active(find_string(buf, 'FOLDERNAME:', 1)):
                                        {
                                                remove_string(buf, 'FOLDERNAME:', 1);
                                                sActFolder = buf;
                                                nFolder = 1;
                                        }

                                        active(find_string(buf, 'PLAYING:', 1)):
                                        {
                                        stack_var integer nSongID;
                                        stack_var char sTitle[256];
                                        stack_var char sArtist[256];
                                        stack_var char sAlbum[256];
                                        stack_var char sGenre[256];
                                        stack_var char sCover[256];
                                        stack_var integer anz;
                                        stack_var integer i;

                                                remove_string(buf, 'PLAYING:', 1);
                                                anz = strtok(buf, ':');
                                                
                                                for (i = 1; i <= anz; i++)
                                                {
                                                        switch (i)
                                                        {
                                                                case 1: nSongID = atoi(getStrTok(i));
                                                                case 2: sTitle = DecodeURL(getStrTok(i));
                                                                case 3: sArtist = DecodeURL(getStrTok(i));
                                                                case 4: sAlbum = DecodeURL(getStrTok(i));
                                                                case 5: sGenre = DecodeURL(getStrTok(i));
                                                                case 6: sCover = DecodeURL(getStrTok(i));
                                                        }
                                                }

                                                // Initialize detail fields
                                                send_command dvTPs, "'^TXT-',itoa(TEXT_DETAIL_TITLE),',0,',sTitle";
                                                send_command dvTPs, "'^TXT-',itoa(TEXT_DETAIL_ARTIST),',0,',sArtist";
                                                send_command dvTPs, "'^TXT-',itoa(TEXT_DETAIL_ALBUM),',0,',sAlbum";
                                                send_command dvTPs, "'^TXT-',itoa(TEXT_DETAIL_GENRE),',0,',sGenre";
                                                setLogo(sCover, 0);
                                        }

                                        active(find_string(buf, 'POSITION:', 1)):
                                        {
                                                stack_var char sTimeA[16];
                                                stack_var char sTimeB[16];
                                                stack_var char sTimeC[16];
                                                stack_var integer anz;
                                                stack_var integer i;

                                                remove_string(buf, 'POSITION:', 1);
                                                anz = strtok(buf, ':');

                                                for (i = 1; i <= anz; i++)
                                                {
                                                        switch(i)
                                                        {
                                                                case 1: sTimeA = DecodeURL(getStrTok(i));
                                                                case 2: sTimeB = DecodeURL(getStrTok(i));
                                                                case 3: sTimeC = DecodeURL(getStrTok(i));
                                                        }
                                                }

                                                send_command dvTPs, "'^TXT-',itoa(TEXT_DETAIL_TIME_PROG),',0,',sTimeA";
                                                send_command dvTPs, "'^TXT-',itoa(TEXT_DETAIL_TIME_TOTAL),',0,',sTimeC";
                                                displayProgresBar(sTimeA, sTimeC);
                                        }

                                        active(find_string(buf, 'USER:', 1)):
                                        {
                                                remove_string(buf, 'USER:', 1);
                                                sActUser = DecodeURL(buf);
                                        }

                                        active(find_string(buf, 'TOTAL:', 1)):
                                        {
                                                remove_string(buf, 'TOTAL:', 1);
                                                nTotal = atoi(buf);
                                                displayPageInfo(nStart, nTotal);

                                                if (nTotal == 0)
                                                        clearPage();
                                        }

                                        active(find_string(buf, 'PAGE:', 1)):
                                        {
                                                remove_string(buf, 'PAGE:', 1);
                                                setActualPage(buf);
                                                displayPageInfo(nStart, nTotal);
                                        }

                                        active(find_string(buf, 'PLAYER:', 1)):
                                        {
                                                remove_string(buf, 'PLAYER:', 1);

                                                if (buf == 'PLAY')
                                                {
                                                        nPlayStatus = PLAYER_PLAY;
                                                        on[dvTPs,PLAY];
                                                        off[dvTPs,STOP];
                                                        off[dvTPs,PAUSE];
                                                }
                                                else if (buf == 'STOP')
                                                {
                                                        nPlayStatus = PLAYER_STOP;
                                                        off[dvTPs,PLAY];
                                                        on[dvTPs,STOP];
                                                        off[dvTPs,PAUSE];
                                                }
                                                else if (buf == 'PAUSE')
                                                {
                                                        nPlayStatus = PLAYER_PAUSE;
                                                        off[dvTPs,PLAY];
                                                        off[dvTPs,STOP];
                                                        on[dvTPs,PAUSE];
                                                }
                                                else
                                                {
                                                        nPlayStatus = 0;
                                                        off[dvTPs,PLAY];
                                                        off[dvTPs,STOP];
                                                        off[dvTPs,PAUSE];
                                                }
                                        }

                                        active(find_string(buf, 'RANDOM:', 1)):
                                        {
                                                remove_string(buf, 'RANDOM:', 1);

                                                if (buf == 'TRUE')
                                                        nRandom = 1;
                                                else
                                                        nRandom = 0;
                                        }

                                        active(find_string(buf, 'REPEAT:', 1)):
                                        {
                                                remove_string(buf, 'REPEAT:', 1);

                                                if (buf == 'TRUE')
                                                        nRepeat = 1;
                                                else
                                                        nRepeat = 0;
                                        }

                                        active(find_string(buf, 'ERROR:PLAYLIST:No user selected', 1)):
                                        {
                                                sActUser = '';
                                                nKeyboard[get_last(dvTPs)] = TEXT_INPUT_UNAME;
                                                send_command dvTPs[get_last(dvTPs)],"'@AKB-',sActUser,';Enter user name'";
                                        }

                                        active(find_string(buf, 'KEYBOARD:', 1)):
                                        {
                                        stack_var integer pan;
        
                                                remove_string(buf, 'KEYBOARD:', 1);
                                                pan = atoi(buf);
                                                remove_string(buf, ':', 1);
        
                                                if (nKeyboard[pan] == TEXT_INPUT_UNAME)
                                                {
                                                        sInputUser = buf;
                                                        send_command dvTPs[pan], "'^TXT-',itoa(TEXT_INPUT_UNAME),',0,',sInputUser";
                                                        nKeyboard[pan] = 0;
                                                }
                                                else if (nKeyboard[pan] == TEXT_INPUT_PLAYLIST)
                                                {
                                                        sInputPlaylist = buf;
                                                        send_command dvTPs, "'^TXT-',itoa(TEXT_INPUT_PLAYLIST),',0,',sInputPlaylist";
                                                        nKeyboard[pan] = 0;
                                                }
                                                else if (nKeyboard[pan] == TEXT_INPUT_SEARCH)
                                                {
                                                        setPopup(DIR_OPEN, sPopupAudio);
                                                        nOldStart = nStart;
                                                        nStart = 1;
                                                        nSearch = 1;
                                                        nOldPage = nPage;
                                                        sSearchFor = buf;
                                                        send_command vdvMDB, "'SEARCH:',requestActualPage(),':',EncodeURL(buf),':1:',itoa(MAX_LINES),';'";
                                                }
                                        }
                                }
                        }
                }
        }

        button_event[dvTPs,BTN_SCROLLBAR]
        {
                push:
                {
                stack_var integer pan;
                
                        pan = get_last(dvTPs)
                        nScrollbarPressed[pan] = 1;
                }

                release:
                {
                stack_var integer pan;
                
                        pan = get_last(dvTPs)
                        nScrollbarPressed[pan] = 0;

                        if (nTotal)
                        {
                                nStart = type_cast(nTotal / 100.0 * nScrollbarLvl);
                                send_command vdvMDB, "'LIST:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                        }
                }
        }

        level_event[dvTPs,LVL_SCROLLBAR]
        {
        stack_var integer pan;

                pan = get_last(dvTPs);

                if (nScrollbarPressed[pan])
                        nScrollbarLvl = LEVEL.VALUE;
        }

DEFINE_PROGRAM
        [dvTPs,MEDIA_RANDOM] = nRandom;
        [dvTPs,MEDIA_REPEAT] = nRepeat;