#include "folderWindow.h"
#include "directoryview.h"
#include "ltostr.h"

#include <unistd.h>

folderWindow::folderWindow( char *path, appConfig * inputConfig ):os::Window( os::Rect( 20, 100, 500, 400 ), "folderWindow", path, 0, os::CURRENT_DESKTOP )
{
	os::Rect menuRect = GetBounds();
	os::Rect r;

	strcpy( windowPath, path );
	mainConfig = inputConfig;

	/* Creating the main menu for a folder window
	 */

	menuRect.bottom = 18;
	os::Menu * mainMenu = new os::Menu( menuRect, "mainMenu", os::ITEMS_IN_ROW );

	// File menu
	os::Menu * tempSubMenu = new os::Menu( os::Rect( 0, 0, 0, 0 ), "File", os::ITEMS_IN_COLUMN );
	tempSubMenu->AddItem( "Exit", new os::Message( ID_MENU_FILE_EXIT ) );
	mainMenu->AddItem( tempSubMenu );
#if 0
	// Edit menu
	tempSubMenu = new os::Menu( os::Rect( 0, 0, 0, 0 ), "Edit", os::ITEMS_IN_COLUMN );
	tempSubMenu->AddItem( "Copy file ...", new os::Message( ID_MENU_EDIT_CPFILE ) );
	tempSubMenu->AddItem( "Move file ...", new os::Message( ID_MENU_EDIT_MVFILE ) );
	tempSubMenu->AddItem( "Delete", new os::Message( ID_MENU_EDIT_DELETE ) );
	tempSubMenu->AddItem( new os::MenuSeparator() );
	tempSubMenu->AddItem( "Cut", new os::Message( ID_MENU_EDIT_CUT ) );
	tempSubMenu->AddItem( "Copy", new os::Message( ID_MENU_EDIT_COPY ) );
	tempSubMenu->AddItem( "Paste", new os::Message( ID_MENU_EDIT_PASTE ) );
	tempSubMenu->AddItem( new os::MenuSeparator() );
	tempSubMenu->AddItem( "Options", new os::Message( ID_MENU_EDIT_OPTIONS ) );
	mainMenu->AddItem( tempSubMenu );
#endif
	// Help menu
	tempSubMenu = new os::Menu( os::Rect( 0, 0, 0, 0 ), "Help", os::ITEMS_IN_COLUMN );
	tempSubMenu->AddItem( "About ...", new os::Message( ID_MENU_HELP_ABOUT ) );
	mainMenu->AddItem( tempSubMenu );

	mainMenu->SetTargetForItems( this );
	AddChild( mainMenu );

	/* Creating the buttons
	 */

	os::Button * parentButton = new os::Button( os::Rect( 5, 21, 31, 41 ), "up_button", "Up", new os::Message( ID_BUTTON_UP ), os::CF_FOLLOW_LEFT | os::CF_FOLLOW_TOP, 0 );
	AddChild( parentButton );

	os::Button * homeButton = new os::Button( os::Rect( 36, 21, 82, 41 ), "home_Button", "Home", new os::Message( ID_BUTTON_HOME ), os::CF_FOLLOW_LEFT | os::CF_FOLLOW_TOP, 0 );
	AddChild( homeButton );

	os::Button * refreshButton = new os::Button( os::Rect( 87, 21, 140, 41 ), "refresh_Button", "Refresh", new os::Message( ID_BUTTON_REFRESH ), os::CF_FOLLOW_LEFT | os::CF_FOLLOW_TOP, 0 );
	AddChild( refreshButton );

	r = GetBounds();
	r.left = 145;
	r.top = 21;
	r.right -= 5;
	r.bottom = 41;
	locationBar = new os::TextView( r, "lLabel", windowPath, os::CF_FOLLOW_LEFT | os::CF_FOLLOW_RIGHT | os::CF_FOLLOW_TOP, 0 );
	locationBar->SetEventMask( os::TextView::EI_ENTER_PRESSED );
	locationBar->SetMessage( new os::Message( ID_LOCATION_BAR_INVOKED ) );
	locationBar->SetTarget( this );
	AddChild( locationBar );

	/* The information label
	 */

	r = GetBounds();
	r.left = 5;
	r.right -= 1;
	r.bottom -= 1;
	r.top = r.bottom - 12;

	infoLabel = new os::StringView( r, "iLabel", "", os::ALIGN_LEFT, os::CF_FOLLOW_LEFT | os::CF_FOLLOW_RIGHT | os::CF_FOLLOW_BOTTOM, os::WID_WILL_DRAW | os::WID_FULL_UPDATE_ON_RESIZE );
	AddChild( infoLabel );

	/* The main view
	 */

	r = GetBounds();
	r.top = 41;
	r.bottom -= 18;

	mainView2 = new os::DirectoryView( r, windowPath, 1, os::CF_FOLLOW_ALL, 0 );
	mainView2->SetDirChangeMsg( new os::Message( ID_DIRECTORY_CHANGE ) );
	mainView2->SetInvokeMsg( new os::Message( ID_DIRECTORY_INVOKED ) );
	mainView2->SetSelChangeMsg( new os::Message( ID_SELECTION_CHANGE ) );
	AddChild( mainView2 );
}

bool folderWindow::OkToQuit( void )
{
	os::Application::GetInstance()->PostMessage( os::M_QUIT );
	return ( true );
}

void folderWindow::HandleMessage( os::Message * pcMessage )
{
	int i, j;
	char tempFileName[4096];
	char tempAction[4096];
	char finalAction[4096];
	char *cursorFinalAction;

	switch ( pcMessage->GetCode() )
	{
		case ID_MENU_FILE_EXIT:
		{
			OkToQuit();
			break;
		}
		case ID_MENU_HELP_ABOUT:
		{
			os::Alert *aboutBox = new os::Alert( "Manager v0.0.1",
				"Manager v0.0.1\n"
				"File management utility for AtheOS\n\n"
				"Written by Stephane Aubry (arbogad@free.fr)\n"
				"http://arbogad.free.fr/atheos/\n\n"
				"Copyright © David Kent 2015\n\n"
				"Manager is released under the GNU General Public License.\n"
				"Please see the file COPYING, distributed with Manager,\n"
				"or http://www.gnu.org for more information.",
				0x00, "Close", NULL );
			aboutBox->Go( new os::Invoker() );
			aboutBox->CenterInWindow( this );
			break;
		}
		case ID_BUTTON_UP:
		{
			DirectoryUp();
			mainView2->SetPath( windowPath );
			mainView2->Clear();
			mainView2->ReRead();
			locationBar->Set( windowPath, true );
			SetTitle( windowPath );
			break;
		}
		case ID_BUTTON_HOME:
		{
			char *userHome = getenv( "HOME" );
			mainView2->SetPath( userHome );
			mainView2->Clear();
			mainView2->ReRead();
			strcpy( windowPath, ( mainView2->GetPath() ).c_str() );
			locationBar->Set( windowPath, true );
			SetTitle( windowPath );
			mainView2->MakeFocus();
			break;
		}
		case ID_BUTTON_REFRESH:
		{
			mainView2->SetPath( windowPath );
			mainView2->Clear();
			mainView2->ReRead();
			locationBar->Set( windowPath, true );
			SetTitle( windowPath );
			mainView2->MakeFocus();
			break;
		}
		case ID_DIRECTORY_CHANGE:
		{
			infoLabel->SetString( "" );
			strcpy( windowPath, ( mainView2->GetPath() ).c_str() );
			locationBar->Set( windowPath, true );
			SetTitle( windowPath );
		 	break;
		}
		case ID_DIRECTORY_INVOKED:
		{
			struct::stat tempFileStat;

			for( i = mainView2->GetFirstSelected(); i <= mainView2->GetLastSelected(); i++ )
			{
				if( mainView2->IsSelected( i ) )
				{
					strcpy( tempFileName, mainView2->GetFile( i )->GetName().c_str() );
					strcpy( tempAction, ( mainConfig->mainMimeTable->getType( tempFileName ) )->action );

					if( strcmp( tempAction, " " ) )
					{
						// The file has a predifined action
						j = 0;
						cursorFinalAction = finalAction;
						while( tempAction[j] )
						{
							if( tempAction[j] == '%' && tempAction[j + 1] == 'f' )
							{
								strcpy( cursorFinalAction, tempFileName );
								cursorFinalAction += strlen( tempFileName );
								j++;
							}
							else
							{
								*cursorFinalAction = tempAction[j];
								cursorFinalAction++;
							}
							j++;
						}
						strcpy( cursorFinalAction, " &" );
						chdir( windowPath );
						system( finalAction );
					}
					else
					{
						// The file has no predefined action
						tempFileStat = mainView2->GetFile( i )->GetFileStat();
						if( tempFileStat.st_mode & 0100 )
						{
							chdir( windowPath );
							strcat( tempFileName, " &" );
							system( tempFileName );
						}
					}
				}
			}
			break;
		}
		case ID_SELECTION_CHANGE:
		{
			int firstFileNumber = mainView2->GetFirstSelected();
			char tempInfo[1024];
			char numBuffer[33];
			struct::stat tempFileStat;
			long long numberOfSelection, sizeOfSelection;

			if( firstFileNumber == mainView2->GetLastSelected() )
			{
				if( firstFileNumber != -1 )
				{
					// One item selected
					tempFileStat = mainView2->GetFile( firstFileNumber )->GetFileStat();
					if( tempFileStat.st_mode & 0100000 )
					{
						// Regular file selected
						strcpy( tempFileName, mainView2->GetFile( firstFileNumber )->GetName().c_str() );
						strcpy( tempInfo, "Type : " );

						if( ( tempFileStat.st_mode & 0100 ) && !strcmp( " ", ( mainConfig->mainMimeTable->getType( tempFileName ) )->action ) )
						{
							// Executable file selected
							strcpy( tempInfo, "Type : Executable file" );
						}
						else
						{
							// Non executable selected
							strcat( tempInfo, ( mainConfig->mainMimeTable->getType( tempFileName ) )->name );
						}
					}
					else
					{
						// Directory selected
						strcpy( tempInfo, "Type : Directory" );
					}
				}
				else
				{
					// No item selected
					strcpy( tempInfo, "" );
				}
				// printf("%o\n", tempFileStat.st_mode);
			}
			else
			{
				numberOfSelection = 0;
				sizeOfSelection = 0;
				// Multiple items selected
				for( i = firstFileNumber; i <= mainView2->GetLastSelected(); i++ )
				{
					if( mainView2->IsSelected( i ) )
					{
						numberOfSelection++;
						tempFileStat = mainView2->GetFile( i )->GetFileStat();
						if( tempFileStat.st_mode & 0100000 )
							sizeOfSelection += tempFileStat.st_size;
					}
				}

				ltostr( numberOfSelection, numBuffer );
				strcpy( tempInfo, numBuffer );
				strcat( tempInfo, " items using " );

				ltostr( sizeOfSelection, numBuffer );
				strcat( tempInfo, numBuffer );
				strcat( tempInfo, " bytes" );
			}
			infoLabel->SetString( tempInfo );
			break;
		}
		case ID_LOCATION_BAR_INVOKED:
		{
	    	uint32 nEvents = 0;
	    	pcMessage->FindInt( "events", &nEvents );
	    	if ( nEvents & os::TextView::EI_ENTER_PRESSED )
	    	{
	    		const char* locationPath = locationBar->GetBuffer()[0].c_str();
				locationBar->Set( locationPath, true );
				SetTitle( locationPath );
				mainView2->SetPath( locationPath );
				mainView2->Clear();
				mainView2->ReRead();
				mainView2->MakeFocus();
			}
			break;
		}
		default:
		{
			os::Window::HandleMessage( pcMessage );
			break;
		}
	}
}

void folderWindow::DirectoryUp()
{
	int i = 0;

	while( windowPath[i] != 0 )
		i++;

	if( i > 1 )
	{
		i--;
		while( windowPath[i] != '/' )
			i--;
		if( i != 0 )
		{
			windowPath[i] = 0;
		}
		else
		{
			windowPath[1] = 0;
		}
	}
}