/***************************************************************
 * Name:      wxPulso v2
 * Purpose:   Code for Application Frame
 * Author:    seta43 ()
 * Created:   2020-02-27
 * Copyright: seta43 ()
 * License:		D.P.
 * seta43.duckdns.org
 * seta43.blogspot.com
 **************************************************************/
#include "main.h"
#include "define.h"
#include "port.h"

char CLAVE[] = "MAXOP";

	int INDEX=90;
    int PANTALLA;
    int PAUSA;
    int PULSO;
    int ZOOM=0;
    int PanX,PanY;
    
    int val0,val1,val2;
	int anteriorVal;
	int xx;
        
    char CADE1[100];
    char CADE2[100];
    
	int SearchPort2(void);
	unsigned char portok;
	
	int analizar(void);
	void calcPunto(void);
	
	
#define TIEMPO1		7 	//pulso
#define xtimePort	5	//Lectura serie
#define TIEMPO3		2	//pintar punto


int tiempo1=TIEMPO1,timePort=xtimePort, tiempo3=TIEMPO3;
	

DECLARE_APP(MiAplicacion)
// Give wxWidgets the means to create a MiAplicacion object
IMPLEMENT_APP(MiAplicacion)

BEGIN_EVENT_TABLE(MiFrame,wxFrame)
	EVT_PAINT(MiFrame::OnPaint)
	EVT_TIMER(ID_TIMER , MiFrame::OnTimer1Trigger)
	EVT_BUTTON(ID_BUTTON1, MiFrame::OnBexitClick)
	EVT_BUTTON(ID_BUTTON2, MiFrame::OnOclearClick)
	EVT_BUTTON(ID_BUTTON3, MiFrame::OnOresetClick)
	EVT_COMBOBOX(ID_COMBOBOX1,MiFrame::OnOsampleAverageSelected)
	EVT_COMBOBOX(ID_COMBOBOX2,MiFrame::OnOledModeSelected)
	EVT_COMBOBOX(ID_COMBOBOX3,MiFrame::OnOsampleRateSelected)
	EVT_COMBOBOX(ID_COMBOBOX4,MiFrame::OnOpulseWidthSelected)
	EVT_COMBOBOX(ID_COMBOBOX5,MiFrame::OnOadcRangeSelected)
	EVT_COMBOBOX(ID_COMBOBOX6,MiFrame::OnOdisplaySelected)
	EVT_COMBOBOX(ID_COMBOBOX7,MiFrame::OnOzoomSelected)	
	EVT_SPINCTRL(ID_SPINCTRL1,MiFrame::OnOledBrightnessChange)
	EVT_SPINCTRL(ID_SPINCTRL2,MiFrame::OnOindexChange)
	EVT_CHECKBOX(ID_CHECKBOX1,MiFrame::OnOpauseClick)
END_EVENT_TABLE();

 wxString  wxCadena;

MiFrame::MiFrame(wxWindow* parent,wxWindowID id)
{
  int z;
 
  
	//(*Initialize(wxpulsoMaxFrame)
    Create(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("id"));
    SetClientSize(wxSize(735,491));
	  SetBackgroundColour(wxColour(251,250,14));
    Bexit = new wxButton(this, ID_BUTTON1, _("EXIT"), wxPoint(632,448), wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
    StaticText1 = new wxStaticText(this, ID_STATICTEXT1, _("ledBrightness"), wxPoint(16,16), wxDefaultSize, 0, _T("ID_STATICTEXT1"));
    StaticText2 = new wxStaticText(this, ID_STATICTEXT2, _("sampleAverage"), wxPoint(16,64), wxDefaultSize, 0, _T("ID_STATICTEXT2"));
    StaticText3 = new wxStaticText(this, ID_STATICTEXT3, _("ledMode"), wxPoint(16,112), wxDefaultSize, 0, _T("ID_STATICTEXT3"));
    StaticText4 = new wxStaticText(this, ID_STATICTEXT4, _("sampleRate"), wxPoint(16,160), wxDefaultSize, 0, _T("ID_STATICTEXT4"));
    StaticText5 = new wxStaticText(this, ID_STATICTEXT5, _("pulseWidth"), wxPoint(16,208), wxDefaultSize, 0, _T("ID_STATICTEXT5"));
    StaticText6 = new wxStaticText(this, ID_STATICTEXT6, _("adcRange"), wxPoint(16,256), wxDefaultSize, 0, _T("ID_STATICTEXT6"));
    StaticText7 = new wxStaticText(this, ID_STATICTEXT7, _("BPM"), wxPoint(168,464), wxDefaultSize, 0, _T("ID_STATICTEXT7"));
    wxFont StaticText7Font(10,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Sans"),wxFONTENCODING_DEFAULT);
    StaticText7->SetFont(StaticText7Font);
    OledBrightness = new wxSpinCtrl(this, ID_SPINCTRL1, _T("31"), wxPoint(16,32), wxSize(64,25), 0, 0, 255, 31, _T("ID_SPINCTRL1"));
    OledBrightness->SetValue(_T("31"));
    OsampleAverage = new wxComboBox(this, ID_COMBOBOX1, wxEmptyString, wxPoint(16,80), wxSize(72,27), 0, 0, 0, wxDefaultValidator, _T("ID_COMBOBOX1"));
    OsampleAverage->Append(_("1"));
    OsampleAverage->Append(_("2"));
    OsampleAverage->SetSelection( OsampleAverage->Append(_("4")) );
    OsampleAverage->Append(_("8"));
    OsampleAverage->Append(_("16"));
    OsampleAverage->Append(_("32"));
    OsampleAverage->SetMaxSize(wxSize(-1,-1));
    OledMode = new wxComboBox(this, ID_COMBOBOX2, wxEmptyString, wxPoint(16,128), wxSize(96,27), 0, 0, 0, wxDefaultValidator, _T("ID_COMBOBOX2"));
    OledMode->Append(_("RED"));
    OledMode->Append(_("RED+IR"));
    OledMode->SetSelection( OledMode->Append(_("RED+IR+GREEN")) );
    wxFont OledModeFont(7,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL,false,_T("Sans"),wxFONTENCODING_DEFAULT);
    OledMode->SetFont(OledModeFont);
    OsampleRate = new wxComboBox(this, ID_COMBOBOX3, wxEmptyString, wxPoint(16,176), wxSize(72,27), 0, 0, 0, wxDefaultValidator, _T("ID_COMBOBOX3"));
    OsampleRate->Append(_("50"));
    OsampleRate->Append(_("100"));
    OsampleRate->Append(_("200"));
    OsampleRate->SetSelection( OsampleRate->Append(_("400")) );
    OsampleRate->Append(_("800"));
    OsampleRate->Append(_("1000"));
    OsampleRate->Append(_("1600"));
    OsampleRate->Append(_("3200"));
    OpulseWidth = new wxComboBox(this, ID_COMBOBOX4, wxEmptyString, wxPoint(16,224), wxSize(72,27), 0, 0, 0, wxDefaultValidator, _T("ID_COMBOBOX4"));
    OpulseWidth->Append(_("69"));
    OpulseWidth->Append(_("118"));
    OpulseWidth->Append(_("215"));
    OpulseWidth->SetSelection( OpulseWidth->Append(_("411")) );
    OadcRange = new wxComboBox(this, ID_COMBOBOX5, wxEmptyString, wxPoint(16,272), wxSize(72,27), 0, 0, 0, wxDefaultValidator, _T("ID_COMBOBOX5"));
    OadcRange->Append(_("2048"));
    OadcRange->SetSelection( OadcRange->Append(_("4096")) );
    OadcRange->Append(_("8192"));
    OadcRange->Append(_("16384"));
    Odisplay = new wxComboBox(this, ID_COMBOBOX6, wxEmptyString, wxPoint(8,392), wxSize(112,27), 0, 0, 0, wxDefaultValidator, _T("ID_COMBOBOX6"));
    Odisplay->SetSelection( Odisplay->Append(_("Display Red")) );
    Odisplay->Append(_("Display IR"));
    Odisplay->Append(_("Display Green"));
    Odisplay->SetForegroundColour(wxColour(223,24,24));
    wxFont OdisplayFont(8,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL,false,_T("Sans"),wxFONTENCODING_DEFAULT);
    Odisplay->SetFont(OdisplayFont);
    Ozoom = new wxComboBox(this, ID_COMBOBOX7, wxEmptyString, wxPoint(8,456), wxSize(56,32), 0, 0, 0, wxDefaultValidator, _T("ID_COMBOBOX7"));
    Ozoom->SetSelection( Ozoom->Append(_("X1")) );
    Ozoom->Append(_("X2"));
    Ozoom->Append(_("X3"));
    Ozoom->Append(_("X4"));
    Oindex = new wxSpinCtrl(this, ID_SPINCTRL2, _T("90"), wxPoint(8,424), wxSize(48,25), 0, -300, 300, 90, _T("ID_SPINCTRL2"));
    Oindex->SetValue(_T("90"));
    Oclear = new wxButton(this, ID_BUTTON2, _("CLEAR"), wxPoint(56,424), wxSize(48,24), 0, wxDefaultValidator, _T("ID_BUTTON2"));
    wxFont OclearFont(8,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL,false,_T("Sans"),wxFONTENCODING_DEFAULT);
    Oclear->SetFont(OclearFont);
    Opause = new wxCheckBox(this, ID_CHECKBOX1, _("PAUSE"), wxPoint(72,464), wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHECKBOX1"));
    Opause->SetValue(false);
    Obmp = new wxTextCtrl(this, ID_TEXTCTRL1, _("Text"), wxPoint(208,456), wxSize(56,24), 0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
    Opulso = new wxCheckBox(this, ID_CHECKBOX2, _("PULSO"), wxPoint(280,456), wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHECKBOX2"));
    Opulso->SetValue(false);
    Oinfo = new wxTextCtrl(this, ID_TEXTCTRL2, _("Info"), wxPoint(376,456), wxSize(168,25), 0, wxDefaultValidator, _T("ID_TEXTCTRL2"));
    Oreset = new wxButton(this, ID_BUTTON3, _("RESET"), wxPoint(16,312), wxSize(72,24), 0, wxDefaultValidator, _T("ID_BUTTON3"));
	StaticText8 = new wxStaticText(this, ID_STATICTEXT8, _("wxPulso v2"), wxPoint(8,352), wxDefaultSize, 0, _T("ID_STATICTEXT8"));
    StaticText8->SetForegroundColour(wxColour(23,35,190));
    wxFont StaticText8Font(13,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Sans"),wxFONTENCODING_DEFAULT);
    StaticText8->SetFont(StaticText8Font);
   
   
	PanX=600; PanY=430;
    m_bitmap = new wxBitmap(PanX,PanY, 32);
    dcBuffer=new wxMemoryDC(*m_bitmap);
    
    z=SearchPort2();
    if(z==-1)
			 {
				 portok=0;
				 printf("No %s\n",CLAVE);
				 sprintf(VARI,"No device");
			 }
			else
		     {
				portok=1;
				MODEMDEVICE=myport[z];
	#if YesWindows
				if(hSerial)CloseRs232();
	#else
				if(fdrs232)CloseRs232();
	#endif
				IniRs232();
				sprintf(VARI,"%s", MODEMDEVICE);
			 }
	wxCadena= wxString::FromUTF8(VARI);
	Oinfo->SetValue(wxCadena);
	
	MiTimer.SetOwner(this, ID_TIMER);
    MiTimer.Start(10, false);
}


MiFrame::~MiFrame()
{
    //
    //
}

void MiFrame::OnPaint(wxPaintEvent& event)
{
     if(!dcPantalla)
    {
        dcPantalla=new wxClientDC(this);
        dcBuffer->Clear();
    }
	dcPantalla->Blit(125,10,PanX,PanY, dcBuffer,0, 0, wxCOPY, true);
}





void MiFrame::OnTimer1Trigger(wxTimerEvent& event)
{
 #define MAXINPUT 100
 static	int  ContadorI=0;
 static char Binput[MAXINPUT];
 static char Binput2[10];
 static	int nbytes;
 
    if(portok==0) return;
	tiempo1--;
	timePort--;

	if(tiempo1<0)
		{
		 tiempo1=TIEMPO1;
			if(PULSO==1)
			{
				PULSO=0;
				Opulso->SetValue(0);
			}
		}

// cada __timePort
	 if(portok==1 && timePort<0)
	    {
		timePort=xtimePort;

	#if YesWindows
			while(( nbytes = ReadSerie(hSerial, Binput2, 1)>0 ))
	#else
				while(( nbytes = read(fdrs232, Binput2, 1)>0 ))
	#endif
				{
					Binput[ContadorI]=Binput2[0];
					if(ContadorI<MAXINPUT-2)   ContadorI++;

					if (Binput2[0] == '\n')
						{
							if(ContadorI<2)ContadorI=2;
							Binput[ContadorI-1]=0;
							ContadorI=0;
							sprintf(VARI,"%s",Binput);
							if(1==analizar())
							{
									dcBuffer->SetPen(wxPen(wxColor(0,255,0), 1, wxSOLID));
									dcBuffer->DrawLine(xx+2,1,xx+2,PanY);

									dcBuffer->SetPen(wxPen(wxColor(255,255,255), 1, wxSOLID));
									dcBuffer->DrawLine(xx,1,xx,PanY);
									dcBuffer->DrawLine(xx+1,1,xx+1,PanY);

									dcBuffer->SetPen(wxPen(wxColor(255,0,0), 1, wxSOLID));
									dcBuffer->DrawLine(xx-2,anteriorVal,xx,val0);
                                dcPantalla->Blit(125,10,PanX,PanY, dcBuffer,0, 0, wxCOPY, true);

								anteriorVal=val0;
								if(PAUSA==0)xx+=2;
								if(xx>PanX-2) xx=0;
								sprintf(VARI,"%d", val1);
								wxCadena= wxString::FromUTF8(VARI);
								Obmp->SetValue(wxCadena);
								if(val2==1)
                                    {
                                        PULSO=1;
                                        tiempo1=TIEMPO1;
                                        Opulso->SetValue(1);
                                    }
							}
						}
				}
		}
}


//_______________________________
int analizar(void)
{

	char *ptr = strtok(VARI, ",");
		if(ptr== NULL) { goto salir1;}
		val0=atoi(ptr);
		ptr = strtok(NULL, ",");
		if(ptr== NULL) {  goto salir1;}
		val1=atoi(ptr);
		ptr = strtok(NULL, ",");
		if(ptr== NULL) {  goto salir1;}
		val2=atoi(ptr);
//		printf("%d_%d_%d_\n",val0,val1,val2);
		calcPunto();

		return 1;
salir1:
	return 0;
}

void calcPunto(void)
{
	switch(ZOOM)
	{
		case 0:
		val0=val0/8;
		break;
		case 1:
		val0=val0/4;
		break;
		case 2:
		val0=val0;
		break;
		case 3:
		val0=val0*2;
		break;
		case 4:
		val0=val0*4;
		break;
	}
	val0=PanY-val0-INDEX;
}




void MiFrame::OnBexitClick(wxCommandEvent& event)
{
	if(portok==1)	{ portok=0;	 CloseRs232();	}   
    Close();
}

void MiFrame::OnOclearClick(wxCommandEvent& event)
{
    xx=0;
    dcBuffer->Clear();
	dcPantalla->Blit(125,10,PanX,PanY, dcBuffer,0, 0, wxCOPY, true);
}


void MiFrame::SendData(void)
{
  sprintf(CADE2,"%s\n",CADE1);
#if DEBUG 
    printf("%s",CADE2);
#endif
    if(portok==1) PrintSerial(CADE2);
}

void MiFrame::OnOresetClick(wxCommandEvent& event)
{
  OledBrightness->SetValue(31);
  OledMode->SetSelection(2);
  OsampleRate->SetSelection(3);
  OpulseWidth->SetSelection(3);
  OadcRange->SetSelection(1);
  Odisplay->SetSelection(0);
  Ozoom->SetSelection(0);
  Oindex->SetValue(90);
  Opause->SetValue(0);
  ZOOM=0;
  INDEX=90;
  sprintf(CADE1,"RESE");
  SendData();

  xx=0;
  dcBuffer->Clear();
  dcPantalla->Blit(125,10,PanX,PanY, dcBuffer,0, 0, wxCOPY, true);
}

void MiFrame::OnOsampleAverageSelected(wxCommandEvent& event)
{
  wxString msg;
    msg=OsampleAverage->GetStringSelection();
    strcpy( CADE2, (const char*)msg.mb_str(wxConvUTF8) );
    sprintf(CADE1,"SAMA,%s",CADE2);
    SendData();
}

void MiFrame::OnOledModeSelected(wxCommandEvent& event)
{
  int z;
  wxString msg;

     z=OledMode->GetSelection();
     switch(z)
        {
       case 0:
            z=1;
            break;
        case 1:
            z=2;
            break;
        case 2:
            z=3;
            break;
        default:
            z=0;
        }
    sprintf(CADE1,"LEDM,%d",z);
    msg= wxString::FromUTF8(CADE1);
	SendData();
}

void MiFrame::OnOsampleRateSelected(wxCommandEvent& event)
{
 wxString msg;
    msg=OsampleRate->GetStringSelection();
    strcpy( CADE2, (const char*)msg.mb_str(wxConvUTF8) );
    sprintf(CADE1,"SAMR,%s",CADE2);
    msg= wxString::FromUTF8(CADE1);
	SendData();
}

void MiFrame::OnOpulseWidthSelected(wxCommandEvent& event)
{
 wxString msg;
    msg=OpulseWidth->GetStringSelection();
    strcpy( CADE2, (const char*)msg.mb_str(wxConvUTF8) );
    sprintf(CADE1,"PULW,%s",CADE2);
	SendData();
}

void MiFrame::OnOadcRangeSelected(wxCommandEvent& event)
{
 wxString msg;
    msg=OadcRange->GetStringSelection();
    strcpy( CADE2, (const char*)msg.mb_str(wxConvUTF8) );
    sprintf(CADE1,"ADCR,%s",CADE2);
	SendData();
}

void MiFrame::OnOdisplaySelected(wxCommandEvent& event)
{
  int z;
      z=Odisplay->GetSelection();
     switch(z)
        {
       case 0:
            z=1;
            break;
        case 1:
            z=2;
            break;
        case 2:
            z=3;
            break;
        default:
            z=0;
        }
    sprintf(CADE1,"VIEW,%d",z);
    SendData();
}

void MiFrame::OnOzoomSelected(wxCommandEvent& event)
{
    ZOOM=Ozoom->GetSelection();
    sprintf(CADE1,"ZOOM=%d",ZOOM);
#if DEBUG 
    printf("%s\n",CADE1);
#endif
}

void MiFrame::OnOledBrightnessChange(wxSpinEvent& event)
{
  int z;
    z=OledBrightness->GetValue();
    sprintf(CADE1,"LEDB,%d",z);
    SendData();
#if DEBUG 
    printf("%s\n",CADE1);
#endif
}

void MiFrame::OnOindexChange(wxSpinEvent& event)
{
	INDEX=Oindex->GetValue();
    sprintf(CADE1,"INDEX=%d",INDEX);
#if DEBUG 
    printf("%s\n",CADE1);
#endif    
}

void MiFrame::OnOpauseClick(wxCommandEvent& event)
{
    PAUSA=Opause->GetValue();
    sprintf(CADE1,"PAUSA=%d",PAUSA);
#if DEBUG 
    printf("%s\n",CADE1);
#endif  

}




//__________________________________
int SearchPort2(void)
{
	#define MAXINPUT 100
	int z,zz,nbytes;
	int  ContadorI=0;
	char Binput[MAXINPUT];
	char Binput2[10];

 #if YesWindows
		for (z=0;z<11;z++)
 #else
			for (z=0;z<7;z++)
 #endif
			{
				MODEMDEVICE=myport[z];
				printf("Test Port %s\n",MODEMDEVICE);
				if(0==IniRs232())
				   {
					DelayMs(700);
					ContadorI=0;
					for(zz=0;zz<20;zz++)
					   {
						DelayMs(100);
#if YesWindows
						while(( nbytes = ReadSerie(hSerial, Binput2, 1)>0 ))
#else
						while(( nbytes = read(fdrs232, Binput2, 1)>0 ))
#endif
							{
								Binput[ContadorI]=Binput2[0];
								if(ContadorI<MAXINPUT-2)   ContadorI++;
								if (Binput2[0] == '\n')
								   {
									if(ContadorI<2)ContadorI=2;
									Binput[ContadorI-1]=0;
									ContadorI=0;
									if(!strncmp(Binput,CLAVE,5))
									   {
										printf("%s found at %s\n",CLAVE,MODEMDEVICE);
										CloseRs232();
										portok=1;
										return z ;
									   }
								    }
							}
						}

					}
			 }
			printf("PULSE no found \n");
	return -1;
}




