#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <iostream.h>


#include "pisysdep.h"

#include PIAPP_H
#include PIMENU_H 
#include PISTDWDG_H 
#include PIWIN_H
#include PIPERIODIC_H

//  ----- Declaration de la classe ArgsWind : Fenetre de dialogue -------
class ArgsWind : public PIWindow {
public :
                ArgsWind(PIApplication *par);
                ~ArgsWind();
          void  SetLabels(char *lab1, char *lab2, char *lab3);
          void  SetTexts(char *tx1, char *tx2, char *tx3);
          void  GetTexts(char *tx1, char *tx2, char *tx3);
  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);

private:
  PILabel  * mLab[3];
  PIButton * mBut[2];
  PIText * mText[3];
  };

//  ----- Declaration de notre classe PIApplication (PITApp) -------
class PITApp : public PIApplication {
public:
     PITApp(int narg=0, char* arg[]=NULL);
     ~PITApp();
     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);

  PILabel *lab;

private :
  PIMenu * m[2];
  PIPeriodX mPeriod;
  ArgsWind *mAW;
};



/* ........................................................... */
/*              Classe ArgsWindow (methodes)                   */
/* ........................................................... */


/* --Methode-- */
ArgsWind::ArgsWind(PIApplication *par)
: PIWindow((PIMsgHandler *)par, "Args", PIWK_dialog, 100, 100, 150, 150)
{
int bsx, bsy;

// On definit la taille a partir de la taille par defaut des composantes 
printf("ArgsWind::ArgsWind() \n");
PIApplicationPrefCompSize(bsx, bsy);
// On redefinit la taille de la fenetre
SetSize(bsx*7, bsy*6);

// Creation de champs "labels"
mLab[0] = new PILabel(this, "UserArg-1:", bsx*2, bsy, bsx/3, bsy/4); 
mLab[1] = new PILabel(this, "UserArg-2", bsx*2, bsy, bsx/3, bsy/4 + (bsy/4+bsy) );
mLab[2] = new PILabel(this, "UserArg-3", bsx*2, bsy, bsx/3, bsy/4 + 2*(bsy/4+bsy) );

// Creation de champs textes 
mText[0] = new PIText(this, "UsArg1", bsx*4, bsy, bsx*2+(bsx*2/3), bsy/4);
mText[0]->SetText("Hello ");
mText[1] = new PIText(this, "UsArg2", bsx*4, bsy, bsx*2+(bsx*2/3), bsy/4 + (bsy/4+bsy) );
mText[1]->SetText("1. -1.");
mText[2] = new PIText(this, "UsArg3", bsx*4, bsy, bsx*2+(bsx*2/3), bsy/4 + 2*(bsy/4+bsy) );
mText[2]->SetText("1. -1.");

// Creation de bouton d'action 
//  Attention : Numero de message pour Process()
mBut[0] = new PIButton(this, "OK",  555, bsx*2, bsy, bsx, 4.5*bsy);
mBut[1] = new PIButton(this, "Cancel", 777, bsx*2, bsy, 4*bsx, 4.5*bsy);

//  Taille et position proportionnelles a la taille de la fenetre pour les elements
for(int i=0; i<3; i++) {
  mLab[i]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
  mText[i]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
  }
for(int ii=0; ii<2; ii++) mBut[ii]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);

}

/* --Methode-- */
ArgsWind::~ArgsWind()
{
for(int i=0; i<3; i++)
  {
  delete mLab[i];
  delete mText[i];
  }

delete mBut[0]; 
delete mBut[1]; 
}

/* --Methode-- */
void ArgsWind::SetLabels(char *lab1, char *lab2, char *lab3)
// Permet de changer les etiquettes (les label)
{
mLab[0]->SetLabel(lab1);
mLab[1]->SetLabel(lab2);
mLab[2]->SetLabel(lab3);
}

/* --Methode-- */
void ArgsWind::SetTexts(char *tx1, char *tx2, char *tx3)
// Permet de changer les contenu des champs texte
{
mText[0]->SetText(tx1);
mText[1]->SetText(tx2);
mText[2]->SetText(tx3);

}

/* --Methode-- */
void ArgsWind::GetTexts(char *tx1, char *tx2, char *tx3)
// Permet de recuperer les contenus des champs texte
// ATTENTION : Il faut qu'il y ait assez de place 
// ds tx1, tx2, tx3 pour que la fonction puisse y copier 
// les chaines
{
strcpy(tx1, mText[0]->GetText().c_str());
strcpy(tx2, mText[1]->GetText().c_str());
strcpy(tx3, mText[2]->GetText().c_str());
}

/* --Methode-- */
void ArgsWind::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
{
float xmin, xmax, ymin, ymax;
float fmin, fmax;

switch (UserMsg(msg))
  {
  case 777:   // Bouton cancel - On s'en va 
    this->Hide();
    break;

  case 555:    // Bouton OK
// On recupere les textes des 3 champs :
    printf("ArgsWind::Process() Txt[0] = %s \n", mText[0]->GetText().c_str());
    sscanf(mText[1]->GetText().c_str(),"%g %g", &xmin, &xmax);
    printf("... XMin/Max= %g %g \n", xmin, xmax);
    this->Hide();
    break;    
  }
    
return;
}


/* ........................................................... */
/*               Classe PITApp (methodes)                      */
/* ........................................................... */

static void mypact(void *);

/* --Methode-- */
PITApp::PITApp(int narg, char* arg[])
: PIApplication(270, 100, narg, arg), mPeriod(1)   // Periode de 1 seconde pour le "timer"
{

//  Menus, les numeros ds AppendItem sont les numeros de messages
//  qui seront passes a Process() et permettent d'identifier l'action

//  Creation du premier menu  
//  Update :
//  Mis a jour du Label se trouvant ds la fenetre principal avec l'heure
//  Start, Stop :
//  Demarrage et Arret d'une fonction Timer (PIPeriodic) pour 
//  la mise a jour periodique de ce champ
//  Exit : 
//  Arret et sortie du programme
  cout << " PITApp::PITApp() - Creating menus " << endl;
m[0] = new PIMenu(Menubar(),"Fichier");
m[0]->AppendItem("Update", 10101);
m[0]->AppendItem("Start", 10102);
m[0]->AppendItem("Stop", 10103);
m[0]->AppendItem("ArgsWindow", 10104);
m[0]->AppendItem("Exit", 10105);
// On accroche le menu au Menubar
AppendMenu(m[0]);

m[1] = new PIMenu(Menubar(),"Edit");
m[1]->AppendItem("Cut", 10201);
m[1]->AppendItem("Copy", 10202);
m[1]->AppendItem("Paste", 10203);
// On accroche le menu au Menubar
AppendMenu(m[1]);


// Creation de deux labels - Un pour l'heure, l'autre pour X-Y 
// de la fenetre histo
  cout << " PITApp::PITApp() - Creating PILabel " << endl;
lab = new PILabel(this->MainWin(), "time", 250, 50, 10, 10);

mPeriod.SetAction(mypact);

// Fenetre de dialogue
mAW = new ArgsWind(this);
SetReady();
}

/* --Methode-- */
PITApp::~PITApp()
{
delete m[0]; delete m[1]; delete lab;
delete mAW;
}  

/* --Methode-- */
void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
{

char strg[64];

// Gestion des actions en fonctions des messages

switch(UserMsg(msg))    {

    case 10101:     // On met a l'heure
      mypact(NULL);    
      break;

    case 10102:
      mPeriod.Start();   // On demarre la montre 
      break;

    case 10103:
      mPeriod.Stop();    // On arrete la montre 
      break;

    case 10104 :     // Apparition de la fenetre de dialogue
      mAW->Show();
      break;

    case 10105:          // Sortie d'application
      Stop();
      break;

    case 10201:          // 2 eme menu
    case 10202:          //    "   "
    case 10203:          //    "   "
      printf("PITApp::Process() Msg= %d (%d - %d) Menu 2 not implemented \n",
              (int)msg, (int)UserMsg(msg),(int)ModMsg(msg));
      break;

    default :
      printf("PITApp::Process() Msg= %d (%d - %d)??? \n", 
            (int)msg, (int)UserMsg(msg),(int)ModMsg(msg));
     break;
    
  }
return;
}

static PITApp * app;

/* Nouvelle-Fonction */
void mypact(void *)
// Fonction pour lire l'heure de la machine et mettre a jour le champ label
{
time_t tm;
char *s;
time(&tm);
s = ctime(&tm);
// printf("mypact_Info:  %d  (%s)", tm, s);
app->lab->SetLabel((string)s);
return;
}

// ................................................................
//                   programme principal 
// ................................................................

int main(int narg, char *arg[])
{
if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
  printf("pit0 : Standard widget test \n");
  printf("  Usage : pit0 [Xt options] \n");
  }
//  Creation de l'objet application et appel de Run()
app = new PITApp(narg, arg);
puts("appel de Application.Run() ... ");
app->Run();

delete app;
exit(0);
}


