/*  ColdFish Music Player
 *  Copyright (C) 2003 Kristian Van Der Vliet
 *  Copyright (C) 2003 Arno Klenke
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of version 2 of the GNU Library
 *  General Public License as published by the Free Software
 *  Foundation.
 *
 *  This library 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
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 *  MA 02111-1307, USA
 */

#include "CFWindow.h"
//#include "lcd.h"
#include "SelectWin.h"
//#include "cimagebutton.h"
#include "messages.h"

//----------------------------------------------------------------------------------

void SetCButtonImageFromResource( os::CImageButton* pcButton, os::String zResource )
{
	os::File cSelf( open_image_file( get_image_id() ) );
	os::Resources cCol( &cSelf );		
	os::ResStream *pcStream = cCol.GetResourceStream( zResource );
	pcButton->SetImage( pcStream );
	pcButton->Flush();
	pcButton->Sync();
	delete( pcStream );
}

void SetCButtonSelectedImageFromResource( os::CImageButton* pcButton, os::String zResource )
{
	os::File cSelf( open_image_file( get_image_id() ) );
	os::Resources cCol( &cSelf );		
	os::ResStream *pcStream = cCol.GetResourceStream( zResource );
	pcButton->SetSelectedImage( pcStream );
	pcButton->Flush();
	pcButton->Sync();
	delete( pcStream );
}

//----------------------------------------------------------------------------------

CFPlaylist::CFPlaylist( const os::Rect & cFrame ):os::ListView( cFrame, "cf_playlist", os::ListView::F_RENDER_BORDER, os::CF_FOLLOW_ALL )
{
}

void CFPlaylist::MouseUp( const os::Point & cPos, uint32 nButtons, os::Message * pcData )
{
	os::String zFile;
	if ( pcData == NULL || pcData->FindString( "file/path", &zFile.str() ) != 0 )
	{
		return ( os::ListView::MouseUp( cPos, nButtons, pcData ) );
	}
	/* Tell CFApp class */
	os::Message cMsg( *pcData );
	cMsg.SetCode( CF_ADD_FILE );
	os::Application::GetInstance()->PostMessage( &cMsg, os::Application::GetInstance() );
}

//----------------------------------------------------------------------------------

CFWindow::CFWindow( const os::Rect & cFrame, const os::String & cName, const os::String & cTitle, uint32 nFlags ):os::Window( cFrame, cName, cTitle, nFlags )
{
	m_nState = CF_STATE_STOPPED;
	os::Rect cNewFrame = GetBounds();

	/* Create menubar */
	m_pcMenuBar = new os::Menu( os::Rect( 0, 0, 1, 1 ), "cf_menu_bar", os::ITEMS_IN_ROW );
	os::Menu* pcAppMenu = new os::Menu( os::Rect(), "Application", os::ITEMS_IN_COLUMN );
	pcAppMenu->AddItem( "About...", new os::Message( CF_GUI_ABOUT ) );
	pcAppMenu->AddItem( new os::MenuSeparator() );
	pcAppMenu->AddItem( "Quit", new os::Message( CF_GUI_QUIT ) );
	m_pcMenuBar->AddItem( pcAppMenu );
	/* Playlist menu */
	os::Menu* pcPlaylistMenu = new os::Menu( os::Rect(), "Playlist", os::ITEMS_IN_COLUMN );
	pcPlaylistMenu->AddItem( "Select...", new os::Message( CF_GUI_SELECT_LIST ) );
	pcPlaylistMenu->AddItem( "Open Input...", new os::Message( CF_GUI_OPEN_INPUT ) );
	m_pcMenuBar->AddItem( pcPlaylistMenu );
	/* File menu */
	os::Menu* pcFileMenu = new os::Menu( os::Rect(), "File", os::ITEMS_IN_COLUMN );
	pcFileMenu->AddItem( "Add...", new os::Message( CF_GUI_ADD_FILE ) );
	pcFileMenu->AddItem( "Remove", new os::Message( CF_GUI_REMOVE_FILE ) );
	m_pcMenuBar->AddItem( pcFileMenu );
	/* View menu */
	os::Menu* pcViewMenu = new os::Menu( os::Rect(), "View", os::ITEMS_IN_COLUMN );
	pcViewMenu->AddItem( "Playlist", new os::Message( CF_GUI_VIEW_LIST ) );
	m_pcMenuBar->AddItem( pcViewMenu );

	cNewFrame = m_pcMenuBar->GetFrame();
	cNewFrame.right = GetBounds().Width();
	cNewFrame.bottom = cNewFrame.top + m_pcMenuBar->GetPreferredSize( false ).y;
	m_pcMenuBar->SetFrame( cNewFrame );
	m_pcMenuBar->SetTargetForItems( this );

	cNewFrame = GetBounds();
	cNewFrame.top += m_pcMenuBar->GetPreferredSize( false ).y + 1;
	cNewFrame.bottom = cNewFrame.top + 70;

	/* Create root view */
	m_pcRoot = new os::LayoutView( cNewFrame, "cf_root", NULL, os::CF_FOLLOW_LEFT | os::CF_FOLLOW_TOP | os::CF_FOLLOW_RIGHT );

	/* Create control view */
	m_pcControls = new os::HLayoutNode( "cf_controls" );
	m_pcControls->SetBorders( os::Rect( 2, 5, 2, 5 ) );

	/* Create buttons */
	m_pcPlay = new os::CImageButton( os::Rect( 0, 0, 1, 1 ), "cf_playorpause", "Play", new os::Message( CF_GUI_PLAY ), NULL, os::ImageButton::IB_TEXT_BOTTOM, false, false, true );
	SetCButtonImageFromResource( m_pcPlay, "play.png" );
	SetCButtonSelectedImageFromResource( m_pcPlay, "play_sel.png" );

	m_pcStop = new os::CImageButton( os::Rect( 0, 0, 1, 1 ), "cf_stop", "Stop", new os::Message( CF_GUI_STOP ), NULL, os::ImageButton::IB_TEXT_BOTTOM, false, false, true );
	SetCButtonImageFromResource( m_pcStop, "stop.png" );
	SetCButtonSelectedImageFromResource( m_pcStop, "stop_sel.png" );

	m_pcShowList = new os::CImageButton( os::Rect( 0, 0, 1, 1 ), "cf_show_list", "Playlist", new os::Message( CF_GUI_SHOW_LIST ), NULL, os::ImageButton::IB_TEXT_BOTTOM, false, false, true );
	SetCButtonImageFromResource( m_pcShowList, "list.png" );
	SetCButtonSelectedImageFromResource( m_pcShowList, "list_sel.png" );

	m_pcStop->SetEnable( false );

	os::VLayoutNode * pcCenter = new os::VLayoutNode( "cf_v_center" );

	/* Create LCD */
	m_pcLCD = new os::Lcd( os::Rect( 0, 0, 1, 1 ), new os::Message( CF_GUI_SEEK ) );
	m_pcLCD->SetTarget( this );
	m_pcLCD->SetEnable( false );
	pcCenter->AddChild( m_pcLCD );
	AddTimer( m_pcLCD, 123, 1000000, false );

	m_pcControls->AddChild( m_pcPlay );
	m_pcControls->AddChild( m_pcStop );
	m_pcControls->AddChild( pcCenter );
	m_pcControls->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );
	m_pcControls->AddChild( m_pcShowList );
	m_pcControls->SameWidth( "cf_playorpause","cf_stop", "cf_show_list", NULL );
	m_pcRoot->SetRoot( m_pcControls );

	/* Create playlist */
	cNewFrame = GetBounds();
	cNewFrame.top = 71 + m_pcMenuBar->GetPreferredSize( false ).y + 1;
	m_pcPlaylist = new CFPlaylist( cNewFrame );
	m_pcPlaylist->SetInvokeMsg( new os::Message( CF_GUI_LIST_INVOKED ) );
	m_pcPlaylist->SetTarget( this );
	m_pcPlaylist->SetAutoSort( false );
	m_pcPlaylist->SetMultiSelect( false );
	m_pcPlaylist->InsertColumn( "File", (int)cNewFrame.Width() - 105 );
	m_pcPlaylist->InsertColumn( "Track", 50 );
	m_pcPlaylist->InsertColumn( "Length", 55 );

	AddChild( m_pcPlaylist );
	AddChild( m_pcMenuBar );
	AddChild( m_pcRoot );

	/* Create file selector */
	m_pcFileDialog = new os::FileRequester( os::FileRequester::LOAD_REQ, new os::Messenger( os::Application::GetInstance() ), "", os::FileRequester::NODE_FILE, true );
	m_pcFileDialog->Lock();
	m_pcFileDialog->Start();
	m_pcFileDialog->Unlock();

	/* Set Icon */
	os::Resources cCol( get_image_id() );
	os::ResStream *pcStream = cCol.GetResourceStream( "icon24x24.png" );
	os::BitmapImage *pcIcon = new os::BitmapImage( pcStream );
	SetIcon( pcIcon->LockBitmap() );
	delete( pcIcon );

	SetSizeLimits( os::Point( 400,150 ), os::Point( 4096, 4096 ) );
}

CFWindow::~CFWindow()
{
}

void CFWindow::HandleMessage( os::Message * pcMessage )
{
	switch ( pcMessage->GetCode() )
	{
		/* Open file selector */
		case CF_GUI_ADD_FILE:
		{
			m_pcFileDialog->Show();
			m_pcFileDialog->MakeFocus( true );
			break;
		}
		/* Message sent by the CFApp class */
		case CF_STATE_CHANGED:
		{
			if ( m_nState == CF_STATE_STOPPED )
			{
				SetCButtonImageFromResource( m_pcPlay, "play.png" );
				SetCButtonSelectedImageFromResource( m_pcPlay, "play_sel.png" );
				m_pcPlay->Paint( m_pcPlay->GetBounds() );
				m_pcStop->SetEnable( false );
				m_pcLCD->SetEnable( false );
			}
			else if ( m_nState == CF_STATE_PLAYING )
			{
				SetCButtonImageFromResource( m_pcPlay, "pause.png" );
				SetCButtonSelectedImageFromResource( m_pcPlay, "pause_sel.png" );				
				m_pcPlay->Paint( m_pcPlay->GetBounds() );
				m_pcStop->SetEnable( true );
				m_pcLCD->SetEnable( true );
			}
			else if ( m_nState == CF_STATE_PAUSED )
			{
				SetCButtonImageFromResource( m_pcPlay, "play.png" );
				SetCButtonSelectedImageFromResource( m_pcPlay, "play_sel.png" );				
				m_pcPlay->Paint( m_pcPlay->GetBounds() );
				m_pcStop->SetEnable( true );
				m_pcLCD->SetEnable( false );
			}
			Sync();
			break;
		}
		/* Show about alert */
		case CF_GUI_ABOUT:
		{
			ShowAbout(); 
			break;
		}
		/* Forward messages to the CFApp class */
		case CF_GUI_PLAY:
		{
			if (m_nState == CF_STATE_STOPPED || m_nState == CF_STATE_PAUSED)
				os::Application::GetInstance()->PostMessage( CF_GUI_PLAY, os::Application::GetInstance() );
			else if (m_nState == CF_STATE_PLAYING)
				os::Application::GetInstance()->PostMessage( CF_GUI_PAUSE, os::Application::GetInstance() );
			break;
		}
		case CF_GUI_PAUSE:
		case CF_GUI_STOP:
		case CF_GUI_SEEK:
		case CF_GUI_REMOVE_FILE:
		case CF_GUI_SELECT_LIST:
		case CF_GUI_OPEN_INPUT:
		case CF_GUI_QUIT:
		case CF_GUI_SHOW_LIST:
		case CF_GUI_VIEW_LIST:
		case CF_GUI_LIST_INVOKED:
		{
			os::Application::GetInstance()->PostMessage( pcMessage, os::Application::GetInstance() );
			break;
		}
		default:
		{
			os::Window::HandleMessage( pcMessage );
			break;
		}
	}
}

void CFWindow::ShowAbout()
{
	os::Alert* pcAbout = new os::Alert( "About ColdFish",
		"ColdFish V1.2.1\n\n"
		"A Music Player\n"
		"Copyright 2003 Arno Klenke\n"
		"Copyright 2003 Kristian Van Der Vliet\n"
		"Copyright 2005 Rick Caudill\n\n"
		"ColdFish is released under the LGPL.",
		os::Alert::ALERT_INFO, os::WND_NOT_RESIZABLE, "OK", NULL );
	pcAbout->Go( new os::Invoker( 0 ) );
}

bool CFWindow::OkToQuit()
{
	os::Application::GetInstance()->PostMessage( os::M_QUIT );
	return ( false );
}