#include <dirent.h>

#include "channelswitcher.h"
#include "channelmenu.h"
#include "channelsetup.h"

/**
 **************************************************************************************
 * Constructor
 **************************************************************************************
 */
cSwitchMenu::cSwitchMenu( cSwitcher *SwitcherPlug ):cOsdMenu( tr( "Channels.conf SwitcherPlug" ), 20 )
{
    switcher = SwitcherPlug;
    int i, n, nc;
    struct dirent **namelist;
    char *dir;
    char *filename,*name;

    for( i = 0; i < NB_MAX_CHANNEL_CONF; i++ )
        ListChanConf[i] = NULL;
    m_nbChanConf = 0;

    /// Add the default item -> channels.conf
    AddSwitchMenuItem( "Defaut", "channels.conf" );

    /// Browse directory
    asprintf( &dir, "%s/../", cPlugin::ConfigDirectory(  ) );
    n = scandir( dir, &namelist, 0, alphasort );
    nc = 0;
    if( n < 0 )
    {
        perror( "[channelswitcher] scandir() error !" );
    }
    else
    {
        while( nc < n )
        {
            if( strncmp( "channels.conf.", namelist[nc]->d_name, 14 ) == 0 )
            {
                filename = strdup( namelist[nc]->d_name );

                /// extract name of channel.conf (end part of filename)
                name = strtok( namelist[nc]->d_name, "." );
                if( name != NULL ) name = strtok( NULL, "." );
                if( name != NULL ) name = strtok( NULL, "." );

                if( name != NULL )
                {
                    /// Add item
                    AddSwitchMenuItem( name, filename );
                }

                free( namelist[nc] );
                free( filename );
            }
            nc++;
        }
        free( namelist );
    }
    free( dir );
}

/**
 **************************************************************************************
 * Destructor
 **************************************************************************************
 */
cSwitchMenu::~cSwitchMenu( void )
{
    int i;

    /// Free Memory
    for( i = 0; i < m_nbChanConf; i++ )
    {
        if( ListChanConf[m_nbChanConf] != NULL )
        {
            free( ListChanConf[m_nbChanConf] );
            ListChanConf[m_nbChanConf] = NULL;
        }
    }
    m_nbChanConf = 0;
}

/**
 **************************************************************************************
 * Add a files to list of channels.conf and to menu
 *
 * @return 0=Sucess <0=Failure
 **************************************************************************************
 */
int cSwitchMenu::AddSwitchMenuItem( char *itemName, char *fileName )
{
    int addOk = -1;
    cOsdItem *item;

     if( m_nbChanConf < NB_MAX_CHANNEL_CONF )
    {
        item = new cOsdItem( itemName, osUser3 );
        Add( item );

        ListChanConf[m_nbChanConf] = strdup( fileName );
        m_nbChanConf++;

        addOk = 0;
    }
    else
    {
        /// error : too many channels.conf
        addOk = -1;
    }

    return ( addOk );
}

/**
 **************************************************************************************
 *
 *
 **************************************************************************************
 */
eOSState cSwitchMenu::ProcessKey( eKeys Key )
{
    eOSState state = cOsdMenu::ProcessKey( Key );
    char *ToLoad;
    extern cSwitchConfig config;

    switch ( state )
    {
        case osUser3:
            cTimer * time;
            time = Timers.First(  );
            
            // Check whether there is an active timer
            if( time )
            {
                Skins.Message( mtError, "Programmation en cours..." );
                sleep( Setup.OSDMessageTime );
                Skins.Message( mtStatus, "" );
                return osBack;
            }
            
            // Save Setup.UpdateChannels value before setting it to 0
            SaveSetup = Setup.UpdateChannels;
            Setup.UpdateChannels = 0;
            
            // Store selected channels.conf filename to setup file
            switcher->SetupStore("channelsConf", config.channelsConf = ListChanConf[Current(  )] );

            // Load selected channels.conf
            asprintf( &ToLoad, "%s/../%s", cPlugin::ConfigDirectory(  ), ListChanConf[Current(  )] );
            Channels.Load( ToLoad );
            free( ToLoad );
            
            // Switch to first channel of selected channels.conf
            // (needed before restoring Setup.UpdateChannels)
            Channels.SwitchTo( 1 );
            
            // Restore Setup.UpdateChannels and save config
            Setup.UpdateChannels = SaveSetup;
            Setup.Save(  );
            
            // Print OSD message
            asprintf( &ToLoad, "'%s' actif", ListChanConf[Current(  )] );
            printf( "[channelswitcher] switch to '%s'\n",ListChanConf[Current(  )] );
            Skins.Message( mtStatus, ToLoad );
            free( ToLoad );
            sleep( Setup.OSDMessageTime );
            Skins.Message( mtStatus, "" );
            return osBack;
            break;
        default:
            break;
    }
    return state;
}

void cSwitchMenu::Draw( void )
{
}

void cSwitchMenu::Switch( void )
{
}
