// -*- C++ -*- generated by wxGlade 0.6.3 on Tue Mar 10 11:02:18 2009
/*
  Copyright 2009 Ronald S. Burkey <info@sandroid.org>

  This file is part of yaAGC.

  yaAGC is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  yaAGC is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with yaAGC; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  Filename:	yaTelemetry.cpp
  Purpose:	A program to display telemetry-downlink info from AGC.
  Compiler:	GNU gcc.
  Reference:	http://www.ibibio.org/apollo
  Mode:		2009-03-09 RSB.	Began.
  		2009-03-13 RSB	Added --simple.
		2009-03-14 RSB	Use smaller default font sizes when the --simple
				switch is used.  Work around a funky socket 
				error which appears in Windows.
  
  The program does nothing more than connect to yaAGC on a socket, and then
  display any telemetry messages it receives.  There is a single active widget,
  which is a text control.  A periodically-executing event handler fetches
  data from the socket, formats it properly, and sticks it into the text-control.
  The text control is read-only, meaning that the user can't type anything into
  it.  The text control is sized to have 80 columns and 43 rows, since this is
  the same as the size of the xterm which was previously used to display the 
  downlink data when yaDSKY processed it before yaTelemetry was created.
  
  Anyone who knows C++ will notice, I'm sure, that I duplicate a lot of functions
  between MainFrameClass and SimpleFrameClass that I should have just handled
  through inheritance.  If anyone wants to fix it up for me, that would be swell,
  though it might goof up maintenance of the classes via wxGlade.
*/

#include "yaTelemetry.h"
#include "../yaAGC/yaAGC.h"
#include "../yaAGC/agc_engine.h"

MainFrameClass *MainFrame;
SimpleFrameClass *SimpleFrame;

#include <cstdlib>
#include <stdio.h>
#include <errno.h>
#include <iostream>

using namespace std;

#define PULSE_INTERVAL 100
static char DefaultHostname[] = "localhost";
char *Hostname = DefaultHostname;
static char NonDefaultHostname[129];
#ifdef WIN32
static int StartupDelay = 500;
#else
static int StartupDelay = 0;
#endif
#if defined (WIN32)
#define DEFAULT_FONTSIZE_RESIZABLE 8
#define DEFAULT_FONTSIZE_RETRO 9
#elif defined (__APPLE__)
#define DEFAULT_FONTSIZE_RESIZABLE 10
#define DEFAULT_FONTSIZE_RETRO 14
#else
#define DEFAULT_FONTSIZE_RESIZABLE 8
#define DEFAULT_FONTSIZE_RETRO 11
#endif
static int Points = DEFAULT_FONTSIZE_RETRO;
static bool Simple = false;


// Clears the output text control.  The reason we use this instead of the 
// text-control's native Clear function is that we want the text control
// to always contain exactly TELEMETRY_ROWS x TELEMETRY_COLUMNS worth of 
// stuff, even if that stuff is blank spaces.  This makes it easier for us
// to read and write to random locations, since the writing can always be
// replacement of existing text.  We expect this function to be called only
// at startup, or when the downlink mode changes, so we don't bother to
// optimize it for speed.
void
MainFrameClass::ClearScreen (void)
{
  wxString EmptyScreen;
  wxTextAttr Style;
  wxColor TextColor;
  int i, j;
  for (i = 0; i < TELEMETRY_ROWS; i++)
    {
      if (i > 0)
        EmptyScreen += wxT ("\n");
      for (j = 0; j < TELEMETRY_COLUMNS; j++)
        EmptyScreen += wxT (" ");
    }
  Style = TextCtrl->GetDefaultStyle ();
#ifdef __APPLE__
  // On the Mac, the background color of the text control does not come out
  // right --- it's always white, no matter what I do.  It also has a 
  // (disabled) scrollbar no matter what I do.  I've expended more time on
  // it than it's worth to me, so on the Mac I simply eliminate the decorative
  // border into which the text control (which is supposed to be black) is
  // supposed to blend, and choose a text color that shows up okay on the 
  // (wrong) white background.
  TextColor.Set (0x000000UL);
#else
  TextColor.Set (0xc0c0c0UL);
#endif
  Style.SetTextColour (TextColor);
  TextCtrl->SetDefaultStyle (Style);
  TextCtrl->Clear ();
  TextCtrl->FitInside ();
  TextCtrl->ChangeValue (EmptyScreen);
}

// Print to screen at coordinates x,y.  Clipping is performed, but
// not wrapping.  In other words, any call to Print() will go on
// a single line.  Don't try to defeat it by putting in newlines,
// as this will just mess up the rationale by which the screen is
// being managed.

void 
MainFrameClass::Print (int x, int y, wxString &Value)
{
  int From, To, Length, xend;
  // Sanity checking.  Abort if the string will be completely
  // off the screen.  The usual case is that everthing will be
  // fine and on-screen, so we do a quick check for that case.
  if (y < 0 || y >= TELEMETRY_ROWS)
    return;
  Length = Value.Length ();
  xend = x + Length;
  if (x < 0 || xend > TELEMETRY_COLUMNS)
    {
      // Perhaps it's completely off-screen!
      if (xend <= 0 || x >= TELEMETRY_COLUMNS)
	return;
      // No, at least partially on-screen.
      if (xend > TELEMETRY_COLUMNS)
        {
	  Length -= (xend - TELEMETRY_COLUMNS);
	  Value = Value.Left (Length);
	}
      if (x < 0)
        {
	  Length += x;
	  Value = Value.Right (Length);
	}
    }
  // All checked and/or clipped.  Output it.
  From = TextCtrl->XYToPosition (x, y);
  To = From + Length;
  TextCtrl->Replace (From, To, Value);
}

// Set font-size in the text control.
void 
MainFrameClass::FontSize (int Points)
{
  TextCtrl->SetFont(wxFont(Points, wxMODERN, wxNORMAL, wxNORMAL, 0, wxT("")));
}

// Remove frame decorations.
void
MainFrameClass::Undecorate (void)
{
    delete bitmap_1;
    delete bitmap_5;
    delete bitmap_3;
    delete bitmap_2;
    bitmap_1 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxT("tTelemetryLeft.jpg"), wxBITMAP_TYPE_ANY));
    bitmap_5 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxT("tTelemetryTop.jpg"), wxBITMAP_TYPE_ANY));
    bitmap_3 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxT("tTelemetryBottom.jpg"), wxBITMAP_TYPE_ANY));
    bitmap_2 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxT("tTelemetryRight.jpg"), wxBITMAP_TYPE_ANY));
    do_layout();
}

// Clears the output text control.  The reason we use this instead of the 
// text-control's native Clear function is that we want the text control
// to always contain exactly TELEMETRY_ROWS x TELEMETRY_COLUMNS worth of 
// stuff, even if that stuff is blank spaces.  This makes it easier for us
// to read and write to random locations, since the writing can always be
// replacement of existing text.  We expect this function to be called only
// at startup, or when the downlink mode changes, so we don't bother to
// optimize it for speed.
void
SimpleFrameClass::ClearScreen (void)
{
  wxString EmptyScreen;
  //wxTextAttr Style;
  wxColor TextColor;
  int i, j;
  for (i = 0; i < TELEMETRY_ROWS; i++)
    {
      if (i > 0)
        EmptyScreen += wxT ("\n");
      for (j = 0; j < TELEMETRY_COLUMNS; j++)
        EmptyScreen += wxT (" ");
    }
  //Style = TextCtrl->GetDefaultStyle ();
  //TextColor.Set (0x000000UL);
  //Style.SetTextColour (TextColor);
  //TextCtrl->SetDefaultStyle (Style);
  //TextCtrl->Clear ();
  //TextCtrl->FitInside ();
  TextCtrl->SetLabel (EmptyScreen);
  //TextCtrl->Fit ();
  Fit ();
}

#if 0
// Print to screen at coordinates x,y.  Clipping is performed, but
// not wrapping.  In other words, any call to Print() will go on
// a single line.  Don't try to defeat it by putting in newlines,
// as this will just mess up the rationale by which the screen is
// being managed.

void 
SimpleFrameClass::Print (int x, int y, wxString &Value)
{
  int From, To, Length, xend;
  // Sanity checking.  Abort if the string will be completely
  // off the screen.  The usual case is that everthing will be
  // fine and on-screen, so we do a quick check for that case.
  if (y < 0 || y >= TELEMETRY_ROWS)
    return;
  Length = Value.Length ();
  xend = x + Length;
  if (x < 0 || xend > TELEMETRY_COLUMNS)
    {
      // Perhaps it's completely off-screen!
      if (xend <= 0 || x >= TELEMETRY_COLUMNS)
	return;
      // No, at least partially on-screen.
      if (xend > TELEMETRY_COLUMNS)
        {
	  Length -= (xend - TELEMETRY_COLUMNS);
	  Value = Value.Left (Length);
	}
      if (x < 0)
        {
	  Length += x;
	  Value = Value.Right (Length);
	}
    }
  // All checked and/or clipped.  Output it.
  From = TextCtrl->XYToPosition (x, y);
  To = From + Length;
  TextCtrl->Replace (From, To, Value);
}
#endif

// Set font-size in the text control.
void 
SimpleFrameClass::FontSize (int Points)
{
  TextCtrl->SetFont(wxFont(Points, wxMODERN, wxNORMAL, wxNORMAL, 0, wxT("")));
}

void
SwriteTelemetry (void)
{
  int i;
  wxString Dummy;
  for (i = 0; i < Sheight; i++)
    {
      Dummy = wxString::FromAscii (Sbuffer[i]);
      MainFrame->Print (0, i, Dummy);
    }
}

void
SwriteTelemetrySimple (void)
{
  int i;
  wxString Dummy;
  for (i = 0; i < Sheight; i++)
    {
      if (i > 0)
        Dummy += wxT ("\n");
      Dummy += wxString::FromAscii (Sbuffer[i]);
    }
  SimpleFrame->TextCtrl->SetLabel (Dummy);
}

// This is the event handler for the background timer.  The background timer
// executes about every 100 ms. and services the socket interface.  Upon 
// receiving downlink data, it updates the output screen.

void 
TimerClass::Notify ()
{
#ifdef DEBUG
  static int Count = 0;
  int j;
  wxString Dummy;
  j = Count % TELEMETRY_ROWS;
  Dummy = wxT ("Hello #");
  Dummy << Count++;
  MainFrame->Print (2 * j, j, Dummy);
#endif

  static int ServerSocket = -1;
  static unsigned char Packet[4];
  static int PacketSize = 0;
  int i;
  unsigned char c;
  if (StartupDelay > 0)
    {
      StartupDelay -= PULSE_INTERVAL;
      return;
    }
  // Try to connect to the server (yaAGC) if not already connected.
  if (ServerSocket == -1)
    {
      ServerSocket = CallSocket (Hostname, Portnum);
      if (ServerSocket != -1)
        printf ("yaTelemetry is connected.\n");
    }
  if (ServerSocket != -1)
    {
      for (;;)
        {
	  i = recv (ServerSocket, (char *) &c, 1, MSG_NOSIGNAL);
	  if (i == -1)
	    {
	      // The conditions i==-1,errno==0 or 9 occur only on Win32,
	      // and I'm not sure exactly what they corresponds to---but
	      // empirically I find that ignoring them makes no difference
	      // to the operation of the program.
	      if (errno == EAGAIN || errno == 0 || errno == 9)
	        i = 0;
	      else
	        {	
		  //wxString Dummy;
		  //Dummy << wxT ("yaTelemetry reports server error ") << errno;
		  //wxMessageBox (Dummy);
		  printf ("yaTerminal reports server error %d\n", errno);
		  close (ServerSocket);
		  ServerSocket = -1;
		  break;
	        }
	    }
	  if (i == 0)
	    break;
	  if (0 == (0xc0 & c))
	    PacketSize = 0;
	  if (PacketSize != 0 || (0xc0 & c) == 0)	      
	    { 
	      Packet[PacketSize++] = c;
	      if (PacketSize >= 4)
		{
		  ActOnIncomingIO (Packet);
		  PacketSize = 0;   
		}  
	    }
	}
    }
}

void
TimerClass::ActOnIncomingIO (unsigned char *Packet)
{
  int Channel, Value, uBit;
  // Check to see if the message has a yaAGC signature.  If not,
  // ignore it.  The yaAGC signature is 00 01 10 11 in the 
  // 2 most-significant bits of the packet's bytes.  We are 
  // guaranteed that the first byte is signed 00, so we don't 
  // need to check it.
  if (0x40 != (Packet[1] & 0xc0) ||
      0x80 != (Packet[2] & 0xc0) ||
      0xc0 != (Packet[3] & 0xc0))
    return;
  if (ParseIoPacket (Packet, &Channel, &Value, &uBit))
    goto Error;
  // Decode the digital downlink data.  
  if (Channel == 013 || Channel == 034 || Channel == 035)
    DecodeDigitalDownlink (Channel, Value, CmOrLm);
  return;
Error:
  IoErrorCount++;
}



///////////////////////////////////////////////////////////////////////////////
// The stuff below this line was created by wxGlade, and could conceivably be
// modified by wxGlade in the future.  So try to confine useful code to the 
// area above this line, to the extent feasible.

// begin wxGlade: ::extracode
// end wxGlade



MainFrameClass::MainFrameClass(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
    wxFrame(parent, id, title, pos, size, wxCAPTION|wxCLOSE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU)
{
    // begin wxGlade: MainFrameClass::MainFrameClass
    bitmap_1 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxT("TelemetryLeft.jpg"), wxBITMAP_TYPE_ANY));
    bitmap_5 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxT("TelemetryTop.jpg"), wxBITMAP_TYPE_ANY));
    TextCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH|wxNO_BORDER);
    bitmap_3 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxT("TelemetryBottom.jpg"), wxBITMAP_TYPE_ANY));
    bitmap_2 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxT("TelemetryRight.jpg"), wxBITMAP_TYPE_ANY));

    set_properties();
    do_layout();
    // end wxGlade
}

BEGIN_EVENT_TABLE(MainFrameClass, wxFrame)
// content of this block not found: did you rename this class?
    EVT_CLOSE(MainFrameClass::TimerStop)
END_EVENT_TABLE();

void MainFrameClass::set_properties()
{
    // begin wxGlade: MainFrameClass::set_properties
    SetTitle(wxT("yaTelemetry by Ron Burkey"));
    wxIcon _icon;
    _icon.CopyFromBitmap(wxBitmap(wxT("ApolloPatch2.png"), wxBITMAP_TYPE_ANY));
    SetIcon(_icon);
    SetBackgroundColour(wxColour(0, 0, 0));
    SetForegroundColour(wxColour(192, 192, 192));
    SetFocus();
    bitmap_1->SetBackgroundColour(wxColour(0, 0, 0));
    bitmap_5->SetBackgroundColour(wxColour(0, 0, 0));
    TextCtrl->SetBackgroundColour(wxColour(0, 0, 0));
    TextCtrl->SetForegroundColour(wxColour(192, 192, 192));
    TextCtrl->SetFont(wxFont(11, wxMODERN, wxNORMAL, wxNORMAL, 0, wxT("")));
    bitmap_3->SetBackgroundColour(wxColour(0, 0, 0));
    bitmap_2->SetBackgroundColour(wxColour(0, 0, 0));
    // end wxGlade
}


void MainFrameClass::do_layout()
{
    // begin wxGlade: MainFrameClass::do_layout
    wxBoxSizer* sizer_1 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* sizer_2 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_3 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* sizer_4 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_5 = new wxBoxSizer(wxVERTICAL);
    sizer_2->Add(bitmap_1, 0, 0, 0);
    sizer_3->Add(bitmap_5, 0, 0, 0);
    sizer_4->Add(15, 20, 0, 0, 0);
    sizer_5->Add(20, 30, 0, 0, 0);
    sizer_5->Add(TextCtrl, 1, wxEXPAND, 0);
    sizer_5->Add(20, 30, 0, 0, 0);
    sizer_4->Add(sizer_5, 1, wxEXPAND, 0);
    sizer_4->Add(15, 20, 0, 0, 0);
    sizer_3->Add(sizer_4, 1, wxEXPAND, 0);
    sizer_3->Add(bitmap_3, 0, 0, 0);
    sizer_2->Add(sizer_3, 1, wxEXPAND, 0);
    sizer_2->Add(bitmap_2, 0, 0, 0);
    sizer_1->Add(sizer_2, 1, wxEXPAND, 0);
    SetSizer(sizer_1);
    sizer_1->Fit(this);
    Layout();
    // end wxGlade
}


class yaTelemetryApp: public wxApp {
public:
    bool OnInit();
};

IMPLEMENT_APP(yaTelemetryApp)

static wxApp *App;

bool yaTelemetryApp::OnInit()
{
    App = this;
    wxInitAllImageHandlers();
    MainFrame = new MainFrameClass(NULL, wxID_ANY, wxEmptyString);
    SimpleFrame = new SimpleFrameClass (NULL, wxID_ANY, wxEmptyString);
    int i, Undecorated = 0, FontSizeSwitch = 0;
    
    printf ("\n");
    printf ("yaTelemetry build " __DATE__ " " __TIME__ ", Copyright 2009 Ronald Burkey\n");
    printf ("For more information, consult http://www.ibiblio.org/apollo.\n");
	    
    // Read the command-line arguments.
    Portnum = 19800;
    CmOrLm = 0;
    for (i = 1; i < argc; i++)
      {
        long IntValue;
        wxString Arg, Command, Value;
	Arg = argv[i];
	Command = Arg.BeforeFirst ('=');
	Value = Arg.AfterFirst ('=');
	if (!Value.ToLong (&IntValue))
	  IntValue = 0;
	if (Arg.IsSameAs (wxT ("--help")))
	  {
	  Help:
	    printf ("\n");
	    printf ("This program provides a terminal on which to view downlinked telemetry\n");
	    printf ("from the AGC, which is to say from a running yaAGC server.\n");
	    printf ("\n");
	    printf ("USAGE:\n");
	    printf ("     yaTelemetry [OPTIONS]\n");
	    printf ("\n");
	    printf ("The available options are:\n");
	    printf ("\n");
	    printf ("     --help          Displays this message.\n");
	    printf ("     --delay=MS      Provides a delay after startup before\n");
	    printf ("                     attempting to connect to the yaAGC server.\n");
	    printf ("                     This allows elimination of certain race\n");
	    printf ("                     conditions which can occur when starting up\n");
	    printf ("                     a bunch of Virtual AGC servers and clients\n");
	    printf ("                     using scripts.  MS is the delay time, in \n");
	    printf ("                     milliseconds.  It defaults to 500 in Windows\n");
	    printf ("                     and 0 otherwise.\n");
	    printf ("     --port=P        The port number on which to try and set up a\n");
	    printf ("                     socket to the listening yaAGC server.  By\n");
	    printf ("                     convention, the virtual CM uses ports 19697\n");
	    printf ("                     through 19706, whilst the virutal LM uses\n");
	    printf ("                     ports 19797-19806.  By default, yaTelemetry\n");
	    printf ("                     uses 19800.\n");
	    printf ("     --ip=H          The hostname or IP address of the yaAGC server\n");
	    printf ("                     to which yaTelemetry should connect.  The\n");
	    printf ("                     default is \"localhost\".\n");
	    printf ("     --spacecraft=S  The type of spacecraft, either LM or CM.  This\n");
	    printf ("                     defaults to LM.\n");
	    printf ("     --font-size=P   Font size, in points.  Defaults to %d on this\n", DEFAULT_FONTSIZE_RETRO);
	    printf ("                     platform for the default or --undecorated style,\n");
	    printf ("                     and to %d for the --simple style (see below).\n", DEFAULT_FONTSIZE_RESIZABLE);
	    printf ("                     Generally, for the default or --undecorated style,\n");
	    printf ("                     the size should be chosen as the maximum for which\n");
	    printf ("                     scrollbars do not appear.  For the --simple style,\n");
	    printf ("                     the minimum size for comfortable reading should be\n");
	    printf ("                     selected.\n");
	    printf ("     --undecorated   This option is not recommended; you should use\n");
	    printf ("                     --simple instead.  What this option does is to\n");
	    printf ("                     remove decorations (the fake console around the\n");
	    printf ("                     displayed data), in order to reduce amount of screen\n");
	    printf ("                     space occupied.  If the screen height is too\n");
	    printf ("                     small to contain the decorations, then this \n");
	    printf ("                     switch is automatically selected.  It is also\n");
	    printf ("                     the default on Mac OS X.\n");
	    printf ("     --simple        Produces a simple text display, allowing dynamic\n");
	    printf ("                     resizing of the text.  This is by far the best choice\n");
	    printf ("                     when there is limited display-screen real estate.\n");
	    printf ("\n");
	    fflush (stdout);
	    return (false);
	  }
	else if (Command.IsSameAs (wxT ("--delay")))
	  StartupDelay = IntValue;
	else if (Command.IsSameAs (wxT ("--port")))
	  Portnum = IntValue;
	else if (Command.IsSameAs (wxT ("--ip")))
	  {
	    strcpy (NonDefaultHostname, Value.char_str ());
	    Hostname = NonDefaultHostname;
	  }
	else if (Command.IsSameAs (wxT ("--spacecraft")))
	  {
	    Value = Value.Lower ();
	    if (Value.IsSameAs (wxT ("lm")))
	      CmOrLm = 0;
	    else if (Value.IsSameAs (wxT ("cm")))
	      CmOrLm = 1;
	    else
	      {
		char s[129];
		strcpy (s, Arg.char_str ()); 
		printf ("Illegal command-line option: %s\n", s);
		goto Help;
	      }
	  }
	else if (Command.IsSameAs (wxT ("--font-size")))
	  {
	    Points = IntValue;
	    FontSizeSwitch = 1;
	  }
	else if (Command.IsSameAs (wxT ("--undecorated")))
	  Undecorated = 1;
	else if (Command.IsSameAs (wxT ("--simple")))
	  {
	    Simple = true;
	    if (!FontSizeSwitch)
	      Points = DEFAULT_FONTSIZE_RESIZABLE;
	  }
	else // Illegal option.
	  {
	    char s[129];
	    strcpy (s, Arg.char_str ()); 
	    printf ("Unrecognized command-line option: %s\n", s);
	    goto Help;
	  }
      }

    printf ("     --delay=%d\n", StartupDelay);
    printf ("     --port=%d\n", Portnum);
    printf ("     --ip=%s\n", Hostname);
    if (CmOrLm)
      printf ("     --spacecraft=CM\n");
    else
      printf ("     --spacecraft=LM\n");
    printf ("     --font-size=%d\n", Points);
#ifdef __APPLE__
    Undecorated = 1;
#endif    
    if (Undecorated)
      printf ("     --undecorated\n");
    if (Simple)
      printf ("     --simple\n");
    
    int x, y, height, width;
    wxClientDisplayRect (&x, &y, &width, &height);
    if (height < 1040)
      Undecorated = 1;
    printf ("     height=%d\n", height);
    fflush (stdout);

    if (Simple)
      {
      
	SimpleFrame->FontSize (Points);

	SetTopWindow(SimpleFrame);
    
	extern Swrite_t *SwritePtr;
	SwritePtr = SwriteTelemetrySimple;
	SimpleFrame->ClearScreen ();
	SimpleFrame->Timer = new TimerClass ();
	SimpleFrame->Timer->Start (PULSE_INTERVAL);
    
	SimpleFrame->Show();
	
      }
      
    else
    
      {

	MainFrame->FontSize (Points);
	if (Undecorated)
	  MainFrame->Undecorate ();

	SetTopWindow(MainFrame);
    
	extern Swrite_t *SwritePtr;
	SwritePtr = SwriteTelemetry;
	MainFrame->ClearScreen ();
	MainFrame->Timer = new TimerClass ();
	MainFrame->Timer->Start (PULSE_INTERVAL);
    
	MainFrame->Show();
    
      }
    return true;
}

SimpleFrameClass::SimpleFrameClass(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
    wxFrame(parent, id, title, pos, size, wxDEFAULT_FRAME_STYLE)
{
    // begin wxGlade: SimpleFrameClass::SimpleFrameClass
    panel_1 = new wxPanel(this, wxID_ANY);
    Bigger = new wxButton(panel_1, ID_BIGGER, wxT("Bigger"));
    Smaller = new wxButton(panel_1, ID_SMALLER, wxT("Smaller"));
    TextCtrl = new wxStaticText(this, wxID_ANY, wxT("12345678901234567890123456789012345678901234567890123456789012345678901234567890\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39"));

    set_properties();
    do_layout();
    // end wxGlade
}


BEGIN_EVENT_TABLE(SimpleFrameClass, wxFrame)
    // begin wxGlade: SimpleFrameClass::event_table
    EVT_BUTTON(ID_BIGGER, SimpleFrameClass::BiggerPressed)
    EVT_BUTTON(ID_SMALLER, SimpleFrameClass::SmallerPressed)
    // end wxGlade
    EVT_CLOSE(SimpleFrameClass::TimerStop)
END_EVENT_TABLE();


void SimpleFrameClass::BiggerPressed(wxCommandEvent &event)
{
    FontSize (++Points);
    Fit ();
}


void SimpleFrameClass::SmallerPressed(wxCommandEvent &event)
{
    if (Points > 6)
      {
        FontSize (--Points);
	Fit ();
      }
}


// wxGlade: add SimpleFrameClass event handlers

void MainFrameClass::TimerStop(wxCloseEvent &event)
{
  Timer->Stop ();
  delete Timer;
  event.Skip ();
  App->ExitMainLoop ();
}

void SimpleFrameClass::TimerStop(wxCloseEvent &event)
{
  Timer->Stop ();
  delete Timer;
  event.Skip ();
  App->ExitMainLoop ();
}

void SimpleFrameClass::set_properties()
{
    // begin wxGlade: SimpleFrameClass::set_properties
    SetTitle(wxT("yaTelemetry by Ron Burkey"));
    wxIcon _icon;
    _icon.CopyFromBitmap(wxBitmap(wxT("ApolloPatch2.png"), wxBITMAP_TYPE_ANY));
    SetIcon(_icon);
    Bigger->SetToolTip(wxT("Make text bigger by clicking this button."));
    Smaller->SetToolTip(wxT("Make text smaller by clicking this button."));
    panel_1->SetBackgroundColour(wxColour(255, 255, 255));
    TextCtrl->SetBackgroundColour(wxColour(255, 255, 255));
    TextCtrl->SetForegroundColour(wxColour(0, 0, 0));
    // end wxGlade
}


void SimpleFrameClass::do_layout()
{
    // begin wxGlade: SimpleFrameClass::do_layout
    wxBoxSizer* sizer_6 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* sizer_7 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* sizer_7_copy = new wxBoxSizer(wxHORIZONTAL);
    sizer_7->Add(20, 10, 0, 0, 0);
    sizer_7_copy->Add(20, 20, 1, 0, 0);
    sizer_7_copy->Add(Bigger, 0, 0, 0);
    sizer_7_copy->Add(50, 20, 0, 0, 0);
    sizer_7_copy->Add(Smaller, 0, 0, 0);
    sizer_7_copy->Add(20, 20, 1, 0, 0);
    sizer_7->Add(sizer_7_copy, 0, wxEXPAND, 0);
    sizer_7->Add(20, 10, 0, 0, 0);
    panel_1->SetSizer(sizer_7);
    sizer_6->Add(panel_1, 0, wxEXPAND, 0);
    sizer_6->Add(TextCtrl, 1, wxEXPAND, 0);
    SetSizer(sizer_6);
    sizer_6->Fit(this);
    Layout();
    // end wxGlade
}

















