#include "Frame.h"
#include <wx/xrc/xmlres.h>
#include "wx/colordlg.h"
#include "enjTelnetPanel.h"
#include "wx/fileconf.h"
#include "wx/wfstream.h"
#include <wx/fontmap.h>
#include "tinyxml.h"

#include "wx/image.h"
#include "wx/imagpng.h"
#include "wx/wxhtml.h"
#include "wx/statline.h"



//#ifndef __WXDEBUG__
//#undef USE_LOG
//#endif


#define MENU_EDIT_DELETE_ALL				10000
#define MENU_EDIT_ADD_PAGE					10001
#define MENU_EDIT_DELETE_PAGE				10002
#define MENU_EDIT_SET_SELECTION				10003
#define MENU_EDIT_ADVANCE_SELECTION_FWD		10004
#define MENU_EDIT_ADVANCE_SELECTION_BACK	10005
#define MENU_SET_ALL_TABS_SHAPE_ANGLE		10006
#define MENU_SHOW_IMAGES					10007
#define MENU_USE_VC71_STYLE					10008
#define MENU_USE_DEFULT_STYLE				10009
#define MENU_USE_FANCY_STYLE				10010
#define MENU_SELECT_GRADIENT_COLOR_FROM		10011
#define MENU_SELECT_GRADIENT_COLOR_TO		10012
#define MENU_SELECT_GRADIENT_COLOR_BORDER	10013
#define MENU_SET_PAGE_IMAGE_INDEX			10014
#define MENU_HIDE_X							10015
#define MENU_HIDE_NAV_BUTTONS				10016
#define MENU_USE_MOUSE_MIDDLE_BTN			10017
#define MENU_DRAW_BORDER					10018
#define MENU_USE_BOTTOM_TABS				10019
#define MENU_ENABLE_TAB						10020
#define MENU_DISABLE_TAB					10021
#define MENU_ENABLE_DRAG_N_DROP				10022
#define ID_TXT_ADDRESS						10023
#define MENU_ABOUT							10024
#define MENU_OPENSERVER						10025
#define MENU_TELNET_RECONNECT				10026
#define MENU_TELNET_DUPLICATE				10027
#define MENU_CONFIG_FONT					10028
#define MENU_TELNET_SPLIT_VER				10029
#define MENU_TELNET_SPLIT_HOR				10030
#define MENU_TELNET_HIDE_SCROLLBAR			10031
#define MENU_TELNET_CLOSE					10032
#define MENU_TELNET_ENCODING_BIG5			10033
#define MENU_TELNET_ENCODING_GB				10034
#define MENU_TELNET_ENCODING_DEFAULT		10035
#define MENU_MANUAL							10036
#define MENU_EDIT_SERVER_LIST				10037
#define MENU_VISIT_HOMEPAGE					10038
#define MENU_RENEW_SERVER_LIST				10039
#define MENU_SHOW_FULL						10040
#define MENU_SAVE_CONFIG_INFO				10041
#define MENU_RESET_DEFAULT_CONFIG			10042
#define MENU_CHANGE_BUFFER_SIZE				10043
#define MENU_RENAME_TAB_PAGE				10044
#define MENU_CONFIG_BACK					10045
#define MENU_SERVERSTART				    10050

BEGIN_EVENT_TABLE(Frame, wxFrame)
EVT_MENU_RANGE(MENU_HIDE_X, MENU_USE_BOTTOM_TABS, Frame::OnStyle)
EVT_MENU(wxID_EXIT, Frame::OnQuit)
EVT_MENU(MENU_EDIT_DELETE_ALL, Frame::OnDeleteAll)
EVT_MENU(MENU_EDIT_ADD_PAGE, Frame::OnAddPage)
EVT_MENU(MENU_EDIT_DELETE_PAGE, Frame::OnDeletePage)
EVT_MENU(MENU_EDIT_SET_SELECTION, Frame::OnSetSelection)
EVT_MENU(MENU_EDIT_ADVANCE_SELECTION_FWD, Frame::OnAdvanceSelectionFwd)
EVT_MENU(MENU_EDIT_ADVANCE_SELECTION_BACK, Frame::OnAdvanceSelectionBack)
EVT_MENU(MENU_SET_ALL_TABS_SHAPE_ANGLE, Frame::OnSetAllPagesShapeAngle)
EVT_MENU(MENU_SHOW_IMAGES, Frame::OnShowImages)
EVT_MENU_RANGE(MENU_SELECT_GRADIENT_COLOR_FROM, MENU_SELECT_GRADIENT_COLOR_BORDER, Frame::OnSelectColor)
EVT_MENU(MENU_USE_VC71_STYLE, Frame::OnVC71Style)
EVT_MENU(MENU_USE_DEFULT_STYLE, Frame::OnDefaultStyle)
EVT_MENU(MENU_USE_FANCY_STYLE, Frame::OnFancyStyle)
EVT_MENU(MENU_SET_PAGE_IMAGE_INDEX, Frame::OnSetPageImageIndex)
EVT_MENU(MENU_ENABLE_TAB, Frame::OnEnableTab)
EVT_MENU(MENU_DISABLE_TAB, Frame::OnDisableTab)
EVT_MENU(MENU_ENABLE_DRAG_N_DROP, Frame::OnEnableDrag)
EVT_MENU(MENU_ABOUT,    Frame::OnAbout)
EVT_MENU(MENU_MANUAL,    Frame::OnManual)
EVT_MENU(MENU_TELNET_RECONNECT, Frame::OnReconnectSession)
EVT_MENU(MENU_TELNET_DUPLICATE, Frame::OnDupSession)
EVT_MENU(MENU_TELNET_CLOSE, Frame::OnCloseSession)
EVT_MENU(MENU_CONFIG_FONT, Frame::OnChangeFont)
EVT_MENU(MENU_TELNET_SPLIT_VER, Frame::OnSplitVert)
EVT_MENU(MENU_TELNET_SPLIT_HOR, Frame::OnSplitHor)
EVT_MENU(MENU_TELNET_HIDE_SCROLLBAR, Frame::OnHideScrollBar)
EVT_MENU(MENU_EDIT_SERVER_LIST,Frame::OnEditServerList)
EVT_MENU(MENU_RENEW_SERVER_LIST,Frame::OnRenewServerList)
EVT_MENU(MENU_VISIT_HOMEPAGE,Frame::OnVisitHomePage)
EVT_MENU(MENU_SHOW_FULL,Frame::OnFullScreen)
EVT_MENU(MENU_SAVE_CONFIG_INFO,Frame::OnSaveConfig)
EVT_MENU(MENU_RESET_DEFAULT_CONFIG,Frame::ResetDefaultConfig)
EVT_MENU(MENU_CHANGE_BUFFER_SIZE,Frame::OnChangeBufferSize)
EVT_MENU(MENU_RENAME_TAB_PAGE,Frame::OnRenameTabPage)
EVT_MENU(MENU_CONFIG_BACK,Frame::OnChangeBackground)
EVT_MENU(wxID_ANY, Frame::OnOpenServer)


EVT_FLATNOTEBOOK_PAGE_CHANGING(-1, Frame::OnPageChanging)
EVT_FLATNOTEBOOK_PAGE_CHANGED(-1, Frame::OnPageChanged)
EVT_FLATNOTEBOOK_PAGE_CLOSING(-1, Frame::OnPageClosing)
EVT_KEY_DOWN(Frame::OnKeyDown)

EVT_TEXT_ENTER(ID_TXT_ADDRESS, Frame::OnAddressTextEnter)
		
END_EVENT_TABLE()

wxMenu *right_menu=NULL;
extern wxColour TerminalColors[2][8];

wxWindow *enjFindFocus()
{
	wxWindow *fc = wxWindow::FindFocus();//should be a telnet panel
#ifdef __WXGTK__
	if (!g_focustelnet) return NULL;
	if (!fc ) fc=g_focustelnet;
#endif
	return fc;
}

MySplitterWindow* Frame::GetSplitedParentWin(wxWindow *cu,wxWindow **removed)
{
	wxWindow *pc = cu->GetParent();//should be a splitter win
	if (!pc->IsKindOf(CLASSINFO(wxSplitterWindow))) return NULL;
	MySplitterWindow * spwin = (MySplitterWindow *) pc;
	if ( spwin->IsSplit()) {
			*removed=cu;
			return spwin;
	}else{
			return GetSplitedParentWin(spwin,removed);
	}
}

void Frame::OnCloseSession(wxCommandEvent &event)
{
	wxWindow *fc = enjFindFocus();//should be a telnet panel
	wxWindow *sc = fc->GetParent();//should be a scroll telnet panel
	wxWindow *removed = NULL;
	MySplitterWindow *pa= GetSplitedParentWin(sc,&removed);
	if (!pa) return;
	pa->Unsplit(removed);
	delete removed;
	/*
	wxWindow *pc = sc->GetParent();//should be a splitter win
	if (!pc->IsKindOf(CLASSINFO(wxSplitterWindow))) return;
	MySplitterWindow * spwin = (MySplitterWindow *) pc;
	wxWindow *win1 = spwin->GetWindow1();
	wxWindow *win2 = spwin->GetWindow2();
	enjScrollTelnetPanel *ct;
	if ( win1 == sc ) {
		ct = (enjScrollTelnetPanel *)win1;
	}else if ( win2 == sc ){
		ct = (enjScrollTelnetPanel *)win2;
	}else {
		ct = NULL;
	}
	if (!ct) return;
	wxLogMessage("Unsplit");
	if ( spwin->IsSplit()) {
		spwin->Unsplit(ct);
		delete ct;
	}else{
		wxWindow *spp = spwin->GetParent();//parent of split win,also should be a split win
		if (!spp->IsKindOf(CLASSINFO(wxSplitterWindow))) return;
		MySplitterWindow *spp_r = (MySplitterWindow*)spp;
		wxWindow *spwin1 = spp->GetWindow1();
		wxWindow *spwin2 = spp->GetWindow2();
		MySplitterWindow *cp;
		if ( spwin1 == spwin ) {
			cp = (MySplitterWindow *)spwin1;
		}else if ( spwin2 == spwin ){
			cp = (MySplitterWindow *)spwin2;
		}else {
			cp = NULL;
		}
		if (!cp) return;
		spp_r->Unsplit(cp);
	}

	}
	*/
	
}

void Frame::OnSaveConfig( wxCommandEvent &WXUNUSED(event) )
{
	wxFileName fn(wxString(wxTheApp->argv[0]));
	wxString config_list(fn.GetPath() + "/config.ini");
    //wxFile file(config_list, wxFile::read);
	//if (wxFile::Exists(config_list)) {

	//}
   	 //if (file.IsOpened()) {
	//	file.Close();
	wxFileInputStream in(config_list);
	wxFileOutputStream out(config_list);
	wxFileConfig fc(in);
	//	isfull = fc.Read("/FullScreenMode",0);
	long isfull = 0; fc.Write("FullScreenMode",IsFullScreen());
	wxFont fnt = GetCurrentFont();
	wxString face_name ; fc.Write("TermFont",fnt.GetNativeFontInfoDesc());
	/*
	long fnt_family ; fc.Read("TermFont/FamilyName",&fnt_family,0);
	long fnt_style ; fc.Read("TermFont/Style",&fnt_style,0);
	long fnt_underlined ; fc.Read("TermFont/UnderLined",&fnt_underlined,0);
	long fnt_point_size ; fc.Read("TermFont/PointSize",&fnt_point_size,0);
	long fnt_weight ; fc.Read("TermFont/Weight",&fnt_weight,0);
	*/
	
	long term_buf_size ; fc.Write("TermBufferSize",500);
	wxColour bg = TerminalColors[0][0];
	fc.Write("TermBackgroundColour/Red", wxString::Format("%d",bg.Red()));
	fc.Write("TermBackgroundColour/Green", wxString::Format("%d",bg.Green()));
	fc.Write("TermBackgroundColour/Blue", wxString::Format("%d",bg.Blue()));
	fc.Save(out);

	 //}
}

void Frame::OnFullScreen( wxCommandEvent &WXUNUSED(event) )
{
//	HideStart(false);	
  if ( book->GetPageCount()){	
   book->HideTabs(IsFullScreen());
   //book->Hide();
   ShowFullScreen( !IsFullScreen(), wxFULLSCREEN_NOBORDER|wxFULLSCREEN_NOCAPTION|wxFULLSCREEN_NOSTATUSBAR|wxFULLSCREEN_NOTOOLBAR |wxFULLSCREEN_NOMENUBAR);
  }
   //::SetWindowPos((HWND) GetHandle(),HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE | SWP_FRAMECHANGED);
}
void Frame::OnChangeBackground(wxCommandEvent &event)
{
	wxColor newcolor = wxGetColourFromUser(this,TerminalColors[0][0]);
	if (newcolor.Ok) {
			TerminalColors[0][0]=newcolor;
			TerminalColors[0][7].Set(~newcolor.Red(),~newcolor.Green(),~newcolor.Blue());
			book->SetBackgroundColour(TerminalColors[0][0]);
			this->SetBackgroundColour(TerminalColors[0][0]);

	}
}

void Frame::OnChangeFont(wxCommandEvent &event)
{
	UserSetFont(this);
}

void Frame::OnHideScrollBar(wxCommandEvent &event)
{
	wxWindow *fc = enjFindFocus();//should be a telnet panel
	
	((enjTelnetPanel *)fc)->HideScrollBar();
}

#define SPLIT_HOR 0
#define SPLIT_VER 1

void SplitInternal(
	enjTelnetPanel *stel,
	MySplitterWindow *spwin,
	enjScrollTelnetPanel *ct,
	wxWindow *parent,
	int split_mode,
	int isnew
				)
{
	//enjTelnetPanel *stel = (enjTelnetPanel*)fc;
	SiteInfo si;
	if ( !isnew ) {
		si = stel->telnet->getSiteInfo();
	}else{
		//SiteInfo *si=new SiteInfo;
		si.Init(SOCK_SSH);
		PersonalRecordDialog dialog(&si,NULL, wxID_ANY, wxT("New Connection..."),wxDefaultPosition,wxDefaultSize,wxDEFAULT_DIALOG_STYLE );
		if (dialog.ShowModal() == wxID_CANCEL)
		{
			return;
		}else{//wxID_OK
			if ( si.ip == wxEmptyString ) {
				si = stel->telnet->getSiteInfo();
			}
		}
	}
	
	//host = book->GetPageText((book->GetSelection()));
	//NewTelnetPage(host);
	
	//prepare the new split win
	 if ( !spwin->IsSplit()) {
		enjScrollTelnetPanel *telpanel= new enjScrollTelnetPanel(spwin,parent);
		if ( split_mode == SPLIT_HOR ) {
			spwin->SplitHorizontally(ct,telpanel);	
		}else{
			spwin->SplitVertically(ct,telpanel);	
		}
		telpanel->NewConnection(&si);
		telpanel->SetFocus();
	 }else{
	   	MySplitterWindow* m_splitter = new MySplitterWindow(spwin);
	   	m_splitter->SetSashGravity(0.5);
		enjScrollTelnetPanel *telpanel= new enjScrollTelnetPanel(m_splitter,parent);
	 	//m_splitter->Initialize(telpanel);
        spwin->ReplaceWindow( ct, m_splitter);
		ct->Reparent(m_splitter);
		if ( split_mode == SPLIT_HOR ) {
			m_splitter->SplitHorizontally(ct,telpanel);
		}else{
			m_splitter->SplitVertically(ct,telpanel);
		}
		telpanel->NewConnection(&si);
		telpanel->SetFocus();
	 }
}

void Frame::OnSplitHor(wxCommandEvent &event)
{
	wxWindow *fc = enjFindFocus();//should be a telnet panel
	wxWindow *sc = fc->GetParent();//should be a scroll telnet panel
	wxWindow *pc = sc->GetParent();//should be a splitter win
	if (!pc->IsKindOf(CLASSINFO(wxSplitterWindow))) return;
	MySplitterWindow * spwin = (MySplitterWindow *) pc;
	wxWindow *win1 = spwin->GetWindow1();
	wxWindow *win2 = spwin->GetWindow2();
	enjScrollTelnetPanel *ct;
	if ( win1 == sc ) {
		ct = (enjScrollTelnetPanel *)win1;
	}else if ( win2 == sc ){
		ct = (enjScrollTelnetPanel *)win2;
	}else {
		ct = NULL;
	}
	if (!ct) return;
	wxLogMessage("split");

	SplitInternal((enjTelnetPanel *)fc,spwin,ct,this,SPLIT_HOR,1);

	/*
  	wxString host = wxGetTextFromUser(
 		   _("[protocol://]server[:port_num]\n"),
 		   _("Split Vert ..."),
 		   _(""));
	if ( host == wxEmptyString ) {
	 	host = book->GetPageText((book->GetSelection()));
	}
	*/

}

void Frame::OnSplitVert(wxCommandEvent &event)
{
	wxWindow *fc = enjFindFocus();//should be a telnet panel
	wxWindow *sc = fc->GetParent();//should be a scroll telnet panel
	wxWindow *pc = sc->GetParent();//should be a splitter win
	if (!pc->IsKindOf(CLASSINFO(wxSplitterWindow))) return;
	MySplitterWindow * spwin = (MySplitterWindow *) pc;
	wxWindow *win1 = spwin->GetWindow1();
	wxWindow *win2 = spwin->GetWindow2();
	enjScrollTelnetPanel *ct;
	if ( win1 == sc ) {
		ct = (enjScrollTelnetPanel *)win1;
	}else if ( win2 == sc ){
		ct = (enjScrollTelnetPanel *)win2;
	}else {
		ct = NULL;
	}
	if (!ct) return;
	wxLogMessage("split");
	SplitInternal((enjTelnetPanel *)fc,spwin,ct,this,SPLIT_VER,1);

/*
  	wxString host = wxGetTextFromUser(
 		   _("[protocol://]server[:port_num]\n"),
 		   _("Split Vert ..."),
 		   _(""));
	if ( host == wxEmptyString ) {
	 	host = book->GetPageText((book->GetSelection()));
	}
		   */

	/*	
	enjTelnetPanel *stel = (enjTelnetPanel*)fc;
	SiteInfo si = stel->telnet->getSiteInfo();
	
	//NewTelnetPage(host);
	//prepare the new split win
	 if ( !spwin->IsSplit()) {
		enjScrollTelnetPanel *telpanel= new enjScrollTelnetPanel(spwin,this);
		spwin->SplitVertically(ct,telpanel);	
		telpanel->NewConnection(&si);
		telpanel->SetFocus();
	 }else{
	   	MySplitterWindow* m_splitter = new MySplitterWindow(spwin);
	   	//m_splitter->SetSashGravity(1.0);
		enjScrollTelnetPanel *telpanel= new enjScrollTelnetPanel(m_splitter,this);
	 	//m_splitter->Initialize(telpanel);
        spwin->ReplaceWindow( ct, m_splitter);
		ct->Reparent(m_splitter);
		m_splitter->SplitVertically(ct,telpanel);
		telpanel->NewConnection(&si);
		telpanel->SetFocus();
	 }
	 */
}

void Frame::OnChangeBufferSize(wxCommandEvent &event)
{
	wxWindow *fc = enjFindFocus();//should be a telnet panel
	if ( !fc ) return;
	enjTelnetPanel *stel = (enjTelnetPanel*)fc;
 	wxString buffersize = wxGetTextFromUser(
 		   _("Please input new buffer size, minimum lines=500)"),
 		   _("New Buffer Size ..."),
 		   wxString::Format("%d",stel->telnet->GetBufferSize()));
	long new_buffer_size = stel->telnet->GetBufferSize();
	if (buffersize.ToLong(&new_buffer_size)) {
		if ( new_buffer_size < 500 ) return;
		if ( stel->telnet->GetSocket()->GetType() == SOCK_EXECMD ){
			stel->telnet->GetSocket()->GetEXEC()->AdjustBufferSize(new_buffer_size);
		}{
			stel->telnet->ResizeBufferSize(new_buffer_size);
		}
	}
}

void Frame::OnRenameTabPage(wxCommandEvent &event)
{
	int sel=book->GetSelection();
	wxString orig=book->GetPageText(sel);
 	wxString hostname = wxGetTextFromUser(
 		   _("Rename Tab"),
 		   _(""),
 		   orig);
	if (!hostname.IsEmpty()){
		book->SetPageText(sel,hostname);
	}
}

void Frame::OnDupSession(wxCommandEvent &event)
{
	//enjScrollTelnetPanel *stel = (enjScrollTelnetPanel*)(book->GetPage(book->GetSelection()));
	//wxString host = book->GetPageText((book->GetSelection()));
	//NewTelnetPage(host);
	
	wxWindow *fc = enjFindFocus();//should be a telnet panel
	if ( !fc ) return;
	enjTelnetPanel *stel = (enjTelnetPanel*)fc;
	SiteInfo si = stel->telnet->getSiteInfo();
	NewTelnetPage(&si);
//	book->DeletePage(book->GetSelection());
	
	//stel->Reconnect();
}

void Frame::OnReconnectSession(wxCommandEvent &event)
{
	//book->DeletePage(book->GetSelection());
	wxWindow *fc = enjFindFocus();//should be a telnet panel
	
	//enjScrollTelnetPanel *stel = (enjScrollTelnetPanel*)(book->GetPage(book->GetSelection()));
	if ( !fc ) return;
	enjTelnetPanel *stel = (enjTelnetPanel*)fc;
	stel->Reconnect();
}

void Frame::OnAddressTextEnter(wxCommandEvent& WXUNUSED(event))
{		NewTelnetPage( txtAddress->GetValue() );	}
		
Frame::Frame(wxWindow* parent, const wxChar *title):
m_bShowImages(true)
, m_bVCStyle(false)
{
	m_ImageList.push_back(wxXmlResource::Get()->LoadBitmap(wxT("book_red")));
	m_ImageList.push_back(wxXmlResource::Get()->LoadBitmap(wxT("book_green")));
	m_ImageList.push_back(wxXmlResource::Get()->LoadBitmap(wxT("book_blue")));
	Create(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(800, 600), wxDEFAULT_FRAME_STYLE | wxMAXIMIZE |wxNO_FULL_REPAINT_ON_RESIZE);
	SetTitle("MEConsole");
	SetBackgroundColour(TerminalColors[0][0]);
    //SetBackgroundColour(*wxBLACK);
	extern int g_argc;
	extern wxChar **g_argv;
	if ( g_argc > 1) {
		for ( int i=1;i<g_argc;i++){
			NewTelnetPage(wxString(g_argv[i]));
		}
	}	
	//Maximize();
}

Frame::~Frame(void)
{
	extern bool putty_inited;
//#ifdef DEVELOPMENT

	delete wxLog::SetActiveTarget(m_logTargetOld);
//#endif
    if (m_imageList)
    {
        delete m_imageList;
        m_imageList = (wxImageList *) NULL;
    }
	book->Hide();
}

void Frame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
    wxBoxSizer *topsizer;
    wxHtmlWindow *html;
	wxString about_msg("<html> <body bgcolor='#FFFFFF'> \
	<table cellspacing=3 cellpadding=4 width='100%'>\
  <tr> <td bgcolor='#101010'>\
    <center><font size=+2 color='#FFFFFF'><b><br>MEConsole 3.2 FullVersion<br></b></font></center>\
  </td> </tr>\
  <tr> <td bgcolor='#73A183'>\
  	PuTTY 0.58.1.2<br>\
	TuTTY 0.58.1.2<br>\
    <b><font size=+0>Copyright (C) 2006 Yegia Xu</font></b><p>\
	<br>\
    </td> </tr>\
</table> </body> </html>");
    wxDialog dlg(this, wxID_ANY, wxString(_("About")));

    topsizer = new wxBoxSizer(wxVERTICAL);

    html = new wxHtmlWindow(&dlg, wxID_ANY, wxDefaultPosition, wxSize(380, 160), wxHW_SCROLLBAR_NEVER);
    html -> SetBorders(0);

	html->AppendToPage(about_msg);
    //html -> LoadPage(wxT("about.htm"));
    html -> SetSize(html -> GetInternalRepresentation() -> GetWidth(),
                    html -> GetInternalRepresentation() -> GetHeight());

    topsizer -> Add(html, 1, wxALL, 10);

    topsizer -> Add(new wxStaticLine(&dlg, wxID_ANY), 0, wxEXPAND | wxLEFT | wxRIGHT, 10);

    wxButton *bu1 = new wxButton(&dlg, wxID_OK, _("OK"));
    bu1 -> SetDefault();

    topsizer -> Add(bu1, 0, wxALL | wxALIGN_RIGHT, 15);

    dlg.SetSizer(topsizer);
    topsizer -> Fit(&dlg);

    dlg.ShowModal();

  //wxMessageBox(_("MEConsole(c) 2006\nVersion: 3.1 Full\nAuthor: Yegia Xu\nProject Page: http://Sourceforge.net/projects/meconsole\n"), _("About"), wxOK | wxICON_INFORMATION, this);
}

void Frame::OnVisitHomePage(wxCommandEvent& WXUNUSED(event))
{
	::ShellExecute(NULL,NULL,"http://sf.net/projects/meconsole",NULL,NULL,SW_SHOWNORMAL);
}

void Frame::OnEditServerList(wxCommandEvent& WXUNUSED(event))
{
	wxFileName fn(wxString(wxTheApp->argv[0]));
	wxString serv_list(fn.GetPath() + "/servers.xml");
	wxFile file(serv_list, wxFile::write_append);
	file.Close();
	::ShellExecute(NULL,"edit",serv_list.c_str(),NULL,NULL,SW_SHOWNORMAL);
	//RenewServerList();
}

void Frame::OnRenewServerList(wxCommandEvent &event)
{
	RenewServerList();
}

void Frame::OnManual(wxCommandEvent& WXUNUSED(event))
{
	wxString help_msg("\n\
\n\
- Major features:\n\
  Support SSH/Telnet/Local Shell connection\n\
      [protocol://]host[:port]\n\
      shell://cmd\n\
      telnet://hostname:port\n\
      ssh://hostname:port\n\
  Multi tabs in one process life\n\
  Multi sessions in one tab\n\
  Customize server list\n\
  Support platform SunOS, HP, Linux , AIX\n\
\n\
- Hotkeys Usage:\n\
  Control + Tab:                   Iterate all tabs\n\
  Control + Up/Down/Left/Right:    Switch sub terms in one tab\n\
  Control + F1...F12:              Index one tab\n\
  Shift + Left/Right:              Switch tab\n\
  Shift + PageUp/PageDown :        Scroll half screen of one telnet\n\
  Alt + Enter:                     Enable/Disable fullscreen mode\n\
  F12:                             Show/Hide cmd window in shell connection mode\n\
\n\
- Mouse Usage:\n\
  In the term screen:\n\
    Left Double Click:    Select a word on the screen, and copy to clipboard\n\
    Right Click:          Copy words from clipboard to current caret position\n\
	Control + Right Click: Popup menu\n\
	Alt + Left Button:    Select a block of text\n\
  On the tab title:\n\
    Right Click:\n\
      Horizontal split: Horizontal split current screen\n\
      Vertical split:   Vertical split current screen\n\
      Close:            Close current session\n\
      Reconnect:        Reconnect current session\n\
      Close Tab:        Close current tab\n\
      Hide Scrollbar:   Hide ScrollBar of current session\n\
    Left Click:     Drag tab to your favor position.\n\
\n\
- Custom server list:\n\
  There is a file named \"servers.xml\", just put your favor servers into it,\n\
  at next run, you will find them on the menu \"Servers\".\n\
\n\
  Format:\n\
    <GroupName>\n\
      <name>protocol://hostname</name>\n\
      <name>telnet://hostname</name>\n\
    </GroupName>\n\
\n\
- Limitation:\n\
  Not support GUI for telnet/ssh sessions.\n\
  Only support English/Chinese text.\n\
  Only support telnet/ssh/shell connections.\n\
  Bugs will be found...\n");

  wxMessageBox(help_msg,
               _("Manual"),
               wxOK | wxICON_INFORMATION, this);
}

void Frame::OnOpenServer(wxCommandEvent &event )
{
    int id = event.GetId();
    wxMenuItem *item = GetMenuBar()->FindItem(id);
    if ( item && id >= MENU_SERVERSTART )
    {
			wxLogMessage("%s",item->GetLabel().c_str());
			NewTelnetPage( item->GetLabel() );
    }
	if ( item ) {
		//extern wxFontEncoding global_default_enc;
		switch(id){
			case MENU_TELNET_ENCODING_DEFAULT:
					global_encoding.current = global_encoding.def;
					UserChangeEncoding(global_encoding.current);
					break;
			case MENU_TELNET_ENCODING_BIG5:
					global_encoding.current = global_encoding.big5;
					UserChangeEncoding(global_encoding.current);
					break;
			case MENU_TELNET_ENCODING_GB:
					global_encoding.current = global_encoding.gb;
					UserChangeEncoding(global_encoding.current);
					break;
			default:
					break;
		}
	}
	event.Skip();
}

void Frame::RenewServerList()
{
	int pos = m_menuBar->FindMenu("Servers");
	if ( pos != wxNOT_FOUND ) {
		m_menuBar->Remove(pos);
	}
	m_editMenu = new wxMenu();
	wxMenuItem *item ;
	wxFileName fn(wxString(wxTheApp->argv[0]));
	wxString serv_list(fn.GetPath() + "/servers.xml");
	TiXmlDocument doc( serv_list );
	if ( !doc.LoadFile()) {
  			//wxMessageBox(wxString::Format("Can not find server list file:\n%s",serv_list.c_str()), _("Missing File"), wxOK | wxICON_INFORMATION, this);
		//printf("Can not find file %s\n",serv_list.c_str());
	}else{
		TiXmlNode *child =NULL;
		int i=0;
		while ( child = doc.IterateChildren(child) ){
			//wxLogMessage("%s",child->Value());
			TiXmlNode *sec_child = NULL;
	    	wxMenu* subMenu = new wxMenu;
			while ( sec_child = child->IterateChildren(sec_child)){
				//wxLogMessage("%s = %s",sec_child->Value(),sec_child->ToElement()->GetText());
				item = new wxMenuItem(subMenu, MENU_SERVERSTART+i, sec_child->ToElement()->GetText()
								, _(""), wxITEM_NORMAL);
				subMenu->Append(item);
				i++;
			}
			m_editMenu->Append(wxID_ANY,child->Value(),subMenu);
		}
		//item = new wxMenuItem(m_editMenu);//seperater;
	}
	m_editMenu->AppendSeparator();
	item = new wxMenuItem(m_editMenu,MENU_EDIT_SERVER_LIST,
	   	_("Edit List"),_("Edit Server List"), wxITEM_NORMAL);
	m_editMenu->Append(item);
	item = new wxMenuItem(m_editMenu,MENU_RENEW_SERVER_LIST,
	   	_("Refresh List"),_("Refresh Server List"), wxITEM_NORMAL);
	m_editMenu->Append(item);
	m_menuBar->Insert(1,m_editMenu, _("Servers"));
}

void Frame::ResetDefaultConfig(wxCommandEvent& WXUNUSED(event))
//void Frame::ResetDefaultConfig(wxCommandEvent )
{
 	extern void GlobalDefaultFont();
	GlobalDefaultFont();
	TerminalColors[0][0].Set(0,0,0);
	TerminalColors[0][7].Set(187,187,187);
}

void Frame::LoadConfig()
{
	wxFileName fn(wxString(wxTheApp->argv[0]));
	wxString config_list(fn.GetPath() + "/config.ini");
	wxFileInputStream in(config_list);
	wxFileConfig fc(in);
	long isfull = 0; fc.Read("FullScreenMode",&isfull,0);
	wxString fnt_name;
   	if (fc.Read("TermFont",&fnt_name,wxEmptyString)) {
		if ( fnt_name != wxEmptyString ) {
			extern void SetGlobalDefaultFont(wxString fnt_name);
			SetGlobalDefaultFont(fnt_name);
		}
	}
	long term_buf_size ; fc.Read("TermBufferSize",&term_buf_size,0);
	wxColour newbg;
	int bg_red=0;
	int bg_green=0;
	int bg_blue=0;
	if (fc.Read("TermBackgroundColour/Red",&bg_red,0))
	if (fc.Read("TermBackgroundColour/Green",&bg_green,0)) 
	if (fc.Read("TermBackgroundColour/Blue",&bg_blue,0)){
		if(bg_red >0 || bg_green >0 || bg_blue >0 ) { 
			TerminalColors[0][0].Set(bg_red,bg_green,bg_blue);
			TerminalColors[0][7].Set(~bg_red,~bg_green,~bg_blue);
		}
	}
	
	/*
	wxString face_name = fc.Read("TermFont/FaceName",wxEmptyString);
	long fnt_family ; fc.Read("TermFont/FamilyName",&fnt_family,0);
	long fnt_style ; fc.Read("TermFont/Style",&fnt_style,0);
	long fnt_underlined ; fc.Read("TermFont/UnderLined",&fnt_underlined,0);
	long fnt_point_size ; fc.Read("TermFont/PointSize",&fnt_point_size,0);
	long fnt_weight ; fc.Read("TermFont/Weight",&fnt_weight,0);
	*/
}

bool Frame::Create(wxFrame * parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
	wxFrame::Create(parent, id, caption, pos, size, style);

	/*

	wxLogMessage("%s %d %d",slist,fc.GetNumberOfEntries(),fc.GetNumberOfGroups());
	*/
	//wxString slist;
	//long buf_size = 0;
	//wxString font_name;
	/*
    wxFont myFont(fnt.GetPointSize(), //pointsize
				 fnt.GetFamily(), //family
				 fnt.GetStyle(),//style
				 fnt.GetWeight(),//weight
				 fnt.GetUnderlined(),//underline
				 fnt.GetFaceName(),//facename
			     global_encoding.current);
				 */
	wxFileName fn(wxString(wxTheApp->argv[0]));
	wxString config_list(fn.GetPath() + "/config.ini");
    //wxFile file(config_list, wxFile::read);
	if (wxFile::Exists(config_list)) {
		LoadConfig();
		/*
		wxFileInputStream in(config_list);
		wxFileConfig fc(in);
		long isfull = 0; fc.Read("FullScreenMode",&isfull,0);
	
		wxString face_name = fc.Read("TermFont/FaceName",wxEmptyString);
		long fnt_family ; fc.Read("TermFont/FamilyName",&fnt_family,0);
		long fnt_style ; fc.Read("TermFont/Style",&fnt_style,0);
		long fnt_underlined ; fc.Read("TermFont/UnderLined",&fnt_underlined,0);
		long fnt_point_size ; fc.Read("TermFont/PointSize",&fnt_point_size,0);
		long fnt_weight ; fc.Read("TermFont/Weight",&fnt_weight,0);
	
		long term_buf_size ; fc.Read("TermBufferSize",&term_buf_size,0);
		*/
	 }




	
	// Init the menu bar
	m_menuBar  = new wxMenuBar( wxMB_DOCKABLE );
	m_fileMenu = new wxMenu();
	wxMenuItem *item ;
	item = new wxMenuItem(m_fileMenu, MENU_EDIT_ADD_PAGE, _("New connect...\t"), _("Add New Page"), wxITEM_NORMAL);
	m_fileMenu->Append(item);

	item = new wxMenuItem(m_fileMenu, MENU_EDIT_DELETE_PAGE, _("Disconnect..\t"), _("Delete Page"), wxITEM_NORMAL);
	m_fileMenu->Append(item);
	//item = new wxMenuItem(m_fileMenu, MENU_ABOUT, _("About"), _("About"), wxITEM_NORMAL);
	//m_fileMenu->Append(item);

	item= new wxMenuItem(m_fileMenu, wxID_EXIT, _("E&xit"), _("Exit"), wxITEM_NORMAL);
	m_fileMenu->Append(item);
	m_menuBar->Append(m_fileMenu, _("Connection"));

	RenewServerList();
	/*
	wxFileName fn(wxString(wxTheApp->argv[0]));
	wxString serv_list(fn.GetPath() + "/servers.xml");
	TiXmlDocument doc( serv_list );
	if ( !doc.LoadFile()) {
  			wxMessageBox(wxString::Format("Can not find server list file:\n%s",serv_list.c_str()),
               _("Missing File"),
               wxOK | wxICON_INFORMATION, this);
		//printf("Can not find file %s\n",serv_list.c_str());
	}else{
		m_editMenu = new wxMenu();
		TiXmlNode *child =NULL;
		int i=0;
		while ( child = doc.IterateChildren(child) ){
			//wxLogMessage("%s",child->Value());
			TiXmlNode *sec_child = NULL;
	    	wxMenu* subMenu = new wxMenu;
			while ( sec_child = child->IterateChildren(sec_child)){
				//wxLogMessage("%s = %s",sec_child->Value(),sec_child->ToElement()->GetText());
				item = new wxMenuItem(subMenu, MENU_SERVERSTART+i, sec_child->ToElement()->GetText()
								, _(""), wxITEM_NORMAL);
				subMenu->Append(item);
				i++;
			}
			m_editMenu->Append(wxID_ANY,child->Value(),subMenu);
		}
		m_menuBar->Append(m_editMenu, _("&Servers"));
	}
	*/

	wxMenu *m_configMenu = new wxMenu();
	item = new wxMenuItem(m_configMenu, MENU_CONFIG_FONT ,"Font ..." , _("Change Font"), wxITEM_NORMAL);
	m_configMenu->Append(item);

	item = new wxMenuItem(m_configMenu, MENU_CONFIG_BACK ,"Background ..." , _("Change Background Color"), wxITEM_NORMAL);
	m_configMenu->Append(item);

	//encoding init
	//extern encodingList global_encoding;

	wxMenu* subMenu = new wxMenu;

	item = new wxMenuItem(subMenu, MENU_TELNET_ENCODING_DEFAULT, "System default" , _(""), wxITEM_RADIO);
	subMenu->Append(item);
	global_encoding.def = wxFONTENCODING_DEFAULT;
	global_encoding.current = wxFONTENCODING_DEFAULT;

	wxString facename;
	wxFontEncoding enc ;
	enc = wxFontMapper::GetEncodingFromName(wxString("GB2312"));
	if (wxFontMapper::Get()->IsEncodingAvailable(enc, facename)){
		item = new wxMenuItem(subMenu, MENU_TELNET_ENCODING_GB, 
					   wxFontMapper::GetEncodingDescription(enc), _(""), wxITEM_RADIO);
		subMenu->Append(item);
		global_encoding.gb = enc;
	}else{
		global_encoding.gb = wxFONTENCODING_DEFAULT;
	}

	enc = wxFontMapper::GetEncodingFromName(wxString("BIG5"));
	if (wxFontMapper::Get()->IsEncodingAvailable(enc, facename)) {
		item = new wxMenuItem(subMenu, MENU_TELNET_ENCODING_BIG5, 
						wxFontMapper::GetEncodingDescription(enc) , _(""), wxITEM_RADIO);
		subMenu->Append(item);
		global_encoding.big5 = enc;
	}else{
		global_encoding.big5 = wxFONTENCODING_DEFAULT;
	}

	m_configMenu->Append(wxID_ANY,"Encoding",subMenu);

	item = new wxMenuItem(m_configMenu, MENU_SHOW_FULL ,"FullScreen" , _("Show Full Screen"), wxITEM_NORMAL);
	m_configMenu->Append(item);

	m_configMenu->AppendSeparator();

	item = new wxMenuItem(m_configMenu, MENU_RESET_DEFAULT_CONFIG ,"Reset" , _("Reset config to default value"), wxITEM_NORMAL);
	m_configMenu->Append(item);

	item = new wxMenuItem(m_configMenu, MENU_SAVE_CONFIG_INFO ,"Save Config" , _("Save Config Info"), wxITEM_NORMAL);
	m_configMenu->Append(item);

	m_menuBar->Append(m_configMenu, _("Config"));

	wxMenu *m_helpMenu = new wxMenu();

	item = new wxMenuItem(m_helpMenu, MENU_MANUAL, _("Manual"), _("Manual"), wxITEM_NORMAL);
	m_helpMenu->Append(item);
	item = new wxMenuItem(m_helpMenu, MENU_VISIT_HOMEPAGE, _("Visit Homepage"), _("Visit Project HomePage"), wxITEM_NORMAL);
	m_helpMenu->Append(item);
	m_helpMenu->AppendSeparator();

	item = new wxMenuItem(m_helpMenu, MENU_ABOUT, _("About"), _("About"), wxITEM_NORMAL);
	m_helpMenu->Append(item);

	m_menuBar->Append(m_helpMenu, _("Help"));

	SetMenuBar(m_menuBar);

	// Create a right click menu
	wxMenu *rmenu = new wxMenu();
	item = new wxMenuItem(rmenu, MENU_EDIT_ADD_PAGE, _("New Tab"), _("New Tab"), wxITEM_NORMAL);
	rmenu->Append(item);

	item = new wxMenuItem(rmenu, MENU_RENAME_TAB_PAGE, _("Rename Tab"), _("Rename Tab"), wxITEM_NORMAL);
	rmenu->Append(item);

	item = new wxMenuItem(rmenu, MENU_EDIT_DELETE_PAGE, _("Close Tab"), _("Close Tab"), wxITEM_NORMAL);
	rmenu->Append(item);

	rmenu->AppendSeparator();

	item = new wxMenuItem(rmenu, MENU_TELNET_CLOSE, _("Close"), _("Close Session"), wxITEM_NORMAL);
	rmenu->Append(item);
	item = new wxMenuItem(rmenu, MENU_TELNET_RECONNECT, _("Reconnect"), _("Reconnect Session"), wxITEM_NORMAL);
	rmenu->Append(item);

	rmenu->AppendSeparator();

	item = new wxMenuItem(rmenu, MENU_TELNET_DUPLICATE, _("Duplicate"), _("Duplicate Session"), wxITEM_NORMAL);
	rmenu->Append(item);
	item = new wxMenuItem(rmenu, MENU_TELNET_SPLIT_VER, _("Split Vert"), _("Split Vertical"), wxITEM_NORMAL);
	rmenu->Append(item);
	item = new wxMenuItem(rmenu, MENU_TELNET_SPLIT_HOR, _("Split Hor"), _("Split Horizontal"), wxITEM_NORMAL);
	rmenu->Append(item);

	rmenu->AppendSeparator();

	item = new wxMenuItem(rmenu, MENU_TELNET_HIDE_SCROLLBAR, _("Hide ScrollBar"), _("Hide ScrollBar"), wxITEM_NORMAL);
	rmenu->Append(item);
	item = new wxMenuItem(rmenu, MENU_SHOW_FULL, _("FullScreen"), _("Full Screen"), wxITEM_NORMAL);
	rmenu->Append(item);

	rmenu->AppendSeparator();
	item = new wxMenuItem(rmenu, MENU_CHANGE_BUFFER_SIZE, _("BufferSize"), _("Change Buffer Size"), wxITEM_NORMAL);
	rmenu->Append(item);

	wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
	SetSizer(mainSizer);

	long bookStyle = 0; 
	m_bVCStyle ? bookStyle |= wxFNB_VC71 : bookStyle |= 0;
	bookStyle |= wxFNB_TABS_BORDER_SIMPLE;

	book = new wxFlatNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, bookStyle);
	book->SetBackgroundColour(TerminalColors[0][0]);
	//book->SetBackgroundColour(*wxBLACK);

	//secondBook = new wxFlatNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, bookStyle);

	// Set right click menu to the notebook
	book->SetRightClickMenu(rmenu);
	right_menu = rmenu;
	// Set the image list 
	book->SetImageList(&m_ImageList);
	mainSizer->Add(book, 6, wxEXPAND);

	/*
	// Add spacer between the books
	
	wxPanel *spacer = new wxPanel(this, wxID_ANY);
	spacer->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
	mainSizer->Add(spacer, 0, wxALL | wxEXPAND);
	*/

	/*
	mainSizer->Add(secondBook, 2, wxEXPAND);

	// Add some pages to the second notebook
	Freeze();
	wxTextCtrl *text = new wxTextCtrl(secondBook, wxID_ANY, _("Second Book Page 1"), wxDefaultPosition, wxDefaultSize, 
		wxTE_MULTILINE);
	secondBook->AddPage(text,  _("Second Book Page 1"));

	text = new wxTextCtrl(secondBook, wxID_ANY, _("Second Book Page 2"), wxDefaultPosition, wxDefaultSize, 
		wxTE_MULTILINE);
	secondBook->AddPage(text,  _("Second Book Page 2"));

	Thaw();	
	*/
//#ifdef DEVELOPMENT
	text = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
                            wxDefaultPosition, wxSize(10,-1),
                            wxTE_MULTILINE | wxTE_READONLY);
    m_logTargetOld = wxLog::SetActiveTarget( new wxLogTextCtrl(text) );
	mainSizer->Add(text, 1, wxEXPAND);
#ifndef __WXDEBUG__
	text->Hide();
#endif
//#endif
	
	long styleb = book->GetWindowStyleFlag();

	if(styleb & wxFNB_VC71)
		styleb ^= wxFNB_VC71;

	styleb |= wxFNB_FANCY_TABS;
	styleb |= wxFNB_BOTTOM;
	
	book->SetWindowStyleFlag(styleb);
	book->SetGradientColorTo(wxColour("FOREST GREEN"));

			
	#include "icon/AFPClient_16.xpm"
    SetIcon(wxIcon(AFPClient_16_xpm));
	#include "icon/shutdown.xpm"
	#include "icon/terminal.xpm"
	#include "icon/console.xpm"

    wxSize imageSize(32, 32);

    m_imageList
        = new wxImageList( imageSize.GetWidth(), imageSize.GetHeight() );
    m_imageList->Add ( wxIcon(Shutdown_xpm));
    m_imageList->Add ( wxIcon(console_xpm));
   	m_imageList->Add ( wxIcon(console_xpm));

    wxToolBar *tb = CreateToolBar(wxTB_FLAT | wxTB_HORIZONTAL | wxNO_BORDER | wxTB_TEXT,wxID_ANY);
	tb->SetToolBitmapSize(imageSize);
	tb->SetWindowStyle( wxTB_FLAT | wxTB_DOCKABLE | wxTB_HORIZONTAL );
	tb->SetMargins(3, 3);
	
	tb->AddTool( MENU_EDIT_ADD_PAGE , wxEmptyString , wxIcon(console_xpm) , gettext("New Connect...") );
	tb->AddTool( MENU_EDIT_DELETE_PAGE , wxEmptyString , wxIcon(Shutdown_xpm) , gettext("Disconnect") );
	tb->AddSeparator();
	//for wxGTK add wxTE_PROCESS_ENTER 
	//txtAddress = new wxTextCtrl(tb, ID_TXT_ADDRESS, wxEmptyString, wxDefaultPosition, wxSize(200,-1),wxTE_PROCESS_ENTER ); 

	txtAddress  = new wxComboBox(tb, ID_TXT_ADDRESS,wxEmptyString , 
					wxDefaultPosition, 
					wxSize(200,-1),
					0,NULL,
				   	wxCB_SORT);
			
	//wxFileName fn(wxString(wxTheApp->argv[0]));
	wxString his_list(fn.GetPath() + "/history.servers");
	
	{//load history file into combobox
   		 bool success = false;
   		 wxFile file(his_list, wxFile::read);

   		 if (file.IsOpened())
   		 {
   		     wxString contents;
   		     // get the file size (assume it is not huge file...)
   		     ssize_t len = (ssize_t)file.Length();

   		     if (len > 0)
   		     {
   		         wxString buffer;
   		         success = (file.Read(wxStringBuffer(buffer, len), len) == len);
   		         contents = buffer;
				 while(buffer.Find('\n') != -1){
					int pos = buffer.Find('\n');
					wxString a_line(buffer.Mid(0,pos));
					a_line.Replace("\n","");
					if (a_line.Len() != 0 ) txtAddress->Append(a_line);
					buffer.Remove(0,pos+1);
				 }
   		     }
   		 }

	}
	tb->AddControl( new wxStaticText(tb, -1, _T("[protocol://]Server[:port_num]:") ) );
	tb->AddControl( txtAddress );
	//tb->AddControl( new wxStaticText(tb,-1,_T(" Control/Shift + Left/Right/Up/Down: Switch connections;\n Shift + PageDown/PageUp: Scroll half screen;"))); 
	//tb->AddControl( new wxStaticText(tb,-1,_T(" Mouse Left (Double Click): Selec a word on screen;\n Mouse Right (Click) : Copy words from Clipboard to current caret position")));
	tb->Realize();
	
	Centre(); 
	mainSizer->Layout();
	SendSizeEvent();
	return true;
}

void Frame::OnStyle(wxCommandEvent& event)
{
	long style = book->GetWindowStyleFlag();
	switch(event.GetId())
	{
	case MENU_HIDE_NAV_BUTTONS:
		if(event.IsChecked())
		{
			// Hide the navigation buttons
			style |= wxFNB_NO_NAV_BUTTONS;
		}
		else
		{
			if(style & wxFNB_NO_NAV_BUTTONS)
				style ^= wxFNB_NO_NAV_BUTTONS;
		}
		book->SetWindowStyleFlag(style);
		break;
	case MENU_HIDE_X:
		if(event.IsChecked())
		{
			// Hide the X button
			style |= wxFNB_NO_X_BUTTON;
		}
		else
		{
			if(style & wxFNB_NO_X_BUTTON)
				style ^= wxFNB_NO_X_BUTTON;
		}
		book->SetWindowStyleFlag(style);
		break;
	case MENU_DRAW_BORDER:
		if(event.IsChecked())
		{
			style |= wxFNB_TABS_BORDER_SIMPLE;
		}
		else
		{
			if(style & wxFNB_TABS_BORDER_SIMPLE)
				style ^= wxFNB_TABS_BORDER_SIMPLE;
		}
		book->SetWindowStyleFlag(style);
		break;
	case MENU_USE_MOUSE_MIDDLE_BTN:
		if(event.IsChecked())
		{
			style |= wxFNB_MOUSE_MIDDLE_CLOSES_TABS;
		}
		else
		{
			if(style & wxFNB_MOUSE_MIDDLE_CLOSES_TABS)
				style ^= wxFNB_MOUSE_MIDDLE_CLOSES_TABS;
		}
		book->SetWindowStyleFlag(style);
		break;
	case MENU_USE_BOTTOM_TABS:
		if(event.IsChecked())
		{
			style |= wxFNB_BOTTOM;
		}
		else
		{
			if(style & wxFNB_BOTTOM)
				style ^= wxFNB_BOTTOM;
		}
		book->SetWindowStyleFlag(style);
		book->Refresh();
		break;
	}
}

void Frame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
	Close(true);
}

void Frame::OnDeleteAll(wxCommandEvent& WXUNUSED(event))
{
	book->DeleteAllPages();
}

void Frame::OnShowImages(wxCommandEvent& event)
{
	m_bShowImages = event.IsChecked();
}

void Frame::OnVC71Style(wxCommandEvent& event)
{
	long style = book->GetWindowStyleFlag();

	if(style & wxFNB_FANCY_TABS)
		style ^= wxFNB_FANCY_TABS;
	style |= wxFNB_VC71;

	book->SetWindowStyleFlag(style);
}

void Frame::OnDefaultStyle(wxCommandEvent& event)
{
	long style = book->GetWindowStyleFlag();

	if(style & wxFNB_FANCY_TABS)
		style ^= wxFNB_FANCY_TABS;

	if(style & wxFNB_VC71)
		style ^= wxFNB_VC71;

	book->SetWindowStyleFlag(style);
}

void Frame::OnFancyStyle(wxCommandEvent& event)
{
	long style = book->GetWindowStyleFlag();

	if(style & wxFNB_VC71)
		style ^= wxFNB_VC71;

	style |= wxFNB_FANCY_TABS;
	book->SetWindowStyleFlag(style);
}

void Frame::OnSelectColor(wxCommandEvent& event)
{
	// Open a color dialog
	wxColourData data;
	wxColourDialog dlg(this, &data);
	if(dlg.ShowModal() == wxID_OK)
	{
		switch(event.GetId())
		{
		case MENU_SELECT_GRADIENT_COLOR_BORDER:
			book->SetGradientColorBorder(dlg.GetColourData().GetColour());
			break;
		case MENU_SELECT_GRADIENT_COLOR_FROM:
			book->SetGradientColorFrom(dlg.GetColourData().GetColour());
			break;
		case MENU_SELECT_GRADIENT_COLOR_TO:
			book->SetGradientColorTo(dlg.GetColourData().GetColour());
//			"DARK OLIVE GREEN"
			break;
		}
		book->Refresh();
	}
}

void Frame::NewTelnetPage(SiteInfo *site)
{
	wxString hostname = site->ip;
	if ( hostname.Len() == 0 ) return; 
	Freeze();
   	MySplitterWindow* m_splitter = new MySplitterWindow(this);
    
    m_splitter->SetSashGravity(0.5);
	
	
	 enjScrollTelnetPanel *telpanel= new enjScrollTelnetPanel(m_splitter,this);
	 //telpanel->NewConnection(site);
	 if (telpanel->NewConnection(site)) {
	 	//add current host into history.servers
		wxFileName fn(wxString(wxTheApp->argv[0]));
		wxString hostname;
		if ( site->protocol == SOCK_TELNET ) {
			hostname = "telnet://";
		}else if ( site->protocol == SOCK_SSH ) {
			hostname = "ssh://";
		}else if ( site->protocol == SOCK_EXECMD ) {
			hostname = "shell://";
		}
		hostname += site->ip;
		if ( site->protocol != SOCK_EXECMD ) {
			hostname +=wxString::Format(":%d",site->port);
		}
		wxString his_list(fn.GetPath() + "/history.servers");
		int isfind=0;
		{//load history file check duplicate 
			 bool success;
	   		 wxFile file(his_list, wxFile::read);
	   		 if (file.IsOpened())
	   		 {
	   		     wxString contents;
	   		     // get the file size (assume it is not huge file...)
	   		     ssize_t len = (ssize_t)file.Length();
	
	   		     if (len > 0)
	   		     {
	   		         wxString buffer;
	   		         success = (file.Read(wxStringBuffer(buffer, len), len) == len);
	   		         contents = buffer;
					 while(buffer.Find('\n') != -1){
						int pos = buffer.Find('\n');
						wxString a_line(buffer.Mid(0,pos));
						a_line.Replace("\n","");
						if ( a_line == hostname ) {
							isfind = 1; break;
						}
						//txtAddress->Append(a_line);
						buffer.Remove(0,pos+1);
					 }
	   		     }
	   		 }
		}
		{
			if ( !isfind ) {
	   	 		wxFile file(his_list, wxFile::write_append);
	   		 	if (file.IsOpened()){
					file.Write(hostname+"\n");
				}
				txtAddress->Append(hostname);
			}
		}
	 }
	 
 	 telpanel->SetFocus();

	 m_splitter->Initialize(telpanel);
	 book->AddPage(m_splitter,  hostname, true, m_bShowImages ? 1 : -1);	
	 book->SetSelection(book->GetPageCount()-1);
	 book->HideTabs(!IsFullScreen());
	 Thaw();	
}

void Frame::NewTelnetPage(wxString hostname)
{
	if ( hostname.Len() == 0 ) return; 
	Freeze();
   	MySplitterWindow* m_splitter = new MySplitterWindow(this);
    
    m_splitter->SetSashGravity(0.5);
	
	
	 enjScrollTelnetPanel *telpanel= new enjScrollTelnetPanel(m_splitter,this);
	 if (telpanel->NewConnection(hostname)) {
	 	//add current host into history.servers
		wxFileName fn(wxString(wxTheApp->argv[0]));
		wxString his_list(fn.GetPath() + "/history.servers");
		int isfind=0;
		{//load history file check duplicate 
			 bool success;
	   		 wxFile file(his_list, wxFile::read);
	   		 if (file.IsOpened())
	   		 {
	   		     wxString contents;
	   		     // get the file size (assume it is not huge file...)
	   		     ssize_t len = (ssize_t)file.Length();
	
	   		     if (len > 0)
	   		     {
	   		         wxString buffer;
	   		         success = (file.Read(wxStringBuffer(buffer, len), len) == len);
	   		         contents = buffer;
					 while(buffer.Find('\n') != -1){
						int pos = buffer.Find('\n');
						wxString a_line(buffer.Mid(0,pos));
						a_line.Replace("\n","");
						if ( a_line == hostname ) {
							isfind = 1; break;
						}
						//txtAddress->Append(a_line);
						buffer.Remove(0,pos+1);
					 }
	   		     }
	   		 }
		}
		{
			if ( !isfind ) {
	   	 		wxFile file(his_list, wxFile::write_append);
	   		 	if (file.IsOpened()){
					file.Write(hostname+"\n");
				}
				txtAddress->Append(hostname);
			}
		}
	 }
 	 telpanel->SetFocus();
	 /*
	 enjScrollTelnetPanel *right= new enjScrollTelnetPanel(m_splitter,this);
	 right->NewConnection(hostname);
 	 right->SetFocus();
	 */
	 m_splitter->Initialize(telpanel);
    //m_splitter->SplitVertically(telpanel, right);
	//book->AddPage(CreatePage(),  caption, true, m_bShowImages ? rand() % (int)book->GetImageList()->size() : -1);	
	book->AddPage(m_splitter,  hostname, true, m_bShowImages ? 1 : -1);	
	book->SetSelection(book->GetPageCount()-1);
	book->HideTabs(!IsFullScreen());
	Thaw();	
}

void Frame::OnAddPage(wxCommandEvent& WXUNUSED(event))
{
	static int newPageCounter = 0;
	SiteInfo *si=new SiteInfo;
	si->Init(SOCK_SSH);
PersonalRecordDialog dialog(si,NULL, wxID_ANY, wxT("New Connection..."),wxDefaultPosition,wxDefaultSize,wxDEFAULT_DIALOG_STYLE );
if (dialog.ShowModal() == wxID_CANCEL)
{
		return;
}

/*
 	 wxString hostname = wxGetTextFromUser(
 		   _("Format: [protocol://]server[:port_num]\nSupported protocol: telnet or ssh\n"),
 		   _("New Connect ..."),
 		   _(""));
		   */
	NewTelnetPage(si);	
	delete si;
	//caption.Printf(_("New Page Added #%ld"), newPageCounter++);
}


wxWindow* Frame::CreatePage()
{
	static int newPageCounter = 0;
	wxString caption;
	caption.Printf(_("New Page Added #%ld"), newPageCounter++);

//	if(newPageCounter % 2)
//	{
		//return  new wxTextCtrl(book, wxID_ANY, caption, wxDefaultPosition, book->GetPageBestSize(), wxTE_MULTILINE);
 		 wxString hostname = wxGetTextFromUser(
 		   _("Enter the address of server:"),
 		   _("Connect ..."),
 		   _(""));
	     //return new wxPanel(book,wxID_ANY);//enjScrollTelnetPanel(book,book);
		 enjScrollTelnetPanel *telpanel= new enjScrollTelnetPanel(book,this);
		 telpanel->NewConnection(hostname);
	 	 telpanel->SetFocus();
		 return telpanel;
		
//	}
//	else
//	{
//		wxPanel* p = new wxPanel(book, wxID_ANY, wxDefaultPosition, book->GetPageBestSize());
//		wxTextCtrl *txt = new wxTextCtrl(p, wxID_ANY, caption);
//		return p;
//	}
}

void Frame::OnDeletePage(wxCommandEvent& (event))
{
	if ( book->GetPageCount() == 1 ) {
		if ( IsFullScreen()){
			OnFullScreen(event);
		}
	}
	book->DeletePage(book->GetSelection());
}

void Frame::OnSetSelection(wxCommandEvent& WXUNUSED(event))
{
	wxTextEntryDialog dlg(this, "Enter Tab Number to select:", "Set Selection");
	if(dlg.ShowModal() == wxID_OK)
	{
		wxString val = dlg.GetValue();
		long tabIdx;
		val.ToLong(&tabIdx);
		book->SetSelection((size_t)tabIdx);
	}
}

void Frame::OnEnableTab(wxCommandEvent& WXUNUSED(event))
{
	wxTextEntryDialog dlg(this, "Enter Tab Number to enable:", "Enable Tab");
	if(dlg.ShowModal() == wxID_OK)
	{
		wxString val = dlg.GetValue();
		long tabIdx;
		val.ToLong(&tabIdx);
		book->Enable((size_t)tabIdx, true);
	}
}

void Frame::OnDisableTab(wxCommandEvent& WXUNUSED(event))
{
	wxTextEntryDialog dlg(this, "Enter Tab Number to disable:", "Disable Tab");
	if(dlg.ShowModal() == wxID_OK)
	{
		wxString val = dlg.GetValue();
		long tabIdx;
		val.ToLong(&tabIdx);
		book->Enable((size_t)tabIdx, false);
	}
}

void Frame::OnEnableDrag(wxCommandEvent& event)
{
	long style = book->GetWindowStyleFlag();
	if(event.IsChecked())
	{
		if(style & wxFNB_NODRAG)
			style ^= wxFNB_NODRAG;
	}
	else
	{
		style |= wxFNB_NODRAG;
	}

	book->SetWindowStyleFlag(style);
}

void Frame::OnSetAllPagesShapeAngle(wxCommandEvent& WXUNUSED(event))
{
	
	wxTextEntryDialog dlg(this, _("Enter an inclination of header borders (0-15):"), _("Set Angle"));
	if(dlg.ShowModal() == wxID_OK)
	{
		wxString val = dlg.GetValue();
		unsigned int angle = wxAtoi(val);		
		book->SetAllPagesShapeAngle(angle);
	}
}

void Frame::OnSetPageImageIndex(wxCommandEvent& WXUNUSED(event))
{
	
	wxTextEntryDialog dlg(this, 
		wxString::Format(_("Enter an image index (0-%i):"), book->GetImageList()->size()-1), 
		_("Set Angle"));
	if(dlg.ShowModal() == wxID_OK)
	{
		wxString val = dlg.GetValue();
		unsigned int imgindex = wxAtoi(val);		
		book->SetPageImageIndex(book->GetSelection(), imgindex);
	}
}

void Frame::OnAdvanceSelectionFwd(wxCommandEvent& WXUNUSED(event))
{
	book->AdvanceSelection(true);
}

void Frame::OnAdvanceSelectionBack(wxCommandEvent& WXUNUSED(event))
{
	book->AdvanceSelection(false);
}

void Frame::OnPageChanging(wxFlatNotebookEvent& event)
{
#ifdef DEVELOPMENT
	wxString msg;
	msg.Printf(_("Page is changing: old=%ld new=%ld"), event.GetOldSelection(), event.GetSelection());
	wxLogMessage(msg);
#endif
}

void Frame::OnPageChanged(wxFlatNotebookEvent& event)
{
#ifdef DEVELOPMENT
	wxString msg;
	msg.Printf(_("Page has changed, new selection is now=%ld"), event.GetSelection());
	wxLogMessage(msg);
#endif
}

void Frame::OnPageClosing(wxFlatNotebookEvent& event)
{
#ifdef DEVELOPMENT
	wxString msg;
	msg.Printf(_("Page is closing: selection=%ld"), event.GetSelection());
	wxLogMessage(msg);
#endif
}


							/*
						if ( pt.y == cu.y ) {
							return tmp;
						}
						if ( pt.y+st.y == cu.y+cu.height ) {
							return tmp;
						}
						*/
						/*
						dis = pt.y + st.y - cu.y;
						if ( dis < FLOAT_DIS && dis > 0 ) {
							 return tmp;
						}
						dis = cu.y+ cu.height - pt.y;
						if ( dis < FLOAT_DIS && dis > 0 ) {
							return tmp;
						}
						*/

				/*
				{
					int dis = cu.x - pt.x - st.x;
					if ( dis < FLOAT_DIS && dis >= 0 ){
						if ( pt.y <= cu.GetBottom() 
								&& (pt.y + st.y) >= cu.GetBottom() )
							   	return tmp;
						if ( pt.y <= cu.y 
								&& (pt.y+st.y) >= cu.y )
								return tmp;
						if ( pt.y >= cu.y 
								&& pt.y+st.y <= cu.GetBottom())
								return tmp;
								
					}
					break;
				}
				
				case TELNET_RIGHT:
				{
					int dis = pt.x - cu.GetRight() ;
					if ( dis < FLOAT_DIS && dis >=0 ){
						if ( pt.y <= cu.GetBottom() 
								&& (pt.y + st.y) >= cu.GetBottom() )
							   	return tmp;
						if ( pt.y <= cu.y 
								&& (pt.y+st.y) >= cu.y )
								return tmp;
						if ( pt.y >= cu.y 
								&& pt.y+st.y <= cu.GetBottom())
								return tmp;
					}
					break;
				}
				*/
#define FLOAT_DIS		20
#define TELNET_LEFT		1
#define TELNET_RIGHT	2
#define TELNET_UP		3
#define TELNET_DOWN		4

wxWindow *compareit(wxWindow *tmp,wxRect cu,int side)
{
			wxPoint pt = (tmp->GetParent())->ClientToScreen(tmp->GetPosition());
			wxSize	st = tmp->GetSize();
			wxRect t_cu(pt,st);
			/*
			{
				if ( dis <= FLOAT_DIS && dis >= 0 ) {
					if ( t_cu.GetTop() <= cu.GetBottom() 
							&& t_cu.GetBottom() >= cu.GetBottom())
						return tmp;
					if ( t_cu.GetTop() <= cu.GetTop() 
							&& t_cu.GetBottom() >= cu.GetTop())
						return tmp;
					if ( t_cu.GetTop() >= cu.GetTop()
							&& t_cu.GetBottom() <= cu.GetBottom())
						return tmp;
				}
			}
			*/
			switch ( side ) {
				case TELNET_LEFT:
				case TELNET_RIGHT:
				{
					int dis=-1;
					if ( side == TELNET_LEFT ){
						dis = cu.GetLeft() - t_cu.GetRight();
					}else{
						dis = t_cu.GetLeft() - cu.GetRight() ;
					}
					if ( dis <= FLOAT_DIS && dis >= 0 ) {
						if ( t_cu.GetTop() <= cu.GetBottom() 
								&& t_cu.GetBottom() >= cu.GetBottom())
							return tmp;
						if ( t_cu.GetTop() <= cu.GetTop() 
								&& t_cu.GetBottom() >= cu.GetTop())
							return tmp;
						if ( t_cu.GetTop() >= cu.GetTop()
								&& t_cu.GetBottom() <= cu.GetBottom())
							return tmp;
					}
					break;
				}
				case TELNET_UP:
				case TELNET_DOWN:
				{
					int dis = -1;
					if ( side == TELNET_UP ) {
						dis = cu.GetTop() - t_cu.GetBottom();
					}else{
						dis = t_cu.GetTop() - cu.GetBottom();
					}
					if ( dis <= FLOAT_DIS && dis >= 0 ) {
						if ( t_cu.GetRight() >= cu.GetLeft()
							&& t_cu.GetLeft() <= cu.GetLeft())
							return tmp;
						if ( t_cu.GetRight() >= cu.GetRight()
							&& t_cu.GetLeft() <= cu.GetRight())
							return tmp;
						if ( t_cu.GetRight() <= cu.GetRight()
							&& t_cu.GetLeft() >= cu.GetLeft())
							return tmp;
					}
					break;
				}
				/*
				case TELNET_DOWN:
				{
					break;
				}
				*/
			}
			return NULL;
}

void Frame::GetHorSplitedWin(MySplitterWindow *ro,wxRect cu,wxWindow **ta,int side)
{
	wxWindow *win1=ro->GetWindow1();
	wxWindow *win2=ro->GetWindow2();
	wxWindow *tmp=NULL;

	if ( win1 ) {
		if (win1->IsKindOf(CLASSINFO(wxSplitterWindow))) {
			GetHorSplitedWin((MySplitterWindow *)win1,cu,&tmp,side);
		}else if (win1->IsKindOf(CLASSINFO(wxPanel))) {
			tmp=win1;
		}
		if (tmp) {
			*ta =compareit(tmp,cu,side);
			if ( *ta ) return;
		}
		tmp=NULL;
	}
	if ( win2 ) {
		if (win2->IsKindOf(CLASSINFO(wxPanel))) {
			tmp=win2;
		}else if (win2->IsKindOf(CLASSINFO(wxSplitterWindow))) {
				GetHorSplitedWin((MySplitterWindow *)win2,cu,&tmp,side);
		}
		if (tmp) {//compare tmp with ta
			*ta =compareit(tmp,cu,side);
			if ( *ta ) return;
		}
		tmp=NULL;
	}
		
}

void Frame::OnKeyDown(wxKeyEvent& event)
{

	//這必須放在前面，不然可能會被 now_telnet->OnKeyDown(event); 呼叫 event.Skip();
//	GetParent()->ProcessEvent(event);
		wxLogMessage("key down");
		int key = event.GetKeyCode();
		if (event.ShiftDown()) {
				switch (key)
				{
					case WXK_LEFT:
					{
						book->AdvanceSelection(false); 
						return;
					}
					case WXK_RIGHT:
					{

						book->AdvanceSelection(true); 
						return;
					}
					break;
					default:
						event.Skip();
						break;
				}
		}else if ( event.ControlDown() ) {
				MySplitterWindow *stel = (MySplitterWindow*)(book->GetPage(book->GetSelection()));

				wxWindow *fc=enjFindFocus();
				wxWindow *sc = fc->GetParent();//should be a scroll telnet panel
				wxWindow *target=NULL;
				wxPoint point = (sc->GetParent())->ClientToScreen(sc->GetPosition());
				wxRect rect(point,sc->GetSize());
				switch (key)
				{
					case WXK_LEFT:
					{
						wxLogMessage("Control+Left");
						GetHorSplitedWin(stel,rect,&target,TELNET_LEFT);
						if ( target ) target->SetFocus();
						return;
					}
					case WXK_RIGHT:
					{
						wxLogMessage("Control+Right");
						GetHorSplitedWin(stel,rect,&target,TELNET_RIGHT);
						if ( target ) target->SetFocus();
						return;
					}
					break;
					case WXK_UP:
					{
						wxLogMessage("Control+Up");
						GetHorSplitedWin(stel,rect,&target,TELNET_UP);
						if ( target ) target->SetFocus();
						return;
					}
					break;
					case WXK_DOWN:
					{
						wxLogMessage("Control+Down");
						GetHorSplitedWin(stel,rect,&target,TELNET_DOWN);
						if ( target ) target->SetFocus();
						return;
					}
					break;
					case WXK_F1:
					case WXK_F2:
					case WXK_F3:
					case WXK_F4:
					case WXK_F5:
					case WXK_F6:
					case WXK_F7:
					case WXK_F8:
					case WXK_F9:
					case WXK_F10:
					case WXK_F11:
					case WXK_F12:
					{
						int pos = key - WXK_F1;
						if ( pos < book->GetPageCount() ) {
							book->SetSelection(pos);
						}
						event.Skip(false);
						break;
					}
					case WXK_TAB:
					{
						book->AdvanceSelection(true); 
					}
					default:
						event.Skip();
						break;
				}
		}else if ( event.AltDown()) {
				switch (key ){
					case WXK_RETURN:
					{
						wxCommandEvent ev;
						OnFullScreen(ev);
						break;
					}
				}
		}
}

