// Font Preferences :: (C)opyright 2002 Daryl Dudey
// Inspiration from code by Kurt Skuaen
//
// This 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., 675 Mass Ave, Cambridge, MA 02139, USA.

#include <stdio.h>
#include <gui/image.h>
#include <util/application.h>
#include <util/message.h>
#include <util/resources.h>

#include "settingswindow.h"
#include "settings.h"
#include "messages.h"

SettingsWindow::SettingsWindow( const os::Rect & cFrame, AppSettings * pcSettings ):os::Window( cFrame, "SettingsWindow", "Settings", /*os::WND_NOT_RESIZABLE */ 0 )
{
	m_pcSettings = pcSettings;

	os::Rect cBounds = GetBounds();
	os::Rect cRect = os::Rect( 0, 0, 0, 0 );

	// Create the layouts/views
	pcLRoot = new os::LayoutView( cBounds, "L", NULL, os::CF_FOLLOW_ALL );
	pcVLRoot = new os::VLayoutNode( "VL" );
	pcVLRoot->SetBorders( os::Rect( 10, 5, 10, 5 ) );

	// Server
	pcHLServer = new os::HLayoutNode( "HLServer" );
	pcHLServer->AddChild( new os::HLayoutSpacer( "" ) );
	pcHLServer->AddChild( new os::StringView( cRect, "SVServer", "Server: " ) );
	pcHLServer->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );
	pcHLServer->AddChild( pcDDMServer = new os::DropdownMenu( cRect, "DDMServer" ) );
	pcDDMServer->SetShortcut( os::ShortcutKey( "O" ) );
	pcDDMServer->SetMinPreferredSize( 18 );
	pcHLServer->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );

	// Port
	pcHLPort = new os::HLayoutNode( "HLPort" );
	pcHLPort->AddChild( new os::HLayoutSpacer( "" ) );
	pcHLPort->AddChild( new os::StringView( cRect, "SVPort", "Port: " ) );
	pcHLPort->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );
	pcHLPort->AddChild( pcDDMPort = new os::DropdownMenu( cRect, "DDMPort" ) );
	pcDDMPort->SetShortcut( os::ShortcutKey( "B" ) );
	pcDDMPort->SetMinPreferredSize( 18 );
	pcHLPort->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );

	// Username
	pcHLUsername = new os::HLayoutNode( "HLUsername" );
	pcHLUsername->AddChild( new os::HLayoutSpacer( "" ) );
	pcHLUsername->AddChild( new os::StringView( cRect, "SVUsername", "Username: " ) );
	pcHLUsername->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );
	pcHLUsername->AddChild( pcDDMUsername = new os::DropdownMenu( cRect, "DDMUsername" ) );
	pcDDMUsername->SetShortcut( os::ShortcutKey( "F" ) );
	pcDDMUsername->SetMinPreferredSize( 18 );
	pcHLUsername->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );

	// Password
	pcHLPassword = new os::HLayoutNode( "HLPassword" );
	pcHLPassword->AddChild( new os::HLayoutSpacer( "" ) );
	pcHLPassword->AddChild( new os::StringView( cRect, "SVPassword", "Password: " ) );
	pcHLPassword->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );
	pcHLPassword->AddChild( pcDDMPassword = new os::DropdownMenu( cRect, "DDMPassword" ) );
	pcDDMPassword->SetShortcut( os::ShortcutKey( "W" ) );
	pcDDMPassword->SetMinPreferredSize( 18 );
	pcHLPassword->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );

	// Realname
	pcHLRealname = new os::HLayoutNode( "HLRealname" );
	pcHLRealname->AddChild( new os::HLayoutSpacer( "" ) );
	pcHLRealname->AddChild( new os::StringView( cRect, "SVRealname", "Realname: " ) );
	pcHLRealname->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );
	pcHLRealname->AddChild( pcDDMRealname = new os::DropdownMenu( cRect, "DDMRealname" ) );
	pcDDMRealname->SetShortcut( os::ShortcutKey( "T" ) );
	pcDDMRealname->SetMinPreferredSize( 18 );
	pcHLRealname->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );

	// Nickname
	pcHLNickname = new os::HLayoutNode( "HLNickname" );
	pcHLNickname->AddChild( new os::HLayoutSpacer( "" ) );
	pcHLNickname->AddChild( new os::StringView( cRect, "SVTNickname", "Nickname: " ) );
	pcHLNickname->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );
	pcHLNickname->AddChild( pcDDMNickname = new os::DropdownMenu( cRect, "DDMNickname" ) );
	pcDDMNickname->SetShortcut( os::ShortcutKey( "T" ) );
	pcDDMNickname->SetMinPreferredSize( 18 );
	pcHLNickname->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );

	// Channel
	pcHLChannel = new os::HLayoutNode( "HLChannel" );
	pcHLChannel->AddChild( new os::HLayoutSpacer( "" ) );
	pcHLChannel->AddChild( new os::StringView( cRect, "SVChannel", "Channel: " ) );
	pcHLChannel->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );
	pcHLChannel->AddChild( pcDDMChannel = new os::DropdownMenu( cRect, "DDMChannel" ) );
	pcDDMChannel->SetShortcut( os::ShortcutKey( "T" ) );
	pcDDMChannel->SetMinPreferredSize( 18 );
	pcHLChannel->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );

	// Add types to types layout node
	pcVLTypes = new os::VLayoutNode( "VLTypes" );
	pcVLTypes->SetBorders( os::Rect( 5, 5, 5, 5 ) );
	pcVLTypes->AddChild( new os::VLayoutSpacer( "" ) );
	pcVLTypes->AddChild( pcHLServer );
	pcVLTypes->AddChild( new os::VLayoutSpacer( "", 5.0f, 5.0f ) );
	pcVLTypes->AddChild( pcHLPort );
	pcVLTypes->AddChild( new os::VLayoutSpacer( "", 5.0f, 5.0f ) );
	pcVLTypes->AddChild( pcHLUsername );
	pcVLTypes->AddChild( new os::VLayoutSpacer( "", 5.0f, 5.0f ) );
	pcVLTypes->AddChild( pcHLPassword );
	pcVLTypes->AddChild( new os::VLayoutSpacer( "", 5.0f, 5.0f ) );
	pcVLTypes->AddChild( pcHLRealname );
	pcVLTypes->AddChild( new os::VLayoutSpacer( "", 5.0f, 5.0f ) );
	pcVLTypes->AddChild( pcHLNickname );
	pcVLTypes->AddChild( new os::VLayoutSpacer( "", 5.0f, 5.0f ) );
	pcVLTypes->AddChild( pcHLChannel );
	pcVLTypes->AddChild( new os::VLayoutSpacer( "", 5.0f, 5.0f ) );
	pcFVTypes = new os::FrameView( cBounds, "FVTypes", "Server Settings", os::CF_FOLLOW_ALL );
	pcFVTypes->SetRoot( pcVLTypes );

	// Set widths the same
	pcVLTypes->SameWidth( "SVServer", "SVPort", "SVUsername", "SVPassword", "SVRealname", "SVNickname", "SVChannel", NULL );
	pcVLTypes->SameWidth( "DDMServer", "DDMPort", "DDMUsername", "DDMPassword", "DDMRealname", "DDMNickname", "DDMChannel", NULL );

	// Add types to main node
	pcVLRoot->AddChild( pcFVTypes );
	pcVLRoot->AddChild( new os::VLayoutSpacer( "", 5.0f, 5.0f ) );

	// Add buttons
	pcHLButtons = new os::HLayoutNode( "HLButtons" );
	pcVLRoot->AddChild( new os::VLayoutSpacer( "", 10.f, 10.0f ) );
	pcHLButtons->AddChild( new os::HLayoutSpacer( "" ) );
	pcHLButtons->AddChild( pcBApply = new os::Button( cRect, "BApply", "Apply", new os::Message( M_SW_APPLY ) ) );
	pcHLButtons->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );
	pcHLButtons->AddChild( pcBRevert = new os::Button( cRect, "BRevert", "Revert", new os::Message( M_SW_REVERT ) ) );
	pcHLButtons->AddChild( new os::HLayoutSpacer( "", 5.0f, 5.0f ) );
	pcHLButtons->AddChild( pcBDefault = new os::Button( cRect, "BDefault", "Default", new os::Message( M_SW_DEFAULT ) ) );
	pcHLButtons->SameWidth( "BApply", "BRevert", "BDefault", NULL );
	pcHLButtons->SameHeight( "BApply", "BRevert", "BDefault", NULL );
	pcVLRoot->AddChild( pcHLButtons );

	// Set root and add to window
	pcLRoot->SetRoot( pcVLRoot );
	AddChild( pcLRoot );

	// Set Default button and initial focus
	this->SetDefaultButton( pcBApply );
	pcDDMServer->MakeFocus();

	// Set tab order
	int iTabOrder = 0;

	pcDDMServer->SetTabOrder( iTabOrder++ );
	pcDDMPort->SetTabOrder( iTabOrder++ );
	pcDDMUsername->SetTabOrder( iTabOrder++ );
	pcDDMPassword->SetTabOrder( iTabOrder++ );
	pcDDMRealname->SetTabOrder( iTabOrder++ );
	pcDDMNickname->SetTabOrder( iTabOrder++ );
	pcDDMChannel->SetTabOrder( iTabOrder++ );
	pcBApply->SetTabOrder( iTabOrder++ );
	pcBRevert->SetTabOrder( iTabOrder++ );
	pcBDefault->SetTabOrder( iTabOrder++ );

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

	// Show data
	GetCurrentValues();
	ResizeTo( pcVLRoot->GetPreferredSize( false ) );	//simple way of making sure the window is no bigger than it needs to be
}

void SettingsWindow::GetCurrentValues()
{
	os::String zHost, zPort, zUsername, zPassword, zRealname, zNickname, zChannel;

	m_pcSettings->LoadHistory( &zHost, &zPort, &zUsername, &zPassword, &zRealname, &zNickname, &zChannel );

	pcDDMServer->SetCurrentString( zHost );
	pcDDMPort->SetCurrentString( zPort );
	pcDDMUsername->SetCurrentString( zUsername );
	pcDDMPassword->SetCurrentString( zPassword );
	pcDDMRealname->SetCurrentString( zRealname );
	pcDDMNickname->SetCurrentString( zNickname );
	pcDDMChannel->SetCurrentString( zChannel );
}

SettingsWindow::~SettingsWindow()
{
}

void SettingsWindow::Apply()
{
	m_pcSettings->AddHistory( pcDDMServer->GetCurrentString(), pcDDMPort->GetCurrentString(), pcDDMUsername->GetCurrentString(), pcDDMPassword->GetCurrentString(), pcDDMRealname->GetCurrentString(), pcDDMNickname->GetCurrentString(), pcDDMChannel->GetCurrentString() );

	m_pcSettings->Save();
	OkToQuit();
}

void SettingsWindow::Revert()
{
	GetCurrentValues();
}

void SettingsWindow::Default()
{
	// Set sane system defaults
	pcDDMServer->SetCurrentString( "irc.libera.chat" );
	pcDDMPort->SetCurrentString( "6667" );
	pcDDMUsername->SetCurrentString( "sIRC_" );
	pcDDMPassword->SetCurrentString( "password" );
	pcDDMRealname->SetCurrentString( "Syllable User" );
	pcDDMNickname->SetCurrentString( "sIRC_" );
	pcDDMChannel->SetCurrentString( "#syllable" );
}

void SettingsWindow::HandleMessage( os::Message * pcMessage )
{
	int iMessage = pcMessage->GetCode();

	// Get message code and act on it
	switch ( iMessage )
	{

	case M_SW_APPLY:
		Apply();
		break;

	case M_SW_REVERT:
		Revert();
		break;

	case M_SW_DEFAULT:
		Default();
		break;

	default:
		os::Window::HandleMessage( pcMessage );
		break;
	}

}

bool SettingsWindow::OkToQuit()
{
	this->Close();
	return false;
}