/***************************************************************************
 *   Copyright (C) 2005 by Reel Multimedia                                 *
 *                                                                         *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <vector>

#include "stringtools.h"
#include "player.h"
#include "filecache.h"
#include "playlist.h"
#include "setup.h"
#include "menushow.h"

//----------cMenuShowFile-----------------------

cMenuShowFile::cMenuShowFile(std::string title, cPlayList *Playlist, cFileCache *Cache, cImageConvert *Convert)
:cMenuFileBrowserBase(title), player_(NULL), playlist_(Playlist), convert_(Convert), cache_(Cache), state_(plInvalid), 
 msg_(""), slideShow_(fileBrowserSetup.slideShow)
{
    DELETENULL(displayMenu);  //Destroy Display Menu while Picture is shown 

    UpdateImage();
    StartPlayer();
}

cMenuShowFile::~cMenuShowFile()
{ 
    Shutdown();
} 

void cMenuShowFile::Shutdown()
{
    cControl::Shutdown();
    if(!displayMenu)
    {
        displayMenu = Skins.Current()->DisplayMenu();  //reconstruct Display Menu
        displayMenuItems = displayMenu->MaxItems();
    }
    if(convert_)
    {
        convert_->ClearConvertedFiles();
    }
}

eOSState cMenuShowFile::ProcessKey(eKeys Key)
{
    UpdateShow();

    eOSState state = osUnknown;

    state = ProcessKey2(Key);

    if(state == osUnknown && slideShow_ && timer_.TimedOut())
    {
        state = ShowNext(true, fileBrowserSetup.cyclic, fileBrowserSetup.random);
    }

    if (UpdateMessage())
    {
        eKeys key = Skins.Message(mtInfo,msg_.c_str());
        state = ProcessKey2(key);
    }

    if(state == osBack)
    {
        return osBack;
    }
    else
    {
        return osUser1; //never handle this call in supermenus
    }
}

eOSState cMenuShowFile::ProcessKey2(eKeys Key)
{
    eOSState state = osUnknown;
    switch (Key)
    {
        case kBack:
            return osBack;
        case kUp:
        case kRight:
            state = ShowNext(true, fileBrowserSetup.cyclic);
            break;
        case kDown:
        case kLeft:
            state = ShowNext(false, fileBrowserSetup.cyclic);
            break;
        case kPlay:
            ToggleSlideShow(true);
            state = osContinue;
            break;
        case kStop:
        case kPause:
            ToggleSlideShow(false);
            state = osContinue;
            break;
        default:
            break;
    }
    return state;
}

void cMenuShowFile::Show()
{
    if(player_)
    {
        player_->ShowPicture(&(convertedFile_.buffer[0]), convertedFile_.buffer.size());
    }
    timer_.Start();
    state_ = plValid;
}

void cMenuShowFile::UpdateShow()
{
    if(state_ != plValid)
    {
        if(cache_ && cache_->FetchFromCache(playlist_->GetCurrent().GetPath(), convertedFile_.buffer))
        { 
            Show();
        }
        else if(convert_ && convert_->GetConvertedFile(playlist_->GetCurrent(), convertedFile_))
        { 
            if(convertedFile_.valid)
            {
                Show();
            }
            else
            { 
                state_ = plError;
                timer_.Start(1);
            }
        }
    }
}

eOSState cMenuShowFile::ShowNext(bool forward, bool cyclic, bool random)
{
    bool next = true;
    if((state_ == plValid || state_ == plError) && !playlist_->IsEmpty())
    {
        if(random)
        {
            playlist_->NextRandom();
        }
        else if(cyclic)
        {
            playlist_->NextCyclic(forward);
        }
        else
        {
            next = playlist_->Next(forward);
        }

        if(next && UpdateImage())
        {
            Show();
        }
    }
    /*if(!next) //do not exit when last imaged displayed
    {
       return osBack;
    }*/
    return osContinue;
}

bool cMenuShowFile::UpdateMessage()
{
    std::string msg = "";
    if(state_ == plValid && fileBrowserSetup.displayFileNames)
    { 
        msg = GetLast(playlist_->GetCurrent().GetPath());
    } 
    else if(state_ == plInvalid && fileBrowserSetup.displayFileNames)
    {
        msg = GetLast(playlist_->GetCurrent().GetPath()) + tr(" ...opening file");
    } 
    else if (state_ == plError)
    {
        msg = std::string(tr("Can't open file:")) + " " + GetLast(playlist_->GetCurrent().GetPath());
    }
    if(msg_ != msg)
    {
        msg_= msg;
        if(msg_ != "")
        {
            return true;
        }
    }
    return false;
}

bool cMenuShowFile::UpdateImage()
{
    if(!cache_ || !cache_->FetchFromCache(playlist_->GetCurrent().GetPath(), convertedFile_.buffer))
    {
        if(convert_)
        {
            StartConversion(); 
            state_ = plInvalid;
        }
        else
        {
            state_ = plError; 
            timer_.Start(1);
        }
        return false;
    }
    return true;
}

void cMenuShowFile::StartConversion()
{
    convert_->InsertInConversionList(playlist_->GetCurrent(), true);
    convert_->StartConversion();
}

void cMenuShowFile::StartPlayer()
{
    player_ = new cStillPicturePlayer;
    cControl *control = new cStillPictureControl(player_, true);
    cControl::Launch(control);
}

void cMenuShowFile::ToggleSlideShow(bool on)
{
    if(on)
    {
        if(!slideShow_)
        {
            ShowNext(true, fileBrowserSetup.cyclic);
            slideShow_ = true;
            Skins.Message(mtInfo,tr("Slide show started")); //TODO: find out if this call really crashes remote in scarce situations
        }
    }
    else
    {
        if(slideShow_)
        {
            slideShow_ = false; 
            Skins.Message(mtInfo,tr("Slide show halted"));
        }
    }
}

