/*  Project Tec3270

	 SUBSYSTEM:    Tec3270.exe (Tec3270 application)
	 FILE:         alffntap.cpp
	 AUTHOR:       Alcindo Ferreira Filho

	 OVERVIEW:
	 Tec3270App and Tec3270MainWindow Classes Implementation, the base
    classes for Tec3270 application. They include Menu, Tool Bar,
    Status Bar, etc...

    COPYRIGHT:    © 1998-2007
                  Alcindo Ferreira Filho
                  <alcindo@inttec.com.br>

    LICENSE:      Tec3270_License (docs/Tec3270_License.txt)
*/

#include "alffnall.h"

//{{Tec3270App Implementation}}
//
// Build a response table for all messages/commands handled
// by the application.
//
DEFINE_RESPONSE_TABLE1(Tec3270App, TApplication)
//{{Tec3270AppRSP_TBL_BEGIN}}
	 EV_COMMAND(CM_HELPCONTENTS, CmHelpContents),
	 EV_COMMAND(CM_HELPUSING, CmHelpUsing),
    EV_COMMAND(CM_HELPVERSION, CmHelpVersion),
	 EV_COMMAND(CM_HELPABOUT, CmHelpAbout),
	 EV_COMMAND(CM_GETWSADATA, CmGetCommClusterInfo),
	 EV_COMMAND(CM_GETCOMPUTERADDRESS, CmGetComputerInfo),
	 EV_WM_WININICHANGE,
//{{Tec3270AppRSP_TBL_END}}
END_RESPONSE_TABLE;

//
// Build a response table for all messages/commands handled
// by the main window.
//
DEFINE_RESPONSE_TABLE1(Tec3270MainWindow,TDecoratedMDIFrame)
//{{Tec3270MainWindowRSP_TBL_BEGIN}}
	 EV_WM_SIZE,
	 EV_WM_MOVE,
	 EV_WM_CLOSE,
    EV_MESSAGE(MSG_BITMAP_PRESSED, EvStatusBitmapPressed),
//{{Tec3270MainWindowRSP_TBL_END}}
END_RESPONSE_TABLE;

//////////////////////////////////////////////////////////
// Tec3270MainWindow
// =================
//
Tec3270MainWindow::Tec3270MainWindow(char* title,
						 TResId menuResId, ALFFMDIClient& clientWnd,
						 bool trackMenuSelection, TModule* module):
						 TDecoratedMDIFrame(title, menuResId, clientWnd,
												  trackMenuSelection, module)
{
 ALFFIniFile* iniFile;
 char iniSection[21];
 TRect winRect;
 /*
  * Set Font Char Metrics
  */
 SetFontMetrics();

 /* Access the Application Scope For Getting Ini File Pointer */
 Tec3270App *theApp = TYPESAFE_DOWNCAST(GetApplication(), Tec3270App);
 iniFile = theApp->GetIniFile();

 /* Register Date and Time Of Session Begin */
 strcpy(iniSection,APPLNAME);

 char timeStamp[STRINGMSGLEN];
 theApp->GetTimeStamp(timeStamp);
 iniFile->WriteString(iniSection,"LASTSESSIONBEGIN",timeStamp);

 /* Get Main Window coordinates */
 strcpy(iniSection,"POSITION");
 winRect.left = iniFile->GetInt(iniSection,"X",0);
 winRect.top = iniFile->GetInt(iniSection,"Y",0);
 winRect.right = winRect.left + iniFile->GetInt(iniSection,"CX",400);
 winRect.bottom = winRect.top + iniFile->GetInt(iniSection,"CY",400);

 /* Check Main Window Coordinates For its Limits */
 int XLimit = GetSystemMetrics(SM_CXFULLSCREEN)-1;
 int YLimit = GetSystemMetrics(SM_CYFULLSCREEN)-1;
 if ( ((winRect.left < 0) || (winRect.left > XLimit))
	 ||((winRect.top < 0) || (winRect.top > YLimit))
	 ||((winRect.right < 0) || (winRect.right > XLimit))
	 ||((winRect.bottom < 0)|| (winRect.bottom > YLimit)) )
	winRect = SetWindowCoordinates();

 /*
  * Setting up Window Coordinates
  */

 /* Calculate Main Window top left corner */
 int mainWinWidth  = winRect.Width();
 int mainWinHeight = winRect.Height();

 winRect.left = (GetSystemMetrics(SM_CXFULLSCREEN)-mainWinWidth-1)/2;
 if ( (winRect.left < 0)
	|| (winRect.left > GetSystemMetrics(SM_CXFULLSCREEN)))
	winRect.left = 0;

 winRect.top  = (GetSystemMetrics(SM_CYFULLSCREEN)-mainWinHeight-1)/2;
 if ( (winRect.top < 0)
	|| (winRect.top > GetSystemMetrics(SM_CYFULLSCREEN)))
	winRect.top = 0;

 Attr.X = winRect.left;
 Attr.Y = winRect.top;
 Attr.W = mainWinWidth;
 Attr.H = mainWinHeight;
}

Tec3270MainWindow::~Tec3270MainWindow()
{
; /* Nothing to do */
}

void
Tec3270MainWindow::SetupWindow()
{
  TDecoratedMDIFrame::SetupWindow();
  /*  Setup the base window width for status bar laying out */
  Tec3270App *theApp =  TYPESAFE_DOWNCAST(GetApplication(), Tec3270App);
  theApp->SetBaseWinWidth(730);
}
void
Tec3270MainWindow::EvMove(TPoint& clientOrigin)
{
 TDecoratedMDIFrame::EvMove(clientOrigin);
 /* Include your code here */
}

void
Tec3270MainWindow::EvClose()
{
 PostMessage(WM_COMMAND,CM_ALFFEXIT,0);
}

LRESULT
Tec3270MainWindow::EvStatusBitmapPressed(WPARAM /*wParam*/, LPARAM lParam)
{
 if (lParam == IDG_ALFFSSLLOCK)
  {
   ALFFMDIChild* currChild = (ALFFMDIChild *)GetClientWindow()->GetActiveMDIChild();
   if (currChild && !currChild->IsWHLLSession())
       currChild->ShowCertificate();
  }
 else if (lParam == IDG_ALFFPRINTER)
  {
   ALFFMDIChild* currChild = (ALFFMDIChild *)GetClientWindow()->GetActiveMDIChild();
   if (currChild && !currChild->IsWHLLSession() && currChild->GetRemotePrinter())
       currChild->GetRemotePrinter()->Show(SW_SHOW);
  }
 return 1L;
}


void
Tec3270MainWindow::SetFontMetrics()
{
 unsigned int cWidth, cHeight;
 /* Access the Application Scope */
 Tec3270App *theApp = TYPESAFE_DOWNCAST(GetApplication(), Tec3270App);

 /*
  * Calculates Font Char Metrics
  */
 TEXTMETRIC tm;
 TScreenDC dc;
 if (theApp->GetAppFont())
  dc.SelectObject(*theApp->GetAppFont());
 dc.GetTextMetrics(tm);
 cHeight = tm.tmHeight + tm.tmExternalLeading +1; //For Line Spacing
 cWidth  = tm.tmAveCharWidth;
 theApp->SetFontCharWidth(cWidth);
 theApp->SetFontCharHeight(cHeight);
}

TRect
Tec3270MainWindow::SetWindowCoordinates()
{
 TRect wRect = GetWindowRect();

 /* Access the Application Scope */
 Tec3270App *theApp = TYPESAFE_DOWNCAST(GetApplication(), Tec3270App);

 /*
  * Get Font Char Metrics
  */
 unsigned int cWidth  = theApp->GetFontCharWidth();
 unsigned int cHeight = theApp->GetFontCharHeight();

 // Set System Screen Properties for calculating position
 int scrollBottom = 0;
 // Window's Vertical Border width
 int XBorder = GetSystemMetrics(SM_CXSIZEFRAME);
 // Window's Vertical Right Border 3D shadow width
 int X3DBorder =  GetSystemMetrics(SM_CXEDGE);
 // Tec3270 Current Screen line size (collumns)
 int XCols  = theApp->GetTermLineSize();
 // Screen Full Size Width in Pixels (600,800,1024)
 int XLimit = 0;
 // Screen Full Size Height minus tray height, if it is always visible
 //  in Pixels (480, 600, 768 or less if tray is visible)
 int YLimit = 0;
 TRect screenRect;
 if (SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect,0))
  {
    XLimit = (int)(screenRect.right-screenRect.left+1);
    YLimit = (int)(screenRect.bottom-screenRect.top+1);
  }
 else
  {
    XLimit = GetSystemMetrics(SM_CXFULLSCREEN);
    YLimit = GetSystemMetrics(SM_CYFULLSCREEN);
  }

 // Window's  Caption Height
 int YCaption = GetSystemMetrics(SM_CYCAPTION);
 // Window's Horizontal Border height
 int YBorder   = GetSystemMetrics(SM_CYSIZEFRAME);
 // Window's Horizontal Bottom Border 3D shadow height
 int Y3DBorder    = GetSystemMetrics(SM_CYEDGE);
 // Window's Menu Line Height
 int YMenuBut = GetSystemMetrics(SM_CYMENUSIZE) + (YBorder*2);
 // Window's Menu ToolBar Button Height
 int YMenu   = GetSystemMetrics(SM_CYMENU) + YBorder;

 // First Time Status Bar is not available, so we must use
 // YCaption as an approximation to its height.
 int YStatBar =  0;
 if (theApp->GetStatusBar())
    YStatBar = theApp->GetStatusBar()->Attr.H + YBorder;
 else YStatBar = YCaption + YBorder;

 // Tec3270 Current Screen number of lines
 int YLines  = theApp->GetTermNumLines();

  /* Calculate Main Window top left corner shift from left */
 wRect.left = (XLimit-
              (XCols * cWidth)-(XBorder*2)-X3DBorder) / 2;

 if ((wRect.left < 0)||(wRect.left > XLimit))
	  wRect.left = 0;

 /* Calculate Main Window top left corner shift from top */
 wRect.top  = (YLimit-
 				  (YLines * cHeight)-
				  (YBorder*2)-YCaption-YMenu-YMenuBut-YStatBar-Y3DBorder) / 2;

 if ((wRect.top < 0) || (wRect.top > YLimit))
	  wRect.top = 0;

 /* Calculate MainWindow down right corner shift from top  */
 wRect.right = wRect.left+
					(XCols*cWidth)+
					(XBorder*2)+X3DBorder;

 if ( (wRect.right < 0)
	|| (wRect.right > (XLimit+(XBorder/2))) )
  {
	wRect.right = XLimit;
	//scrollBottom = GetSystemMetrics(SM_CYVTHUMB);
  }

 /* Calculate MainWindow down right corner shift from left */
 wRect.bottom = wRect.top+
					 (theApp->GetTermNumLines()*cHeight)+
                (YBorder*2)+YCaption+YMenu+YMenuBut+
                 YStatBar+Y3DBorder; //+ scrollBottom;

 if ( (wRect.bottom < 0)
	|| (wRect.bottom > YLimit))
  {
	wRect.bottom = YLimit;
	wRect.right += GetSystemMetrics(SM_CXHTHUMB);
  }

 return wRect;
}

int
Tec3270MainWindow::ResizeWindow()
{
 TRect winRect;
 int  retCode = 0;

 /* Get New Window Coordinates */
 winRect = SetWindowCoordinates();

 /* Verify if new coordinates fit on Screen */
 if (winRect.right >= GetSystemMetrics(SM_CXFULLSCREEN))
	 retCode &= SETHSCROLL;

 if (winRect.bottom > GetSystemMetrics(SM_CYFULLSCREEN))
	 retCode &= SETVSCROLL;

 /*
  * Resize Window for new Coordinates
  */
 MoveWindow(winRect, TRUE);

  /* Access the Application Scope For Updating Main Window */
 Tec3270App *theApp = TYPESAFE_DOWNCAST(GetApplication(), Tec3270App);
 theApp->ReSizeStatusBar();

 return retCode;
}

void
Tec3270MainWindow::CleanupWindow()
{
 ALFFIniFile* iniFile;
 char iniSection[21];
 Tec3270App *theApp = TYPESAFE_DOWNCAST(GetApplication(), Tec3270App);

 iniFile = theApp->GetIniFile();
 strcpy(iniSection,"POSITION");

 /*
  * Save Main Window Position
  */
 long windowLong =  GetWindowLong(GWL_STYLE);
 int maximized = 0;

 if (windowLong & WS_MAXIMIZE)
	maximized = 1;
 iniFile->WriteInt(iniSection,"MAXIMIZED",maximized);

 if (!((windowLong & WS_MINIMIZE)
		 || (windowLong & WS_MAXIMIZE)))
  {
	TRect winPos = GetWindowRect();
	iniFile->WriteInt(iniSection,"X",winPos.left);
	iniFile->WriteInt(iniSection,"Y",winPos.top);
	iniFile->WriteInt(iniSection,"CX",winPos.Width());
	iniFile->WriteInt(iniSection,"CY",winPos.Height());
  }

 /* Register Date and Time Of Session Ending */
 strcpy(iniSection,APPLNAME);

 char timeStamp[STRINGMSGLEN];
 theApp->GetTimeStamp(timeStamp);
 iniFile->WriteString(iniSection,"LASTSESSIONEND",timeStamp);

 TDecoratedMDIFrame::CleanupWindow();

}


void
Tec3270MainWindow::EvSize(uint sizeType, TSize& size)
{
 TDecoratedMDIFrame::EvSize(sizeType,size);
 Tec3270App *theApp = TYPESAFE_DOWNCAST(GetApplication(), Tec3270App);
 theApp->ReSizeStatusBar();
}

// Tec3270App
// =====
//
Tec3270App::Tec3270App(char* iniFilePath) throw (ALFFException)
   : TApplication("Tec3270")
{
	 /* Initialize Printer Objects  */
	 Printer = 0;
	 Printing = false;
	 /*
	  * Printer Buffer will be initialized at the moment that
	  * user asks for saving printing pages (StorePrtFields)
     */
	 printerBuf = NULL;

	 /*
	  * Starting Up Socket Manager that will search for WINSOCK.DLL
	  */
	 alffCommCluster = new ALFFCommCluster("Tec3270",NULL);
    pClusterInfo    = NULL;
	 pLocalName      = NULL;
	 pLocalAddress   = NULL;

	 /*
	  * Make Application INI File Name and its corresponding object
	  */
	 char iniFileName[EXE_NAME_MAX_SIZE];
    if (iniFilePath)
     {
      if (!IsValidIniFile(iniFilePath, &iniFileName[0]))
         throw (ALFFException(IDS_ALFFINIFILEERROR));
     }
	 else MakeIniFileName(iniFileName);
	 iniFile = new ALFFIniFile(iniFileName);

	 /* Terminal Controls Initialization */
	 termLineSize = DEFAULTTERMLINESIZE;
	 termNumLines = DEFAULTTERMNUMLINES+1;
    baseWinWidth = 4096;   // Just for initialing before main window creation
	 /*
	  * Get Application Font From INI File and Calculate its
	  * size. Relies on MM_LOENGLISH map mode.
	  */
	 TScreenDC dc;
	 char iniSection[21];
	 scrFontName = new char[256];
	 strcpy(iniSection,"SCREEN FONT");
	 iniFile->GetString(iniSection,"NAME","FixedSys",
							  scrFontName,255);
	 scrCharHeight = iniFile->GetInt(iniSection,"HEIGHT",15);
	 scrCharWidth  = iniFile->GetInt(iniSection,"WIDTH",8);
	 scrFontSize  = iniFile->GetInt(iniSection,"SIZE",9);
	 int fontHeight  =
		  -MulDiv(scrFontSize,dc.GetDeviceCaps(LOGPIXELSY),72);
	 scrFontWeight = (int)iniFile->GetInt(iniSection,"WEIGHT",0);
	 scrFontItalic = (int)iniFile->GetInt(iniSection,"ITALIC",0);
	 scrFontCharset = (int)iniFile->GetInt(iniSection,"CHARSET",0);
	 fontSizing   = (int)iniFile->GetInt(iniSection,"FONTSIZING",0);
	 windowSizing = (int)iniFile->GetInt(iniSection,"WINDOWSIZING",1);
	 scrFont = new TFont(scrFontName,fontHeight,0,0,0,scrFontWeight,
								DEFAULT_PITCH|FF_DONTCARE,scrFontItalic,0,0,
								scrFontCharset);
	 /*
	  * Get Printer Font From INI File and Calculate its size.
	  *  Relies on MM_LOENGLISH map mode.
	  */
	 prtFontName = new char[256];
	 strcpy(iniSection,"SCREEN PRINTER DEVICE");
	 iniFile->GetString(iniSection,"FONTNAME","Courier New",
								  prtFontName,255);
	 prtCharHeight = iniFile->GetInt(iniSection,"FONTHEIGHT",12);
	 prtCharWidth  = iniFile->GetInt(iniSection,"FONTWIDTH",8);
	 prtFontSize  = iniFile->GetInt(iniSection,"FONTSIZE",11);
	 fontHeight  =
			 -MulDiv(prtFontSize,dc.GetDeviceCaps(LOGPIXELSY),72);
	 prtFontWeight = iniFile->GetInt(iniSection,"FONTWEIGHT",0);
	 prtFontItalic = iniFile->GetInt(iniSection,"FONTITALIC",0);
	 prtFontCharset = iniFile->GetInt(iniSection,"FONTCHARSET",0);
	 prtFont = new TFont(prtFontName,fontHeight,0,0,0,prtFontWeight,
								DEFAULT_PITCH|FF_DONTCARE,prtFontItalic,0,0,
								prtFontCharset);

	 /* Application is not ended when starting */
	 appEnded = false;

    /* Status Bar Not yet Available */
    sb = NULL;

    /* Status Bar Gadgets */
    sslLocker = NULL;
    tn3270TXT = NULL;
    termGadget = NULL;
    tNetName = NULL;
    prtGadget = NULL;
    pNetName = NULL;
    pDateTime = NULL;
    pNUMLOCK = NULL;
    pCAPSLOCK = NULL;
    pINSERTKEY = NULL;

	/* Security Object - Initially set to Off */
   InitSecurity(false);

   /* Initializing Help Controls */
   helpFile = NULL;
   HelpState = false;
   ContextHelp = false;

}

Tec3270App::~Tec3270App ()
{
 if (appInited)
  {
	 /* Save Actual Application Screen Font To INI File */
	 char iniSection[21];
	 strcpy(iniSection,"SCREEN FONT");
	 iniFile->WriteString(iniSection,"NAME",scrFontName);
	 iniFile->WriteInt(iniSection,"HEIGHT",scrCharHeight);
	 iniFile->WriteInt(iniSection,"WIDTH",scrCharWidth);
	 iniFile->WriteInt(iniSection,"SIZE",scrFontSize);
	 iniFile->WriteInt(iniSection,"WEIGHT",scrFontWeight);
	 iniFile->WriteInt(iniSection,"ITALIC",scrFontItalic);
	 iniFile->WriteInt(iniSection,"CHARSET",scrFontCharset);
	 iniFile->WriteInt(iniSection,"FONTSIZING",fontSizing);
	 iniFile->WriteInt(iniSection,"WINDOWSIZING",windowSizing);

	 /* Save Actual Application Screen Font To INI File */
	 strcpy(iniSection,"SCREEN PRINTER DEVICE");
	 iniFile->WriteString(iniSection,"FONTNAME",prtFontName);
	 iniFile->WriteInt(iniSection,"FONTHEIGHT",prtCharHeight);
	 iniFile->WriteInt(iniSection,"FONTWIDTH",prtCharWidth);
	 iniFile->WriteInt(iniSection,"FONTSIZE",prtFontSize);
	 iniFile->WriteInt(iniSection,"FONTWEIGHT",prtFontWeight);
	 iniFile->WriteInt(iniSection,"FONTITALIC",prtFontItalic);
	 iniFile->WriteInt(iniSection,"FONTCHARSET",prtFontCharset);

	 /* Delete Printer if exists one */
	 if (Printer)
		  delete Printer;
    if (printerBuf)
        delete printerBuf;

	 /* Delete Communications Cluster */
	 delete alffCommCluster;

	 /* Delete Font Descriptors */
	 delete [] scrFontName;
	 delete   scrFont;

	 delete [] prtFontName;
	 delete   prtFont;

	 /* Delete IniFile */
	 delete iniFile;

    if (helpFile != NULL)
      delete helpFile;

    /* Status Bar & Gadgets */
    delete sslLocker;
    delete tn3270TXT;
    delete termGadget;
    delete tNetName;
    delete prtGadget;
    delete pNetName;
    delete pDateTime;
    delete pNUMLOCK;
    delete pCAPSLOCK;
    delete pINSERTKEY;
    delete termSeparator;
    delete prtSeparator;
    delete padSeparator;
    delete modeSeparator;
    delete timeSeparator;
    delete sb;

    if (pSecurity != NULL)
     delete pSecurity;
  }
}

bool
Tec3270App::InitSecurity(bool securityOn)
{
  /* Setup all the global Security stuff */
  pSecurity = new ALFFUseSecurity(securityOn,true);  // true = MultiThreading on
  if (pSecurity)
    return true;
  else return false;
}

bool
Tec3270App::SetSecurityOn()
{
 if (pSecurity != NULL)
  {
    pSecurity->InitLibraries();
    return true;
  }
 else return false;
}


void
Tec3270App::GetTimeStamp(char* timeStamp)
{
 /* This routine accepts PORTUGUESE or ENGLISH Date/Fime Formats
  * If PORTUGUES is defined the date format will be:
  *            Day, Month, Year - Time
  * else it will be assumed that ENGLISH format must be supplied:
  *         WeekDay, Month Day Year, Time
  */
 char charTime[32];
 time_t t;
 time(&t);
 strcpy(&charTime[0],ctime(&t));
#if (PORTUGUES == 1)
 char month[4];
 memset(&charTime[3],NULL,1);
 if (!strcmp(charTime,"Mon"))
	strcpy(timeStamp,"Seg");
 else if (!strcmp(charTime,"Tue"))
	strcpy(timeStamp,"Ter");
 else if (!strcmp(charTime,"Wed"))
	strcpy(timeStamp,"Qua");
 else if (!strcmp(charTime,"Thu"))
	strcpy(timeStamp,"Qui");
 else if (!strcmp(charTime,"Fri"))
	strcpy(timeStamp,"Sex");
 else if (!strcmp(charTime,"Sat"))
	strcpy(timeStamp,"Sab");
 else if (!strcmp(charTime,"Sun"))
	strcpy(timeStamp,"Dom");
 else strcpy(timeStamp,"***");
 memset(&timeStamp[3],',',1);
 memset(&timeStamp[4],' ',1);
 memcpy(&timeStamp[5],&charTime[8],2);
 memset(&timeStamp[7],' ',1);
 memcpy(&month[0],&charTime[4],3);
 memset(&month[3],NULL,1);
 if (!strcmp(month,"Feb"))
	strcpy(month,"Fev");
 else if (!strcmp(month,"Apr"))
	strcpy(month,"Abr");
 else if (!strcmp(month,"May"))
	strcpy(month,"Mai");
 else if (!strcmp(month,"Aug"))
	strcpy(month,"Ago");
 else if (!strcmp(month,"Sep"))
	strcpy(month,"Set");
 else if (!strcmp(month,"Oct"))
	strcpy(month,"Out");
 else if (!strcmp(month,"Dec"))
	strcpy(month,"Dez");
 memcpy(&timeStamp[8],&month[0],3);
 memset(&timeStamp[11],' ',1);
 memcpy(&timeStamp[12],&charTime[20],4);
 memset(&timeStamp[16],' ',1);
 memset(&timeStamp[17],'-',1);
 memset(&timeStamp[18],' ',1);
 memcpy(&timeStamp[19],&charTime[11],8);
 memset(&timeStamp[27],NULL,1);
#elif (ENGLISH == 1)
 strcpy(timeStamp,charTime);
 memset(&timeStamp[3],',',1);
 memset(&timeStamp[4],' ',1);
 memcpy(&timeStamp[5],&charTime[4],6);
 memset(&timeStamp[11],',',1);
 memcpy(&timeStamp[12],&charTime[20],4);
 memset(&timeStamp[16],' ',1);
 memset(&timeStamp[17],'-',1);
 memset(&timeStamp[18],' ',1);
 memcpy(&timeStamp[19],&charTime[11],8);
 memset(&timeStamp[27],NULL,1);
#endif
}


void
Tec3270App::SetAppEnded()
{
 appEnded = TRUE;
}

bool
Tec3270App::IsAppEnded()
{
 return appEnded;
}

ALFFStatusBar*
Tec3270App::GetStatusBar()
{
 return sb;
}

bool
Tec3270App::UpdateSSLLock()
{
 ALFFMDIChild*  activeChild = (ALFFMDIChild*) mdiClient->GetActiveMDIChild();
 if ((activeChild!= NULL) && (activeChild->IsSSLConnected()) )
   sslLocker->SelectImage(0,true);
 else sslLocker->SelectImage(1,true);
 return true;
}
bool
Tec3270App::UpdateTN3270()
{
 ALFFMDIChild*  activeChild = (ALFFMDIChild*) mdiClient->GetActiveMDIChild();
 if ( (activeChild!= NULL) && (activeChild->GetTelnetPtr()) )
  {
   char* text = activeChild->GetTelnetPtr()->GetTN3270Mode();
   if ((text == NULL) || (strlen(text) == 0))
     tn3270TXT->SetText(" ");
   else tn3270TXT->SetText(text);
  }
 else tn3270TXT->SetText(" ");
 return true;
}

bool
Tec3270App::UpdateTermGadget()
{
 //termGadget;
 ALFFMDIChild*  activeChild = (ALFFMDIChild*) mdiClient->GetActiveMDIChild();
 if ((activeChild!= NULL) && (activeChild->GetTelnetPtr()) )
  {
   if (activeChild->GetTelnetPtr()->Is3270EMode())
     termGadget->SelectImage(0,true);
   else termGadget->SelectImage(1,true);
  }
 else termGadget->SelectImage(1,true);
 return true;
}

bool
Tec3270App::UpdateTermNetname()
{
 //
 ALFFMDIChild*  activeChild = (ALFFMDIChild*) mdiClient->GetActiveMDIChild();
 if ( (activeChild!= NULL) && (activeChild->GetTelnetPtr()) )
  {
   char* text = activeChild->GetTelnetPtr()->GetTerminalNetname();
   if ((text == NULL) || (strlen(text) == 0))
     tNetName->SetText(" ");
   else tNetName->SetText(text);
  }
 else tNetName->SetText(" ");
 return true;
}

bool
Tec3270App::UpdatePrtGadget()
{
 //prtGadget;
 ALFFMDIChild*  activeChild = (ALFFMDIChild*) mdiClient->GetActiveMDIChild();
 if ((activeChild!= NULL) && (activeChild->GetRemotePrinter()) )
  {
   if ( (activeChild->GetRemotePrinter()->IsConnected())
      || (activeChild->GetRemotePrinter()->IsSSLConnected()) )
     prtGadget->SelectImage(0,true);
   else prtGadget->SelectImage(1,true);
  }
 else prtGadget->SelectImage(2,true);
 return true;
}

bool
Tec3270App::UpdatePrtNetname()
{
 ALFFMDIChild*  activeChild = (ALFFMDIChild*) mdiClient->GetActiveMDIChild();
 if ( (activeChild!= NULL) && (activeChild->GetRemotePrinter()) )
  {
   if ( (activeChild->GetRemotePrinter()->IsConnected() )
      || (activeChild->GetRemotePrinter()->IsSSLConnected()) )
    {
     char* text = activeChild->GetRemotePrinter()->GetTelnetPtr()->GetPrinterNetname();
     if ((text == NULL) || (strlen(text) == 0))
       pNetName->SetText(" ");
     else pNetName->SetText(text);
    }
   else pNetName->SetText(" ");
  }
 else pNetName->SetText(" ");
 return true;
}

TMDIClient*
Tec3270App::GetMDIClient()
{
 return mdiClient;
}

ALFFIniFile*
Tec3270App::GetIniFile()
{
 return iniFile;
}

ALFFHelp*
Tec3270App::GetHelpFile()
{
 if (!HelpState)
  {
   helpFile = new ALFFHelp(appWindow, IDH_HELPFILENAME);
   HelpState = true;
  }
 return helpFile;
}

TSize
Tec3270App::GetFullScreenSize()
{
 return
 TSize(GetSystemMetrics(SM_CXFULLSCREEN),GetSystemMetrics(SM_CYFULLSCREEN));
}

void
Tec3270App::SetAppFont(LOGFONT logFont, bool wSizing, bool fSizing)
{
 TScreenDC dc;
 if (scrFont)
  delete scrFont;
 strcpy(scrFontName, logFont.lfFaceName);
 scrFontSize = MulDiv(-logFont.lfHeight,72,dc.GetDeviceCaps(LOGPIXELSY));
 SetFontCharWidth(logFont.lfWidth);
 SetFontCharHeight(-logFont.lfHeight);
 scrFontWeight  = logFont.lfWeight;
 scrFontItalic  = logFont.lfItalic;
 scrFontCharset = logFont.lfCharSet;
 scrFont = new TFont(&logFont);
 windowSizing = wSizing;
 fontSizing   = fSizing;
}

TFont*
Tec3270App::GetAppFont()
{
 return scrFont;
}

void
Tec3270App::SetPrtFont(LOGFONT logFont)
{
 TScreenDC pdc;
 if (prtFont)
	  delete prtFont;
 strcpy(prtFontName, logFont.lfFaceName);
 prtFontSize = MulDiv(-logFont.lfHeight,72,pdc.GetDeviceCaps(LOGPIXELSY));
 prtFontWeight = logFont.lfWeight;
 prtFontItalic = logFont.lfItalic;
 prtFontCharset = logFont.lfCharSet;
 int fontHeight  =
			-MulDiv(prtFontSize,pdc.GetDeviceCaps(LOGPIXELSY),72);
 prtFont = new TFont(prtFontName,fontHeight,0,0,0,prtFontWeight,
							DEFAULT_PITCH|FF_DONTCARE,prtFontItalic,0,0,
							prtFontCharset);

}

TFont*
Tec3270App::GetPrtFont()
{
 return prtFont;
}

int
Tec3270App::GetFontCharWidth()
{
 return scrCharWidth;
}

void
Tec3270App::SetFontCharWidth(const int width)
{
 scrCharWidth = width;
}

int
Tec3270App::SizeFontCharWidth(const int scrLineSize)
{
/*
 * This method must have same formulas that is used
 * by Tec3270MainWindow::SetWindowCoordinates.
 * Do not alter it before examining those formulas
 * and guaranteeing that both are compatible between
 * themselves.
 */
 int XLimit, cWidth;
 TRect screenRect;
 if (SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect,0))
  { XLimit = (int)(screenRect.right-screenRect.left+1); }
 else
  { XLimit = GetSystemMetrics(SM_CXFULLSCREEN); }

 int XBorder = GetSystemMetrics(SM_CXSIZEFRAME);
 int X3DBorder =  GetSystemMetrics(SM_CXEDGE);

 cWidth = (XLimit-(XBorder*2)/*-X3DBorder*/) / scrLineSize;
 return cWidth;
}

int
Tec3270App::GetFontCharHeight()
{
 return scrCharHeight;
}

void
Tec3270App::SetFontCharHeight(const int height)
{
 scrCharHeight = height;
}

int
Tec3270App::SizeFontCharHeight(const int scrNumLines)
{
/*
 * This method must have same formulas that is used
 * by Tec3270MainWindow::SetWindowCoordinates.
 * Do not alter it before examining those formulas
 * and guaranteeing that both are compatible between
 * themselves.
 */
 int YLimit, cHeight;
 TRect screenRect;
 if (SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect,0))
  { YLimit = (int)(screenRect.bottom-screenRect.top+1); }
 else { YLimit = GetSystemMetrics(SM_CYFULLSCREEN); }

 int YCaption = GetSystemMetrics(SM_CYCAPTION);
 int YBorder   = GetSystemMetrics(SM_CYSIZEFRAME);
 int Y3DBorder    = GetSystemMetrics(SM_CYEDGE);
 int YMenuBut = GetSystemMetrics(SM_CYMENUSIZE) + (YBorder*2);
 int YMenu   = GetSystemMetrics(SM_CYMENU) + YBorder;
 int YStatBar = GetStatusBar()->Attr.H + YBorder;

 cHeight = (YLimit-
           (YBorder*2+YCaption+YMenu+YMenuBut+YStatBar+Y3DBorder))/scrNumLines;
 return cHeight;
}

int
Tec3270App::GetFontSize()
{
 return scrFontSize;
}

int
Tec3270App::GetTermLineSize()
{
 return termLineSize;
}

void
Tec3270App::SetTermLineSize(const int lSize)
{
 termLineSize = lSize;
}

int
Tec3270App::GetTermNumLines()
{
 return termNumLines;
}

void
Tec3270App::SetTermNumLines(const int nLines)
{
 termNumLines = nLines;
}

bool
Tec3270App::IsValidIniFile(char* fileName, char* iniFileName)
{
 ALFFDiskObject diskObj;
 if (diskObj.FileExists (fileName))
  {
   string strFileName = fileName;
   diskObj.QualifyFile (strFileName);
   strcpy (iniFileName, strFileName.c_str());
   return true;
  }
 else return false;
}

void
Tec3270App::MakeIniFileName(char* fileName)
{
 /*
  * MakeFileName takes the executable path & name and then
  * removes the name.
  * It then appends the ini file name.
  */
  char *   namePtr;  /* working pointer to scan the
							 string from the end */
  int     fileNameLen;
  /* Get the executable path and name */
  fileNameLen = GetModuleFileName(fileName,EXE_NAME_MAX_SIZE);
  /* point to end of the string */
  namePtr = fileName + fileNameLen; // pointer arithmetic
  /*
	* While not at start of string
	*/
  while (namePtr > fileName)
	{
	 /*
	  * If not a directory symbol
	  * NB \ is a special character in C++ strings
	  * so need to use \\ to represent it
	  * Might be in root directory - make sure
	  * we don't trip over that either
	  */
	  if (*namePtr == '\\' || *namePtr == ':')
		{
		  /*
			* Found the first divider
			* skip back past it
			*/
		  namePtr++;
		  /*
			* terminate the string after that symbol
			*/
		  namePtr[0] = '\0';
		  break;
		}
	  fileNameLen--; /* will use this soon    */
	  namePtr--;     /* didn't find the  "\",
							  try the previous char */
	}
  if ((fileNameLen+13) < EXE_NAME_MAX_SIZE)
	{
		 /* Append the ini file name */
		  strcat(fileName, INIFILENAME);
	}
	else
	  /*
		* Something silly happened. Ran out of space for
		* the file name. Can't take any sensible action,
		* therefore give up with an exception...
		*/
		throw ALFFException("Tec3270 - Unable to format INI file");
  return;
}

void Tec3270App::SetupSpeedBar (Tec3270MainWindow *appWindow)
{
	 //
	 // Create default toolbar New and associate toolbar buttons with
	 // commands.
	 //
	 TControlBar* cb = new TControlBar(appWindow);
	 cb->Insert(*new TButtonGadget(CM_NEWSESSION, CM_NEWSESSION));
	 cb->Insert(*new TButtonGadget(CM_CLOSESESSION, CM_CLOSESESSION));
	 cb->Insert(*new TSeparatorGadget(6));
	 cb->Insert(*new TButtonGadget(CM_ALFFEDITCUT, CM_ALFFEDITCUT));
	 cb->Insert(*new TButtonGadget(CM_ALFFEDITCOPY, CM_ALFFEDITCOPY));
	 cb->Insert(*new TButtonGadget(CM_ALFFEDITPASTE, CM_ALFFEDITPASTE));
	 cb->Insert(*new TSeparatorGadget(6));
	 cb->Insert(*new TButtonGadget(CM_ALFFEDITUNDO, CM_ALFFEDITUNDO));
	 cb->Insert(*new TSeparatorGadget(6));
	 cb->Insert(*new TButtonGadget(CM_ALFFEDITFIND, CM_ALFFEDITFIND));
	 cb->Insert(*new TButtonGadget(CM_ALFFEDITREPLACE, CM_ALFFEDITREPLACE));
	 cb->Insert(*new TButtonGadget(CM_ALFFEDITFINDNEXT, CM_ALFFEDITFINDNEXT));
	 cb->Insert(*new TSeparatorGadget(6));
	 cb->Insert(*new TButtonGadget(CM_TILECHILDRENHORIZ, CM_TILECHILDRENHORIZ));
	 cb->Insert(*new TButtonGadget(CM_TILECHILDREN, CM_TILECHILDREN));
	 cb->Insert(*new TSeparatorGadget(6));
	 cb->Insert(*new TButtonGadget(CM_ALFFPRINT, CM_ALFFPRINT));
	 cb->Insert(*new TButtonGadget(CM_ALFFPRINTPREVIEW, CM_ALFFPRINTPREVIEW));
	 cb->Insert(*new TSeparatorGadget(6));
	 cb->Insert(*new TButtonGadget(CM_HELPCONTENTS, CM_HELPCONTENTS));

	 // Add fly-over help hints.
	 cb->SetHintMode(TGadgetWindow::EnterHints);
	 appWindow->Insert(*cb, TDecoratedFrame::Top);
}


//////////////////////////////////////////////////////////
// Tec3270 Main Window Bars Updating
//
void
Tec3270App::ReSizeStatusBar()
{
 SetupStatusBar(sb, true);  // Redraw status bar
 UpdateSSLLock();
 UpdateTN3270();
 UpdateTermGadget();
 UpdateTermNetname();
 UpdatePrtGadget();
 UpdatePrtNetname();
}

void
Tec3270App::SetBaseWinWidth(int width)
{
 baseWinWidth = width;
}
//////////////////////////////////////////////////////////
// Tec3270 Status Bar Creating / Updating
//
void
Tec3270App::SetupStatusBar(ALFFStatusBar* sb, bool updateBar)
{
 if (sb == NULL)
   return;

 if (updateBar)
  {
    // Remove all gadgets from status bar
    sb->Remove(*pDateTime);
    sb->Remove(*pINSERTKEY);
    sb->Remove(*pCAPSLOCK);
    sb->Remove(*pNUMLOCK);
    sb->Remove(*sslLocker);
    sb->Remove(*tn3270TXT);
    sb->Remove(*pNetName);
    sb->Remove(*prtGadget);
    sb->Remove(*tNetName);
    sb->Remove(*termGadget);
    sb->Remove(*termSeparator);
    sb->Remove(*prtSeparator);
    sb->Remove(*padSeparator);
    sb->Remove(*modeSeparator);
    sb->Remove(*timeSeparator);
    sb->LayoutSession();

    // delete all gadgets
    delete sslLocker;
    delete tn3270TXT;
    delete termGadget;
    delete tNetName;
    delete prtGadget;
    delete pNetName;
    delete pDateTime;
    delete pNUMLOCK;
    delete pCAPSLOCK;
    delete pINSERTKEY;
    delete termSeparator;
    delete prtSeparator;
    delete padSeparator;
    delete modeSeparator;
    delete timeSeparator;
  }

 /*
  *  Status Bar is layed out to fit Tec3270 Window on 800x600 pixels video
  *   configuration.  "baseSize" is based in the screen width (800).
  *  When screen configurations different from that are choosed the "baseSize"
  *   is adjusted proporcionally.
  */
 int screenSize = GetSystemMetrics(SM_CXSCREEN);
 int baseSize = (16*screenSize)/800;
 int curWinWidth = (appWindow->GetWindowRect().Width())*800/screenSize;

 int textSize = baseSize / 5;
 // Status Bar Font Height must be the same of icons height because it is
 // the bar height limiter
 int barFontHeight = 16;
 int barFontWidth  = (baseSize/4)+1;
 int barFontTimeWidth  = barFontWidth+1; //+(baseSize/8)-1;
 int barFontModeWidth  = barFontWidth+1; //+(baseSize/8)-1;
 int barSeparatorSize  = (baseSize/3);
 int numSeparators     = 1 + 1 + 6 + 6 + 10;  // These are the TGadgetSeparators sizes
 if (curWinWidth > baseWinWidth)
  {
    int adjust = curWinWidth-baseWinWidth+1;
    adjust  =  (adjust/numSeparators);
    barSeparatorSize += adjust;   //*screenSize/800;
  }

 // SSL Padlocker
 sslLocker =  new ALFFBitmapGadget(
                     appWindow, IDG_ALFFSSLLOCK,
                     IDB_ALFFSSLLOCK,
                     IDG_ALFFSSLLOCK,
                     TGadget::Recessed,
                     2,1);
 // TN3270 or TN3270E Indicator Gadget
 COLORREF  txtColor = RGB(0,0,255);
 tn3270TXT = new ALFFTextGadget(	IDG_ALFFTN3270,
            					     	ALFFGadget::Recessed,
                             		ALFFTextGadget::Center, textSize, NULL,
                             		new TFont("Arial",barFontHeight, barFontWidth),
                             		NULL,
                                 &txtColor);

 // Terminal in TN3270E Connection Indicator
 termGadget =  new ALFFBitmapGadget(
                     appWindow, IDG_ALFFTERMINAL,
                     IDB_ALFFTERMINAL,
                     IDG_ALFFTERMINAL,
                     TGadget::Recessed,
                     2,1);
 
 // Terminal in 3270E Connection Netname
 tNetName = new ALFFTextGadget(IDG_ALFFTERMINALNAME,
 										 ALFFTextGadget::Recessed,
                     	       ALFFTextGadget::Center, textSize, NULL,
                        	    new TFont("Arial",barFontHeight,barFontWidth),
                               NULL,
                               &txtColor);

 // Printer in TN3270E Connection Indicator
 prtGadget =  new ALFFBitmapGadget(
                     appWindow, IDG_ALFFPRINTER,
                     IDB_ALFFPRINTER,
                     IDG_ALFFPRINTER,
                     TGadget::Recessed,
                     3,2);

 // Printer in 3270E Connection Netname
 pNetName = new ALFFTextGadget(IDG_ALFFPRINTERNAME,
                    	      	 ALFFTextGadget::Recessed,
                     	       ALFFTextGadget::Center, textSize, NULL,
                        	    new TFont("Arial",barFontHeight,barFontWidth),
                               NULL,
                               &txtColor);

 // Date And Time Gadget
 pDateTime = new TTimeGadget(&TTimeGadget::GetLocalTime,
                             0,
                             TGadget::Recessed,
                             TTextGadget::Center, 4, NULL,
                             new TFont("Arial",barFontHeight, barFontTimeWidth));
 // Mode Status Controls
 COLORREF  modeColor = RGB(255,0,0);
 pNUMLOCK  =  new ALFFModeGadget(VK_NUMLOCK, "NUM", 0,
                              ALFFGadget::Recessed,
                              ALFFTextGadget::Center,
                              new TFont("Arial",barFontHeight,barFontModeWidth,0,0,FW_BOLD),
                              &modeColor);
 pCAPSLOCK =  new ALFFModeGadget(VK_CAPITAL, "CAPS", 0,
                              ALFFGadget::Recessed,
                              ALFFTextGadget::Center,
                              new TFont("Arial",barFontHeight,barFontModeWidth,0,0,FW_BOLD),
                              &modeColor);
/* INSert Key Gadget cannot be an ALFFModeGadget as this class intercept INSERT key independently
 * from main Tec3270 program an we lost control of its state. Instead of it now we use ALFFTextGadget
 * and set it from Tec3270 any time INSert key is pressed without any other key pressed.
 * Changed on Aug,18 2006 at 12:15h by Alcindo. This will be available from 3.2.4 version.
 pINSERTKEY = new ALFFModeGadget(VK_INSERT, "INS", 0,
                              ALFFGadget::Recessed,
                              ALFFTextGadget::Center,
                              new TFont("Arial",barFontHeight,barFontModeWidth,0,0,FW_BOLD),
                              &modeColor);
*/
 COLORREF insTxtColor = RGB(255,0,0);
 pINSERTKEY = new ALFFTextGadget(IDG_ALFFINSERTMODE,
                    	      	 ALFFTextGadget::Recessed,
                     	       ALFFTextGadget::Center, 1, "INS",
                        	    new TFont("Arial",barFontHeight,barFontWidth,0,0,FW_BOLD),
                               NULL,
                               &insTxtColor);
 pINSERTKEY->SetEnabled(false);                               

 // Separators
 termSeparator = new TSeparatorGadget(barSeparatorSize);
 termSeparator->SetShrinkWrap(false, true);

 prtSeparator = new TSeparatorGadget(barSeparatorSize);
 prtSeparator->SetShrinkWrap(false, true);

 padSeparator = new TSeparatorGadget(barSeparatorSize*6);
 padSeparator->SetShrinkWrap(false, true);

 modeSeparator = new TSeparatorGadget(barSeparatorSize*6);
 modeSeparator->SetShrinkWrap(false, true);

 timeSeparator = new TSeparatorGadget(barSeparatorSize*10);
 timeSeparator->SetShrinkWrap(false, true);

 // Insert all Tec3270 Bar Status Controls
 sb->Insert(*termGadget, ALFFStatusBar::Before);
 sb->Insert(*tNetName, ALFFStatusBar::After, termGadget);
 sb->Insert(*prtGadget, ALFFStatusBar::After, tNetName);

 sb->Insert(*termSeparator,ALFFStatusBar::After, tNetName);

 sb->Insert(*pNetName, ALFFStatusBar::After, prtGadget);
 sb->Insert(*tn3270TXT, ALFFStatusBar::After, pNetName);

 sb->Insert(*prtSeparator,ALFFStatusBar::After, pNetName);

 sb->Insert(*sslLocker,ALFFStatusBar::After, tn3270TXT);

 // Time and Date Control
 sb->Insert(*timeSeparator,ALFFStatusBar::After, sslLocker);
 sb->Insert(*pDateTime, ALFFStatusBar::After,sslLocker);

 // Space before special keys status controls
 sb->Insert(*padSeparator,ALFFStatusBar::After, sslLocker);

 // Keyboard special keys status Controls
 sb->Insert(*pNUMLOCK,  ALFFStatusBar::After, sslLocker);
 sb->Insert(*pCAPSLOCK, ALFFStatusBar::After, sslLocker);
 sb->Insert(*pINSERTKEY,ALFFStatusBar::After, sslLocker);

 // Space after special keys status controls
 sb->Insert(*modeSeparator, ALFFStatusBar::After, sslLocker);

 sb->SetShrinkWrap(true,true);

 sb->LayoutSession();
}

int
Tec3270App::Run()
{
 /* Checking previous instance of Tec3270 */
 HWND hwnd = ::FindWindow("Tec3270MainWindow", NULL);

 /////////   D E B U G   D E B U G   D E B U G    ////////////////////
 //          hwnd = NULL;                                           //
 /////////   D E B U G   D E B U G   D E B U G    ////////////////////

 if (hwnd)
  {
   // Advise User
   char msgOtherInstance[STRINGMSGLEN+1];
   ::LoadString(GetInstance(),IDS_TEC3270PREVINST,msgOtherInstance,STRINGMSGLEN);
   ::MessageBox(0, msgOtherInstance, "Tec3270", MB_OK | MB_ICONEXCLAMATION);

   // We found another version of ourself. Let's defer to it:
   if (IsIconic(hwnd))
      ::ShowWindow(hwnd, SW_RESTORE);

   ::SetForegroundWindow (hwnd);
   // If this app actually had any functionality, we would
   // also want to communicate any action that our "twin"
   // should now perform based on how the user tried to
   // execute us.
   appInited = false;
   return -1;
  }
 else
  {
   appInited = true;
   return TApplication::Run();
  }
}

void Tec3270App::InitInstance ()
{
 TApplication::InitInstance();
}

//////////////////////////////////////////////////////////
// Tec3270 Main Window Initialization
//
void
Tec3270App::InitMainWindow()
{
 /* Get Main Window Status When Last Time Tec3270 was executed */
 int maximized = iniFile->GetInt("POSITION","MAXIMIZED",0);
 if (maximized)
	 nCmdShow = SW_SHOWMAXIMIZED;

 if ((nCmdShow != SW_SHOWMAXIMIZED)
	&& (nCmdShow != SW_HIDE))
	nCmdShow = (nCmdShow != SW_SHOWMINNOACTIVE) ? SW_SHOWNORMAL : nCmdShow;

 mdiClient = new ALFFMDIClient(this);
 appWindow = new Tec3270MainWindow(Name, TEC3270_MENU, *mdiClient, true, this);

 // Set the client area to the application workspace color.
 appWindow->SetBkgndColor(::GetSysColor(COLOR_APPWORKSPACE));

  /* Assign ICON w/ this application. */
 appWindow->SetIcon(this, IDI_TEC3270);

 /* Assign mini-ICON w/ this application. */
 appWindow->SetIconSm(this, IDI_TEC3270);

 /*
  * Menu associated with window and accelerator table associated with table.
  * Initialize Main Menu  and  Trace Option Mark BitMap
  */
 TMenuDescr* theMenu = new TMenuDescr(TEC3270_MENU,1,0,1,1,0,1);

 /* Update Menu Trace Options*/
 if (theMenu)
  {
	theMenu->CheckMenuItem(CM_TRACESESSION,
								  (MF_BYCOMMAND | MF_UNCHECKED));
  }
 else MessageBox(0,"Menu Option TRACE Mark Not Set",
						 "Tec3270 Error",	MB_OK | MB_ICONEXCLAMATION);

 appWindow->SetMenuDescr(*theMenu);

 //
 // Associate with the accelerator table.
 //
 appWindow->Attr.AccelTable = TEC3270_MENU;

 SetupSpeedBar(appWindow);

 // Creating Tec3270 Status Bar
 sb = new ALFFStatusBar(appWindow,
                        TGadget::Recessed,
								0,
                        new TGadgetWindowFont(9,false));

 /////////////////////////////////////////////////////////////////////////////////////
 SetupStatusBar(sb, false);  // false = create Status Bar
 ////////////////////////////////////////////////////////////////////////////////////

 appWindow->Insert(*sb, TDecoratedFrame::Bottom);

 SetMainWindow(appWindow);

 /* Update Communications Cluster Main Window Pointer */
 alffCommCluster->SetMainWindow(appWindow);

 /*
  * Get This Computer Name and Address
  */
 pClusterInfo  = alffCommCluster->GetClusterInfo();
 pLocalName    = alffCommCluster->GetComputerName();
 pLocalAddress = alffCommCluster->GetComputerAddress();

 /* Windows 3-D controls. */
 EnableCtl3d(TRUE);

 /* Open Tec3270 Initial Window and Show Tec3270 BitMap */
 CmHelpAbout();
}

char*
Tec3270App::GetClusterInfo()
{
 pClusterInfo = alffCommCluster->GetClusterInfo();
 return pClusterInfo;
}

char*
Tec3270App::GetComputerName()
{
 if (!pLocalName)
    pLocalName = alffCommCluster->GetComputerName();
 return pLocalName;
}

char*
Tec3270App::GetComputerAddress()
{
 if (!pLocalAddress)
    pLocalAddress = alffCommCluster->GetComputerAddress();
 return pLocalAddress;
}

//////////////////////////////////////////////////////////
// Tec3270App
// ===========
// Menu Help Contents command
void Tec3270App::CmHelpContents ()
{
 //
 // Show the help table of contents.
 //
 GetHelpFile()->ShowHelp(HH_DISPLAY_TOC, 0L);
}

// Menu Help Using Help command
void Tec3270App::CmHelpUsing()
{
 //
 // Display the contents of the Windows help file.
 //
 GetHelpFile()->ShowHelp(HH_DISPLAY_INDEX, 0L);
}


// Menu Help Version Tec3270.exe command
void Tec3270App::CmHelpVersion ()
{
	 //
	 // Show the modal dialog.
	 //
	 Tec3270AboutDlg(MainWindow, IDD_ALFFABOUT).Execute();
}

// Menu Help About Tec3270.exe command
void Tec3270App::CmHelpAbout ()
{
 LPSTR pVersion = 0, pCopyright = 0;
 char prodVersion[255];
 char prodCopyRight[255];

 // Process the VERSIONINFO.
 ProjectRCVersion applVersion(this);

 // Get the product name and product version strings.
 if (applVersion.GetProductVersion(pVersion))
	wsprintf(prodVersion, "%s", pVersion);

 //Get the legal copyright string.
 if (applVersion.GetCopyright(pCopyright))
	wsprintf(prodCopyRight, "%s", pCopyright);

 /* Open Tec3270 Initial Window and Show Tec3270 BitMap */
 char versionDate[24] = {__DATE__};

#if (PORTUGUES == 1)
 char month[4];
 memcpy(&month[0],&versionDate[0],3);
 memset(&month[3],NULL,1);
 memcpy(&versionDate[0],&versionDate[4],2);
 memset(&versionDate[2],' ',1);
 if (!strcmp(month,"Feb"))
	strcpy(month,"Fev");
 else if (!strcmp(month,"Apr"))
	strcpy(month,"Abr");
 else if (!strcmp(month,"May"))
	strcpy(month,"Mai");
 else if (!strcmp(month,"Aug"))
	strcpy(month,"Ago");
 else if (!strcmp(month,"Sep"))
	strcpy(month,"Set");
 else if (!strcmp(month,"Oct"))
	strcpy(month,"Out");
 else if (!strcmp(month,"Dec"))
	strcpy(month,"Dez");
 memcpy (&versionDate[3],&month[0],3);
#elif (ENGLISH == 1)
 memset (&versionDate[6],',',1);
#endif
 OpenTec3270(appWindow,prodVersion,versionDate,prodCopyRight);
}

// Menu Help ShowWINSOCK Data
void
Tec3270App::CmGetCommClusterInfo ()
{
	alffCommCluster->GetCommClusterInfo();
}

// Menu Help GetComputerAddress

void
Tec3270App::CmGetComputerInfo()
{
	alffCommCluster->GetComputerCommInfo();
}

bool
Tec3270App::ProcessAppMsg (MSG& msg)
{
	 if (msg.message == WM_COMMAND)
	 {
		if ( (ContextHelp)
		  ||((::GetKeyState(VK_F1) < 0)
			  && (::GetKeyState(VK_CONTROL) < 0)) )
		 {
		  ContextHelp = false;
        ALFFHelp* helpFile = GetHelpFile();
        HWND helpWin = helpFile->ShowHelp(HH_HELP_CONTEXT, msg.wParam, IDH_POPUP_WINDOW);
        if (!helpWin)
          {
           ALFFMsgs pMsgs(appWindow);
           pMsgs.Message(IDS_ALFFHELPNOTAVAIL, IDS_TEC3270_HELP_ERR);
          }
		  return true;
		 }
	 }
	 else
		  switch (msg.message)
		  {
		  case WM_KEYDOWN:
				if (msg.wParam == VK_F1)   //Virtual Key//
				{
				 // If the Ctrl+Shift/F1 then set the help cursor and turn
				 // on the modal help state.
				 if ((::GetKeyState(VK_CONTROL) < 0)
					&&(::GetKeyState(VK_SHIFT) < 0) )
				  {
					ContextHelp = true;
					HelpCursor = ::LoadCursor(GetMainWindow()->GetModule()->
									  GetInstance(),MAKEINTRESOURCE(IDC_ALFFHELPCURSOR));
					::SetCursor(HelpCursor);
					return true;          //Gobble up the message//
				  }
				  else
				  {
					/* If F1 with Ctrl key then bring up help's main index. */
					if (::GetKeyState(VK_CONTROL) < 0)
					 {
                 GetHelpFile()->ShowHelp(HH_DISPLAY_TOC, 0L);
					  return true;        // Gobble up the message.
					 }
				  }
				}
				else
				{
				 if (ContextHelp && (msg.wParam == VK_ESCAPE))
				  {
					 if (HelpCursor)
						 ::DestroyCursor(HelpCursor);
					 ContextHelp = false;
					 HelpCursor = 0;
					 GetMainWindow()->SetCursor(0, IDC_ARROW);
					 return true;    // Gobble up the message.
					}
				}
				break;

		  case WM_MOUSEMOVE:
		  case WM_NCMOUSEMOVE:
				if (ContextHelp)
				 {
					::SetCursor(HelpCursor);
					return true;        // Gobble up the message.
				 }
				break;

		  case WM_INITMENU:
				if (ContextHelp)
				{
				 ::SetCursor(HelpCursor);
				 return true;        // Gobble up the message.
				}
				break;

		  case WM_ENTERIDLE:
				if (msg.wParam == MSGF_MENU)
					 if (GetKeyState(VK_F1) < 0)
					 {
						ContextHelp = true;
						GetMainWindow()->PostMessage(WM_KEYDOWN, VK_RETURN, 0L);
						return true;       // Gobble up the message.
					 }
				break;

		  default:
				;
		  };  // End of switch

	 // Continue normal processing.

	 bool rcProcessAppMsg = TApplication::ProcessAppMsg(msg);
    return rcProcessAppMsg;
}

void
Tec3270App::EvWinIniChange (char far* section)
{
	 if (strcmp(section, "windows") == 0) {
		  // If the device changed in the WIN.INI file then the printer
		  // might have changed.  If we have a TPrinter (Printer) then
		  // check and make sure it's identical to the current device
		  // entry in WIN.INI.
		  if (Printer) {
				char printDBuffer[255];
				LPSTR printDevice = printDBuffer;
				LPSTR devName;
				LPSTR driverName = 0;
				LPSTR outputName = 0;

				if (::GetProfileString("windows", "device", "", printDevice, sizeof(printDevice))) {
					 // The string which should come back is something like:
					 //
					 //      HP LaserJet III,hppcl5a,LPT1:
					 //
					 // Where the format is:
					 //
					 //      devName,driverName,outputName
					 //
					 devName = printDevice;
					 while (*printDevice) {
						  if (*printDevice == ',') {
								*printDevice++ = 0;
								if (!driverName)
									 driverName = printDevice;
								else
									 outputName = printDevice;
						  } else
								printDevice = ::AnsiNext(printDevice);
					 }

					 if ((Printer->GetSetup().Error != 0)                               ||
						  (strcmp(devName, Printer->GetSetup().GetDeviceName()) != 0)    ||
						  (strcmp(driverName, Printer->GetSetup().GetDriverName()) != 0) ||
						  (strcmp(outputName, Printer->GetSetup().GetOutputName()) != 0)) {

						  // New printer installed so get the new printer device now.
						  delete Printer;
						  Printer = new ALFFPrinter(this);
					 }
				} else {
					 // No printer installed (GetProfileString failed).
					 delete Printer;
					 Printer = new ALFFPrinter(this);
				}
		  }
	 }
}

bool
Tec3270App::OpenTec3270(TWindow* parent, char* appVer, char* verDate,
                                         char* cpRight)
{
 Tec3270Open* aboutTec3270 = new Tec3270Open(parent, appVer, verDate, cpRight);
 aboutTec3270->Execute();
 delete aboutTec3270;
 return TRUE;
}

//int  OwlMain(int argc, char* argv[])
int OwlMain (int argc , char* argv[])
{
#ifdef STACKINFO
 // DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
	char buf[128];
	sprintf(buf,"\nStack Available: %u", stackavail());
	strcat(buf,"  <Program Begin>");
	MessageBox(0,buf,"Stack Info",MB_OK);
 // DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
#endif
	 try {
        if (argc >= 2)
         {
          Tec3270App app(argv[1]); // Use provided ini FileName
          return app.Run();
         }
        else
         {
          Tec3270App app;  // Use default ini FileName
          return app.Run();
         }
	 }
    catch (ALFFException e) {
         string errorMsg = TXOwl::MakeMessage(e.ResId,"");
    		::MessageBox(0, errorMsg.c_str(),
#if (ENGLISH == 1)
							"Tec3270: Controlled Exception",
#elif (PORTUGUES == 1)
							"Tec3270: Exceção de Programa",
#else
                     "Invalid Locale"
#endif                     
							MB_OK);
   	  }

	 return -1;
}
