Subversion Repositories mdb

Rev

Rev 23 | Rev 25 | Go to most recent revision | 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)

#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_SAVE =                     340;
        constant integer BTN_DELETE =           341;
        constant integer BTN_NOW_PLAYING =      342;

        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_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 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 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 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 nNavigation[] =
        {
                BTN_SAVE,
                BTN_DELETE,
                BTN_NOW_PLAYING,
                BTN_TITLE,
                BTN_ARTIST,
                BTN_GENRE,
                BTN_ALBUM,
                BTN_PLAYLIST
        };

        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
        };

        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
        };

DEFINE_VARIABLE
        volatile integer nStart;                                // Index position of current position in list.
        volatile integer nTotal;                                // Total number of data
        volatile integer nPage;                                 // The type of the page: TOK_TITLE, ...
        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 integer sActUser[128];                 // The name of the actual loaded user
        volatile integer nFolder;                               // 0 = Top level of list, 1 = Folder opened
        volatile integer sActFolder[128];               // The name of the actual selected folder
        volatile integer nSaveToFolder;                 // 1 = Flag for keyboard to save to entered folder

        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 integer len;
stack_var integer i;

        len = length_string(oldStr);
        str = '';

        for (i = 1; i <= len; i++)
        {
                if (oldStr[i] == ':' || oldStr[i] == ';')
                        str = "str,'%',format('%02X', oldStr[i])";
                else
                        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 = 0;
        i = find_string(str, tok, 1);

        while (i && idx <= 10)
        {
                idx++;
                _strTok[idx] = left_string(str, i - length_string(tok));
                remove_string(str, tok, 1);
        }

        return idx;
}

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

        return '';
}

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 integer nType;
stack_var char sHost[64];
stack_var char sPath[512];
stack_var integer i;

        if (pos > MAX_LINES)
                return;

        sHost = IP;
        sPath = 'mdb';
        nType = 0;                      // 0 = HTTP, 1 = FTP
        send_command dvTPs,"'^SHO-',itoa(300+pos),',1'";

        if (!length_string(sFile))
        {
                if (nPage && pos)
                        send_command dvTPs,"'^BBR-',itoa(300+pos),',0,',sIconsMusic[nPage]";

                return;
        }

        if (pos && pos <= MAX_LINES)
        {
                send_command dvTPs,"'^RMF-XBMC_Audio',itoa(pos),',%P',itoa(nType),'%H',sHost,'%A',sPath,'%F',sFile";
                send_command dvTPs,"'^BBR-',itoa(300+pos),',0,XBMC_Audio',itoa(pos)";
        }
        else
        {
                send_command dvTPs,"'^RMF-XBMC_AudioCover,%P',itoa(nType),'%H',sHost,'%A',sPath,'%F',sFile";
                send_command dvTPs,"'^BBR-',itoa(300+pos),',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()
{
stack_var char sPage[32];

        sPage = '';

        if (nPage == TOK_NONE)
                return sPage;

        switch(nPage)
        {
                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;
        }

        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 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;
        }

        switch(nPage)
        {
                case TOK_TITLE:
                case TOK_ALBUM:
                case TOK_ARTIST:
                case TOK_GENRE:
                case TOK_PLAYLIST:
                        send_command dvTPs, "'@PPN-',sPopupAudio";
                break;

                case TOK_QUEUE:
                        send_command dvTPs, "'@PPN-',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'";
        }

        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,'";
}

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:
                        send_command dvTPs, "'@PPN-',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'";
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU3),',0,Open folder'";
                break;

                case TOK_PLAYLIST:
                        send_command dvTPs, "'@PPN-',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'";
                        send_command dvTPs, "'^TXT-',itoa(BTN_MENU3),',0,Show content'";
                break;

                case TOK_QUEUE:
                        send_command dvTPs, "'@PPN-',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;
        }

        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'";
        }
}

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_ALBUM:
                                case TOK_ARTIST:
                                case TOK_GENRE:
                                case TOK_PLAYLIST:
                                        send_command dvTPs[pan], "'@PPN-',sPopupAudio";
                                        send_command vdvMDB, "'LIST:',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;
                        }
                }
        }

        /*
         * The navigation buttons are for setting the wanted views.
         */
        button_event[dvTPs, nNavigation]
        {
                push:
                {
                        switch(BUTTON.INPUT.CHANNEL)
                        {
                                case BTN_TITLE:         send_command vdvMDB, "'LIST:TITLE:1:',itoa(MAX_LINES),';'"; nFolder = 0; break;
                                case BTN_ARTIST:        send_command vdvMDB, "'LIST:ARTIST:1:',itoa(MAX_LINES),';'"; nFolder = 0; break;
                                case BTN_ALBUM:         send_command vdvMDB, "'LIST:ALBUM:1:',itoa(MAX_LINES),';'"; nFolder = 0; break;
                                case BTN_GENRE:         send_command vdvMDB, "'LIST:GENRE:1:',itoa(MAX_LINES),';'"; nFolder = 0; break;
                                case BTN_NOW_PLAYING: send_command vdvMDB, "'LIST:QUEUE:1:',itoa(MAX_LINES),';'"; nFolder = 0; 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, 'PAUSE;';
                                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_DN:
                                        if (nStart > MAX_LINES)
                                        {
                                                nStart = nStart - MAX_LINES;
                                                send_command vdvMDB, "'LIST:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                        }
                                break;

                                case MENU_THUMBS_UP:
                                        if (nTotal && (nStart+MAX_LINES) <= nTotal)
                                        {
                                                nStart = nStart + MAX_LINES;
                                                send_command vdvMDB, "'LIST:',requestActualPage(),':',itoa(nStart),':',itoa(MAX_LINES),';'";
                                        }
                                break;

                                case MENU_BACK:
                                        if (nFolder)
                                                send_command vdvMDB, "'LIST:',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:
                                        nLastPressedLine = 1;
                                        askMenuList();
                                break;

                                case BTN_LINE2_PIC:
                                case BTN_LINE2_LINE:
                                        nLastPressedLine = 2;
                                        askMenuList();
                                break;

                                case BTN_LINE3_PIC:
                                case BTN_LINE3_LINE:
                                        nLastPressedLine = 3;
                                        askMenuList();
                                break;

                                case BTN_LINE4_PIC:
                                case BTN_LINE4_LINE:
                                        nLastPressedLine = 4;
                                        askMenuList();
                                break;

                                case BTN_LINE5_PIC:
                                case BTN_LINE5_LINE:
                                        nLastPressedLine = 5;
                                        askMenuList();
                                break;

                                case BTN_LINE6_PIC:
                                case BTN_LINE6_LINE:
                                        nLastPressedLine = 6;
                                        askMenuList();
                                break;

                                case BTN_LINE7_PIC:
                                case BTN_LINE7_LINE:
                                        nLastPressedLine = 7;
                                        askMenuList();
                                break;

                                case BTN_LINE8_PIC:
                                case BTN_LINE8_LINE:
                                        nLastPressedLine = 8;
                                        askMenuList();
                                break;

                                case BTN_LINE9_PIC:
                                case BTN_LINE9_LINE:
                                        nLastPressedLine = 9;
                                        askMenuList();
                                break;

                                case BTN_LINE10_PIC:
                                case BTN_LINE10_LINE:
                                        nLastPressedLine = 10;
                                        askMenuList();
                                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;';
                                                send_command vdvMDB, "'PLAY:',requestActualPage(),':',getPageLine(nLastPressedLine),';'";
                                        }
                                        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;';
                                                        send_command vdvMDB, "'PLAY:PLAYLIST:',EncodeURL(sActPlaylist),';'";
                                                }
                                        }
                                        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
                                                send_command vdvMDB, "'ADD:',requestActualPage(),':',EncodeURL(getPageLine(nLastPressedLine)),';'";
                                        else if (nPage == TOK_PLAYLIST)
                                                send_command vdvMDB, "'ADD:PLAYLIST:',EncodeURL(sActPlaylist),';'";
                                        else if (nPage == TOK_QUEUE)
                                        {
                                                send_command dvTPs[pan], "'@PPN-',sPopupSelUser";
                                                send_command dvTPs[pan], "'^TXT-',itoa(TEXT_INPUT_UNAME),',0,',sActUser";
                                                send_command dvTPs[pan], "'@AKB-',sActPlaylist,';Enter name of playlist'";
                                                nSaveToFolder = nLastPressedLine;
                                                nKeyboard[pan] = TEXT_INPUT_PLAYLIST;
                                        }
                                break;
                                
                                case BTN_MENU3:
                                        if (nPage != TOK_PLAYLIST && nPage != TOK_QUEUE)        // Open folder
                                        {
                                                sActFolder = getPageLine(nLastPressedLine);
                                                nFolder = true;
                                                send_command vdvMDB, "'LISTFOLDER:',requestActualPage(),':',EncodeURL(getPageLine(nLastPressedLine)),':1:',itoa(MAX_LINES),';'";
                                        }
                                        else if (nPage == TOK_PLAYLIST)
                                        {
                                        }
                                        else if (nPage == TOK_QUEUE)
                                                send_command vdvMDB, "'DELETE:QUEUE:',itoa(stSong[nLastPressedLine].nID),';'";
                                break;
                        }
                }
        }

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

                        pan = get_last(dvTPs);

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

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

                        pan = get_last(dvTPs);

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

        /*
         * 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, 'LIST:', 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, 'LIST:', 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));
                                                                case 4: stSong[nLine].sTitle = getStrTok(i);
                                                                case 5: stSong[nLine].sArtist = getStrTok(i);
                                                                case 6: stSong[nLine].sAlbum = getStrTok(i);
                                                                case 7: stSong[nLine].sGenre = getStrTok(i);
                                                                case 8: stSong[nLine].sCover = getStrTok(i);
                                                        }
                                                }

                                                stSong[nLine].nID = nSongID;

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

                                                displaySong(nLine);
                                        }

                                        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 vdvMDB, "'^TXT-',itoa(TEXT_DETAIL_TITLE),',0,',sTitle";
                                                send_command vdvMDB, "'^TXT-',itoa(TEXT_DETAIL_ARTIST),',0,',sArtist";
                                                send_command vdvMDB, "'^TXT-',itoa(TEXT_DETAIL_ALBUM),',0,',sAlbum";
                                                send_command vdvMDB, "'^TXT-',itoa(TEXT_DETAIL_GENRE),',0,',sGenre";
                                                setLogo(sCover, 0);
                                        }

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

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

                                        active(find_string(buf, 'PLAYER:')):
                                        {
                                                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, 'KEYBOARD:', 1)):
                                        {
                                        stack_var integer pan;
        
                                                remove_string(buf, 'KEYBOARD:', 1);
                                                pan = atoi(buf);
                                                remove_string(buf, ':', 1);
        
                                                if (nKeyboard[pan] == TEXT_INPUT_UNAME)
                                                {
                                                        sActUser = left_string(buf, length_string(buf) - 1);
                                                        send_command dvTPs[pan], "'@PPF-',sPopupSelUser";
                                                        send_command vdvMDB, "'USER:',EncodeURL(sActUser),':;'";
                                                        nKeyboard[pan] = 0;
                                                }
                                                else if (nKeyboard[pan] == TEXT_INPUT_PLAYLIST)
                                                {
                                                        if (!nSaveToFolder)
                                                        {
                                                                sActPlaylist = left_string(buf, length_string(buf) - 1);
                                                                send_command vdvMDB, "'USER:',EncodeURL(sActUser),':',EncodeURL(sActPlaylist),';'";
                                                        }
                                                        else
                                                        {
                                                                stack_var char sPlaylist[128];

                                                                sPlaylist = left_string(buf, length_string(buf) - 1);
                                                                send_command vdvMDB, "'SAVEQUEUE:',EncodeURL(sActUser),':',EncodeURL(sPlaylist),';'";
                                                                nSaveToFolder = 0;
                                                        }

                                                        send_command dvTPs[pan], "'@PPF-',sPopupSelUser";
                                                        nKeyboard[pan] = 0;
                                                }
                                        }
                                }
                        }
                }
        }