#include "mainwindow.h"
#include "commthread.h"
#include "messages.h"

MainWindow::MainWindow():os::Window( os::Rect( 0, 0, 750, 500 ), "main_wnd", "bsIRC" )
{
	// Create the vertical and horizonal layout root nodes
	os::LayoutView *pcView = new os::LayoutView( GetBounds(), "layout_view" );
	os::LayoutNode *m_pcRoot = new os::VLayoutNode( "Root" );
	os::TabView *m_pcSideTab = new os::TabView( os::Rect(), "SideTab" );
	os::LayoutNode *m_pcHLayoutNode = new os::HLayoutNode( "HLayoutNode", 1.000000 );
	m_pcHLayoutNode->SetBorders( os::Rect( 5.000000, 5.000000, 5.000000, 5.000000 ) );
	os::LayoutNode *m_pcSideNode = new os::VLayoutNode( "SideNode", 1.000000 );
	m_pcSideNode->SetBorders( os::Rect( 0.000000, 0.000000, 5.000000, 0.000000 ) );
	m_pcHLayoutNode->AddChild( m_pcSideNode );

	// Menus
	os::Menu *m_pcMenu = new os::Menu( os::Rect(), "Menu", os::ITEMS_IN_ROW );
	os::Menu* pcMenuApplicationMenu = new os::Menu( os::Rect(), "Application", os::ITEMS_IN_COLUMN );
	pcMenuApplicationMenu->AddItem( "Quit", new os::Message( os::M_QUIT_REQUESTED ) );
	pcMenuApplicationMenu->AddItem( new os::MenuSeparator() );
	pcMenuApplicationMenu->AddItem( "Help...", new os::Message( M_MENU_HELP ) );
	pcMenuApplicationMenu->AddItem( "Website...", new os::Message( M_MENU_WEB ) );
	pcMenuApplicationMenu->AddItem( new os::MenuSeparator() );
	pcMenuApplicationMenu->AddItem( "About...", new os::Message( os::M_ABOUT_REQUESTED ) );
	m_pcMenu->AddItem( pcMenuApplicationMenu );
	m_pcMenu->SetTargetForItems(this);
	m_pcRoot->AddChild( m_pcMenu, 1.000000 );
	m_pcRoot->AddChild( m_pcHLayoutNode );

	// Bookmarks
	os::LayoutView *m_pcBookmarksTab = new os::LayoutView( os::Rect(), "BookmarksTab" );
	os::LayoutNode *m_pcBookmarksLayout = new os::VLayoutNode( "BookmarksLayout" );
	m_pcSideTab->AppendTab( "Bookmarks", m_pcBookmarksTab );
	os::LayoutNode *m_pcBookmarksNode = new os::VLayoutNode( "BookmarksNode", 1.000000 );
	m_pcBookmarksNode->SetBorders( os::Rect( 3.000000, 0.000000, 3.000000, 3.000000 ) );
	m_pcBookmarksLayout->AddChild( m_pcBookmarksNode );
	os::FrameView *m_pcBookmarkFrame = new os::FrameView( os::Rect(), "BookmarkFrame", "Add Bookmarks" );
	os::LayoutNode *m_pcBookmarkFrameLayout = new os::VLayoutNode( "BookmarkFrameLayout" );
	m_pcBookmarkFrameLayout->SetBorders( os::Rect( 3.000000, 0.000000, 3.000000, 3.000000 ) );
	m_pcBookmarksNode->AddChild( m_pcBookmarkFrame, 1.000000 );
	m_pcTextBookmarkName = new os::TextView( os::Rect(), "TextBookmarkName", "" );
	m_pcBookmarkFrameLayout->AddChild( m_pcTextBookmarkName, 1.000000 );
	m_pcBookmarkFrameLayout->AddChild( new os::VLayoutSpacer( "BookmarkSpacer1", 3.000000, 3.000000, NULL, 1.000000 ) );
	m_pcBookmarkFrameLayout->AddChild(  new os::Button( os::Rect(), "ButtonBookmarkName", "Add Bookmark", new os::Message( M_BUTTON_ADDBOOKMARK ) ), 1.000000 );
	m_pcBookmarkFrame->SetRoot( m_pcBookmarkFrameLayout );
	m_pcBookmarksNode->AddChild( new os::VLayoutSpacer( "BookmarkSpacer2", 10.000000, 10.000000, NULL, 1.000000 ) );
	m_pcBookmarkList = new os::ListView( os::Rect(), "BookmarkList", os::ListView::F_NO_HEADER );
	m_pcBookmarkList->InsertColumn( "Name", 1 );
	m_pcBookmarksNode->AddChild( m_pcBookmarkList, 50.000000 );
	m_pcBookmarksNode->AddChild( new os::VLayoutSpacer( "BookmarkSpacer3", 10.000000, 10.000000, NULL, 1.000000 ) );
	os::LayoutNode *m_pcBookmarkButtonsNode = new os::HLayoutNode( "BookmarkButtonsNode", 1.000000 );
	m_pcBookmarkButtonsNode->SetBorders( os::Rect( 0.000000, 0.000000, 0.000000, 0.000000 ) );
	m_pcBookmarksNode->AddChild( m_pcBookmarkButtonsNode );
	//the remove image button
	os::File cButtonRemoveBookmarkFile( open_image_file( get_image_id() ) );
	os::Resources cButtonRemoveBookmarkResources( &cButtonRemoveBookmarkFile );
	os::ResStream* pcButtonRemoveBookmarkStream = cButtonRemoveBookmarkResources.GetResourceStream( "remove.png" );
	os::ImageButton *m_pcButtonRemoveBookmark = new os::ImageButton( os::Rect(), "ButtonRemoveBookmark", "", new os::Message( M_BUTTON_REMOVEBOOKMARK ), new os::BitmapImage( pcButtonRemoveBookmarkStream ), os::ImageButton::IB_TEXT_BOTTOM, true, true, true );
	delete( pcButtonRemoveBookmarkStream );
	m_pcBookmarkButtonsNode->AddChild( m_pcButtonRemoveBookmark, 1.000000 );
	m_pcBookmarkButtonsNode->AddChild( new os::HLayoutSpacer( "BookmarkSpacer4", 0.000000, 10.000000, NULL, 1.000000 ) );
	m_pcBookmarkButtonsNode->AddChild( new os::Button( os::Rect(), "ButtonBConnect", "Connect", new os::Message( M_BUTTON_BCONNECT ) ), 3.000000 );
	m_pcBookmarksTab->SetRoot( m_pcBookmarksLayout );

	// UserList
	os::LayoutView *m_pcUserListTab = new os::LayoutView( os::Rect(), "UserListTab" );
	os::LayoutNode *m_pcUserListLayout = new os::VLayoutNode( "UserListLayout" );
	m_pcSideTab->AppendTab(  "UserList", m_pcUserListTab );
	m_pcSideNode->AddChild( m_pcSideTab, 1.000000 );
	os::LayoutNode *m_pcUserListNode = new os::VLayoutNode( "UserList", 1.000000 );
	m_pcUserListNode->SetBorders( os::Rect( 0.000000, 0.000000, 0.000000, 0.000000 ) );
	m_pcUserListLayout->AddChild( m_pcUserListNode );
	m_pcUserListTab->SetRoot( m_pcUserListLayout );
	m_pcUserList = new os::ListView( os::Rect(), "UserList", os::ListView::F_NO_HEADER );
	m_pcUserList->InsertColumn( "Users", 1 );
	m_pcUserListNode->AddChild( m_pcUserList, 50.000000 );

	// Connect Settings
	os::LayoutNode *m_pcMainNode = new os::VLayoutNode( "MainNode", 50.000000 );
	m_pcMainNode->SetBorders( os::Rect( 0.000000, 0.000000, 0.000000, 0.000000 ) );
	m_pcHLayoutNode->AddChild( m_pcMainNode );
	os::LayoutNode *m_pcConnectNode = new os::HLayoutNode( "ConnectNode", 1.000000 );
	m_pcConnectNode->SetBorders( os::Rect( 0.000000, 0.000000, 0.000000, 5.000000 ) );
	m_pcMainNode->AddChild( m_pcConnectNode );
	os::TabView *m_pcConnectTab = new os::TabView( os::Rect(), "ConnectTab" );
	os::LayoutView *m_pcUserSettingsTab = new os::LayoutView( os::Rect(), "UserSettingsTab" );
	os::LayoutNode *m_pcUserSettingsLayout = new os::VLayoutNode( "UserSettingsLayout" );
	m_pcConnectTab->AppendTab(  "UserSettings", m_pcUserSettingsTab );
	os::LayoutView *m_pcServerSettingsTab = new os::LayoutView( os::Rect(), "ServerSettingsTab" );
	os::LayoutNode *m_pcServerSettingsLayout = new os::VLayoutNode( "ServerSettingsLayout" );
	m_pcConnectTab->AppendTab(  "ServerSettings", m_pcServerSettingsTab );
	m_pcConnectNode->AddChild( m_pcConnectTab, 25.000000 );
	os::LayoutNode *m_pcUserSettings = new os::HLayoutNode( "UserSettings", 1.000000 );
	m_pcUserSettings->SetBorders( os::Rect( 0.000000, 0.000000, 0.000000, 3.000000 ) );
	m_pcUserSettingsLayout->AddChild( m_pcUserSettings );
	//nickname
	os::LayoutNode *m_pcUserNameNode = new os::VLayoutNode( "UserNameNode", 2.000000 );
	m_pcUserNameNode->SetBorders( os::Rect( 5.000000, 0.000000, 15.000000, 0.000000 ) );
	m_pcUserSettings->AddChild( m_pcUserNameNode );
	m_pcUserNameNode->AddChild( new os::StringView( os::Rect(), "StringUserName", "Nickname:" ), 1.000000 );
	m_pcUserNameNode->AddChild( new os::VLayoutSpacer( "UserNameSpacer", 5.000000, 5.000000, NULL, 1.000000 ) );
	m_pcTextUserName = new os::TextView( os::Rect(), "TextUserName", "" );
	m_pcUserNameNode->AddChild( m_pcTextUserName, 1.000000 );
	//password
	os::LayoutNode *m_pcUserPasswordNode = new os::VLayoutNode( "UserPasswordNode", 1.000000 );
	m_pcUserPasswordNode->SetBorders( os::Rect( 15.000000, 0.000000, 15.000000, 0.000000 ) );
	m_pcUserSettings->AddChild( m_pcUserPasswordNode );
	m_pcUserPasswordNode->AddChild( new os::StringView( os::Rect(), "StringUserPassword", "Password:" ), 1.000000 );
	m_pcUserPasswordNode->AddChild( new os::VLayoutSpacer( "UserPasswordSpacer", 5.000000, 5.000000, NULL, 1.000000 ) );
	m_pcTextUserPassword = new os::TextView( os::Rect(), "TextUserPassword", "" );
	m_pcTextUserPassword->SetPasswordMode( true );
	m_pcUserPasswordNode->AddChild( m_pcTextUserPassword, 1.000000 );
	//realname
	os::LayoutNode *m_pcUserRealNameNode = new os::VLayoutNode( "UserRealNameNode", 2.000000 );
	m_pcUserRealNameNode->SetBorders( os::Rect( 15.000000, 0.000000, 5.000000, 0.000000 ) );
	m_pcUserSettings->AddChild( m_pcUserRealNameNode );
	m_pcUserRealNameNode->AddChild( new os::StringView( os::Rect(), "StringUserRealName", "Real Name:" ), 1.000000 );
	m_pcUserRealNameNode->AddChild( new os::VLayoutSpacer( "UserRealNameSpacer", 5.000000, 5.000000, NULL, 1.000000 ) );
	m_pcTextUserRealName = new os::TextView( os::Rect(), "TextUserRealName", "" );
	m_pcUserRealNameNode->AddChild( m_pcTextUserRealName, 1.000000 );
	//server
	os::LayoutNode *m_pcServerSettings = new os::HLayoutNode( "ServerSettings", 1.000000 );
	m_pcServerSettings->SetBorders( os::Rect( 0.000000, 0.000000, 0.000000, 3.000000 ) );
	m_pcServerSettingsLayout->AddChild( m_pcServerSettings );
	os::LayoutNode *m_pcServerNameNode = new os::VLayoutNode( "ServerNameNode", 2.000000 );
	m_pcServerNameNode->SetBorders( os::Rect( 5.000000, 0.000000, 15.000000, 0.000000 ) );
	m_pcServerSettings->AddChild( m_pcServerNameNode );
	m_pcServerNameNode->AddChild( new os::StringView( os::Rect(), "StringServerName", "Server:" ), 1.000000 );
	m_pcServerNameNode->AddChild( new os::VLayoutSpacer( "ServerNameSpacer", 5.000000, 5.000000, NULL, 1.000000 ) );
	m_pcTextServerName = new os::TextView( os::Rect(), "TextServerName", "" );
	m_pcServerNameNode->AddChild( m_pcTextServerName, 1.000000 );
	//port
	os::LayoutNode *m_pcServerPortNode = new os::VLayoutNode( "ServerPortNode", 1.000000 );
	m_pcServerPortNode->SetBorders( os::Rect( 15.000000, 0.000000, 15.000000, 0.000000 ) );
	m_pcServerSettings->AddChild( m_pcServerPortNode );
	m_pcServerPortNode->AddChild( new os::StringView( os::Rect(), "StringServerPort", "Port:" ), 1.000000 );
	m_pcServerPortNode->AddChild( new os::VLayoutSpacer( "ServerPortSpacer", 5.000000, 5.000000, NULL, 1.000000 ) );
	m_pcTextServerPort = new os::TextView( os::Rect(), "TextServerPort", "6667" );
	m_pcServerPortNode->AddChild( m_pcTextServerPort, 1.000000 );
	//channel
	os::LayoutNode *m_pcServerChannelNode = new os::VLayoutNode( "ServerChannelNode", 2.000000 );
	m_pcServerChannelNode->SetBorders( os::Rect( 15.000000, 0.000000, 5.000000, 0.000000 ) );
	m_pcServerSettings->AddChild( m_pcServerChannelNode );
	m_pcServerChannelNode->AddChild( new os::StringView( os::Rect(), "StringServerChannel", "Channel:" ), 1.000000 );
	m_pcServerChannelNode->AddChild( new os::VLayoutSpacer( "ServerChannelSpacer", 5.000000, 5.000000, NULL, 1.000000 ) );
	m_pcTextServerChannel = new os::TextView( os::Rect(), "TextServerChannel", "" );
	m_pcServerChannelNode->AddChild( m_pcTextServerChannel, 1.000000 );
	m_pcUserSettingsTab->SetRoot( m_pcUserSettingsLayout );
	m_pcServerSettingsTab->SetRoot( m_pcServerSettingsLayout );

	// Connect Buttons
	os::LayoutNode *m_pcConnectButtonsNode = new os::VLayoutNode( "ConnectButtonsNode", 1.000000 );
	m_pcConnectButtonsNode->SetBorders( os::Rect( 5.000000, 0.000000, 0.000000, 0.000000 ) );
	m_pcConnectNode->AddChild( m_pcConnectButtonsNode );
	m_pcConnectButtonsNode->AddChild( new os::VLayoutSpacer( "ConnectSpacer1", 12.000000, 12.000000, NULL, 1.000000 ) );
	m_pcConnectButtonsNode->AddChild( new os::Button( os::Rect(), "ButtonConnect", "Connect", new os::Message( M_BUTTON_CCONNECT ) ), 1.000000 );
	m_pcConnectButtonsNode->AddChild( new os::VLayoutSpacer( "ConnectSpacer2", 5.000000, 5.000000, NULL, 1.000000 ) );
	m_pcConnectButtonsNode->AddChild( new os::Button( os::Rect(), "ButtonDisconnect", "Disconnect", new os::Message( M_BUTTON_DISCONNECT ) ), 1.000000 );

	// Message Views
	//text view
	m_pcTextView = new os::TextView( os::Rect(), "TextView", "" );
	m_pcTextView->SetMultiLine( true );
	m_pcTextView->SetReadOnly( true );
	m_pcMainNode->AddChild( m_pcTextView, 35.000000 );
	//message view
	os::LayoutNode *m_pcMessageNode = new os::HLayoutNode( "MessageNode", 0.000000 );
	m_pcMessageNode->SetBorders( os::Rect( 0.000000, 5.000000, 0.000000, 0.000000 ) );
	m_pcMainNode->AddChild( m_pcMessageNode );
	m_pcMessageText = new os::TextView( os::Rect(), "MessageText", "" );
	m_pcMessageText->SetMultiLine( false );
	m_pcMessageNode->AddChild( m_pcMessageText, 25.000000 );
	m_pcMessageText->SetEventMask( os::TextView::EI_ENTER_PRESSED | os::TextView::EI_ESC_PRESSED );
	m_pcMessageText->SetMessage( new os::Message( MSG_TOLOOPER_NEW_MESSAGE ) );
	m_pcMessageText->SetTarget( this );

	// Add it all to this layout view
	pcView->SetRoot( m_pcRoot );
	AddChild( pcView );

	// Set tab order
	uint iTabOrder = 0;
	m_pcTextUserName->SetTabOrder( iTabOrder++ );
	m_pcTextUserPassword->SetTabOrder( iTabOrder++ );
	m_pcTextUserRealName->SetTabOrder( iTabOrder++ );
	m_pcTextServerName->SetTabOrder( iTabOrder++ );
	m_pcTextServerPort->SetTabOrder( iTabOrder++ );
	m_pcTextServerChannel->SetTabOrder( iTabOrder++ );

	SetBookmarkPath();

	/* create a protected commthread instance */
	CommThread *m_pCommThread;
	m_pCommThread = new CommThread( this );
	if( m_pCommThread == NULL )
	{
		os::Alert *sAlert = new os::Alert( "Error", os::String().Format( "Failed to create a commthread instance\nReason: %s", strerror( errno ) ), 0, "OK", NULL );
		sAlert->Go();
		os::Application::GetInstance()->PostMessage( os::M_QUIT );
	}
	m_CommThread = m_pCommThread;
	m_CommThread->SetState( CommThread::S_STOP );
}

void MainWindow::HandleMessage( os::Message * pcMessage )
{
	switch ( pcMessage->GetCode() )
	{
		case M_BUTTON_ADDBOOKMARK:
		{
			AddBookmarkToList();
			break;
		}

		case M_BUTTON_REMOVEBOOKMARK:
		{
			RemoveBookmarkFromList();
			break;
		}

		case M_BUTTON_BCONNECT:
		{
			SelectBookmarkFromList();
			break;
		}

		case M_BUTTON_CCONNECT:
		{
			stdName = m_pcTextUserName->GetBuffer()[0].const_str();
			stdPassword = m_pcTextUserPassword->GetBuffer()[0].const_str();
			stdRealName = m_pcTextUserRealName->GetBuffer()[0].const_str();
			stdServerName = m_pcTextServerName->GetBuffer()[0].const_str();
			stdServerPort = m_pcTextServerPort->GetBuffer()[0].const_str();
			stdServerChannel = m_pcTextServerChannel->GetBuffer()[0].const_str();
			if( stdRealName == "" )
				stdRealName = stdName;

			/* Connect - Login - Join */
			if( m_CommThread->GetState() == CommThread::S_START )
				break;

			if ( !stdServerName.empty() && !stdServerPort.empty() )
			{
				if( m_CommThread->Connect( stdServerName, stdServerPort ) )
				{
					// authenticate to host
					m_CommThread->Send( os::String().Format( "USER %s localhost %s :%s", stdName.c_str(), stdServerName.c_str(), stdRealName.c_str() ) );
					m_CommThread->Send( os::String().Format( "PASS %s", stdPassword.c_str() ) );
					m_CommThread->Send( os::String().Format( "NICK %s", stdName.c_str() ) );

					m_pcTextView->Clear();
					m_CommThread->Start();
					m_CommThread->SetState( CommThread::S_START );
				}
			}
			break;
		}

		case M_BUTTON_DISCONNECT:
		{
			if( m_CommThread->GetState() == CommThread::S_START )
			{
				m_CommThread->SetState( CommThread::S_STOP );
				m_CommThread->Send( "QUIT" );
				m_CommThread->Disconnect();
				m_CommThread->Reinitialize();
			}
			break;
		}

		case MSG_TOLOOPER_NEW_MESSAGE:
		{
	    	uint32 nEvents = 0;
	    	pcMessage->FindInt( "events", &nEvents );
	    	if ( nEvents & os::TextView::EI_ESC_PRESSED )
			{
				m_pcMessageText->Clear();
				m_pcMessageText->MakeFocus();
	    	}
	    	else if ( nEvents & os::TextView::EI_ENTER_PRESSED )
			{
				if( m_CommThread->GetState() == CommThread::S_START )
					m_CommThread->Send( m_pcMessageText->GetBuffer()[0].const_str() );
				m_pcMessageText->Clear();
				m_pcMessageText->MakeFocus();
			}
			break;
		}

		case M_MENU_HELP:
		{
			if( fork() == EOK )
			{
				set_thread_priority( -1, 0 );
				execlp( "/Applications/ABrowse/ABrowse", "/Applications/ABrowse/ABrowse", "http://www.syllable-software.info/index.php?id=bsIRC", NULL );
			}
			break;
		}

		case M_MENU_WEB:
		{
			if( fork() == EOK )
			{
				set_thread_priority( -1, 0 );
				execlp( "/Applications/ABrowse/ABrowse", "/Applications/ABrowse/ABrowse", "http://www.syllable-software.info/index.php?id=bsIRC", NULL );
			}
			break;
		}

		case os::M_ABOUT_REQUESTED:
		{
			AboutRequested();
			break;
		}

		case MSG_FROMLOOPER_NEW_MESSAGE:
		{
			const char *pzName;
			int nCount = 0;
			pcMessage->GetNameInfo( "name", NULL, &nCount );
			for( int i = 0; i < nCount; ++i )
			{
				if( pcMessage->FindString( "name", &pzName, i ) == EOK )
					AddStringToTextView( pzName );
			}
			break;
		}

		case os::M_QUIT_REQUESTED:
		{
			OkToQuit();
			break;
		}

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

void MainWindow::SetBookmarkPath()
{
	os::Path cBookmarkPath;
	os::FSNode cNode;
	os::FileReference cRef;

	cBookmarkPath.SetTo( getenv( "HOME" ) );
	cBookmarkPath.Append( "/Settings" );

	if( cNode.SetTo( cBookmarkPath.GetPath() ) != EOK )
		mkdir( cBookmarkPath.GetPath().c_str(), S_IRWXU | S_IRWXG | S_IRWXO );

	cNode.Unset();
	cBookmarkPath.Append( "/bsIRC" );
	if( cNode.SetTo( cBookmarkPath.GetPath() ) != EOK )
		mkdir( cBookmarkPath.GetPath().c_str(), S_IRWXU | S_IRWXG | S_IRWXO );

	if( cRef.SetTo( cBookmarkPath ) == EOK )
	{
		m_pcDirectory = new os::Directory( cBookmarkPath );
		LoadBookmarkList( m_pcDirectory );
	}
}

void MainWindow::LoadBookmarkList( os::Directory *pcDirectory )
{
	/* Open up directory and check it actually contains something */
	if( pcDirectory )
	{
		/* Clear listview */
		m_pcBookmarkList->Clear();

		/* Loop through directory and add each entry to the list */
		os::String cEntry;
		while( pcDirectory->GetNextEntry( &cEntry ) )
		{
			/* If special directory (i.e. dot(.) and dotdot(..) then ignore */
			if( cEntry == "." || cEntry == ".." )
			{
				continue;
			}

			/* Its valid, add to the listview */
			os::ListViewStringRow * pcRow = new os::ListViewStringRow();
			pcRow->AppendString( cEntry );
			m_pcBookmarkList->InsertRow( pcRow );
		}
	}
}

void MainWindow::AddBookmarkToList()
{
	os::Variant cVar( m_pcTextBookmarkName->GetValue().AsString() );
	os::String cBookmarkName = cVar.AsString();

	if( !cBookmarkName.empty() )
	{
		os::String zPath;
		if( m_pcDirectory->GetPath( &zPath ) == -1 )
			return;

		try
		{
			zPath += os::String ( "/" ) + cBookmarkName;
			os::File cFile( zPath, O_RDWR | O_CREAT );

			os::Settings * pcSettings = new os::Settings( new os::File( cFile ) );
			pcSettings->SetString( "Name", m_pcTextUserName->GetValue().AsString() );
			pcSettings->SetString( "Password", m_pcTextUserPassword->GetValue().AsString() );
			pcSettings->SetString( "RealName", m_pcTextUserRealName->GetValue().AsString() );
			pcSettings->SetString( "ServerName", m_pcTextServerName->GetValue().AsString() );
			pcSettings->SetString( "ServerPort", m_pcTextServerPort->GetValue().AsString() );
			pcSettings->SetString( "ServerChannel", m_pcTextBookmarkName->GetValue().AsString() );
			pcSettings->Save();
			delete( pcSettings );

			/* Make sure there's only one bookmark with the same name, on the list */
			bool bSameName = false;

			for( uint i = 0; i < m_pcBookmarkList->GetRowCount(); ++i )
			{
				os::ListViewStringRow *pcRow = static_cast < os::ListViewStringRow * >( m_pcBookmarkList->GetRow( i ) );
				if( cBookmarkName == pcRow->GetString( 0 ) )
					bSameName = true;
			}

			if( bSameName == false )
			{
				os::ListViewStringRow *row = new os::ListViewStringRow();
				row->AppendString( cBookmarkName );
				m_pcBookmarkList->InsertRow( row );
			}
		}
		catch( std::exception &e )
		{
			std::cerr << zPath.str() << ": " << e.what() << std::endl;
		}
	}
}

void MainWindow::RemoveBookmarkFromList()
{
	int nSelected = m_pcBookmarkList->GetLastSelected();
	os::ListViewStringRow *pcRow = static_cast < os::ListViewStringRow * >( m_pcBookmarkList->GetRow( nSelected ) );
	if( pcRow )
	{
		os::String cBookmarkPath;
		if( m_pcDirectory->GetPath( &cBookmarkPath ) == -1 )
			return;
		os::String cBookmarkName = pcRow->GetString( 0 );

		if( m_pcBookmarkList->GetRowCount() > 0 && nSelected != -1 )
		{
			m_pcBookmarkList->RemoveRow( nSelected );

			os::FileReference cRef( cBookmarkPath + "/" + cBookmarkName );
			cRef.Delete();

			m_pcTextUserName->Clear();
			m_pcTextUserPassword->Clear();
			m_pcTextUserRealName->Clear();
			m_pcTextServerName->Clear();
			m_pcTextServerPort->Clear();
			m_pcTextServerChannel->Clear();
			m_pcTextBookmarkName->Clear();
		}
	}
}

void MainWindow::SelectBookmarkFromList()
{
	int nSelected = m_pcBookmarkList->GetLastSelected();
	if( nSelected == -1 )
		return;

	os::ListViewStringRow *pcRow = static_cast < os::ListViewStringRow * >( m_pcBookmarkList->GetRow( nSelected ) );
	if( pcRow )
	{
		os::String cBookmarkName = pcRow->GetString( 0 );

		if( !cBookmarkName.empty() )
		{
			os::String cBookmarkPath;
			if( m_pcDirectory->GetPath( &cBookmarkPath ) == -1 )
				return;
			os::String zPath( cBookmarkPath + "/" + cBookmarkName );

			try
			{
				/* Load settings */
				os::Settings* pcSettings = new os::Settings( new os::File( zPath ) );
				if( pcSettings->Load() == EOK )
				{
					m_pcTextUserName->Set( pcSettings->GetString( "Name" ).c_str() );
					m_pcTextUserPassword->Set( pcSettings->GetString( "Password" ).c_str() );
					m_pcTextUserRealName->Set( pcSettings->GetString( "RealName" ).c_str() );
					m_pcTextServerName->Set( pcSettings->GetString( "ServerName" ).c_str() );
					m_pcTextServerPort->Set( pcSettings->GetString( "ServerPort" ).c_str() );
					m_pcTextServerChannel->Set( pcSettings->GetString( "ServerChannel" ).c_str() );
					m_pcTextBookmarkName->Set( cBookmarkName.c_str() );
				}
				delete( pcSettings );
			}
			catch( ... )
			{
			}
		}
	}
}

void MainWindow::GetUsers( const os::String& bufstring )
{
	std::string data( bufstring );
	std::vector params;

	// Check whether there is any params
   	if (!data.empty())
   	{
   	 	if (data.substr(0, 1) == ":")
   	 	{
           	params.push_back(data.substr(1));
       	}
       	else
       	{
           	size_t pos1 = 0, pos2;
           	while ((pos2 = data.find(" ", pos1)) != std::string::npos)
           	{
               	params.push_back(data.substr(pos1, pos2 - pos1));
               	pos1 = pos2 + 1;
               	if (data.substr(pos1, 1) == ":")
               	{
                   	params.push_back(data.substr(pos1 + 1));
                   	break;
               	}
           	}
           	if (params.empty())
               	params.push_back(data);
       	}

		for ( std::vector::iterator it = params.begin(); it < params.end(); it++ )	
		{
			os::ListViewStringRow * pcRow = new os::ListViewStringRow();
			pcRow->AppendString( (*it) );
			m_pcBookmarkList->InsertRow( pcRow );
		}
	}
}

void MainWindow::AddStringToTextView( const char* pzName ) const
{
	os::String cName;
	os::DateTime pcTime = os::DateTime::Now();

	if( pcTime.GetHour() < 10 && pcTime.GetMin() > 9 )
		cName.Format( "[0%d:%d] %s", pcTime.GetHour(), pcTime.GetMin(), pzName );
	else if( pcTime.GetHour() > 9 && pcTime.GetMin() < 10 )
		cName.Format( "[%d:0%d] %s", pcTime.GetHour(), pcTime.GetMin(), pzName );
	else if( pcTime.GetHour() < 10 && pcTime.GetMin() < 10 )
		cName.Format( "[0%d:0%d] %s", pcTime.GetHour(), pcTime.GetMin(), pzName );
	else
		cName.Format( "[%d:%d] %s", pcTime.GetHour(), pcTime.GetMin(), pzName );

	/* add new text to the end of the text view buffer */
	const os::TextView::buffer_type cBuffer = m_pcTextView->GetBuffer();
	const int posX = cBuffer[cBuffer.size()-1].size();
	const int posY = cBuffer.size()-1;
	const os::IPoint cPoint = os::IPoint( posX, posY );
	m_pcTextView->Insert( cPoint, cName.c_str() );
}

void MainWindow::AboutRequested()
{
	os::String cText = "bsIRC 0.32\n";
	cText += "Syllable Internet Relay Chat Client\n\n";
	cText += "bsIRC: Copyright © 2006 Flemming H. Sørensen (BurningShadow)\n";
	cText += "libnet: Copyright © 2004 Kristian van der Vliet (vanders)\n";
	cText += "commits: Copyright © 2023 David Kent (peekaye)\n\n";
	cText += "bsIRC is released under the GNU General Public License.\n";
	cText += "Please see the file COPYING, distributed with bsIRC,\n";
	cText += "or http://www.gnu.org for more information.";

	os::Alert *sAbout = new os::Alert( "About bsIRC...", cText, os::Alert::ALERT_INFO, 0x00, "Close", NULL );
	sAbout->CenterInWindow( this );
	sAbout->Go( new os::Invoker() );
}

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