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

#include <iostream.h>

#include "pisysdep.h"
#include PIAPP_H
#include PIWIN_H 
#include PIMENU_H 
#include PISTDWDG_H 
#include PIBWDG_H
#include "piscdrawwdg.h"
#include "pievthandler.h"
#include "parradapter.h"


/*  Composante graphique de trace de chaine de caracteres  */

// ---- Declaration de la classe StringDrawWdg --------
class StringDrawWdg : public PIBaseWdg
{
public:
// Les methodes ...

                  StringDrawWdg(PIContainerGen *par, char *nom,
                         int sx=10, int sy=10, int px=0, int py=0);
  virtual         ~StringDrawWdg();

// Traitement des evenements   
//  virtual void   Resize();
  virtual void   Draw(PIGraphic* g, int x0, int y0, int dx, int dy);

  virtual void   But1Press(int x, int y);
  virtual void   Keyboard(int key, PIKeyModifier kmod);

protected:
  PIFontAtt mFAtt,mSFAtt;
  PIFontSize mFSize, mSFSize;
  int mSL[10], mSH[10];
};


/* ........................................................... */
/*     Classe StringDrawWdg (Implementation des methodes)             */
/* ........................................................... */

/* --Methode-- */
StringDrawWdg::StringDrawWdg(PIContainerGen *par, char *nom,
                       int sx, int sy, int px, int py) 
: PIBaseWdg(par, nom, sx, sy, px, py)

{
  mFAtt = PI_RomanFont;
  mFSize = PI_NormalSizeFont;
  mSFAtt = PI_NotDefFontAtt;
  mSFSize = PI_NotDefFontSize;
  for(int k=0; k<10; k++) 
    mSL[k] = mSH[k] = 0;
  ActivateKeyboard();
  ActivateButton(1);
}

/* --Methode-- */
StringDrawWdg::~StringDrawWdg()
{
}
 

/* --Methode-- */
void StringDrawWdg::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
{
PIFontAtt att[4] = { PI_RomanFont, PI_BoldFont, PI_ItalicFont, PI_BoldItalicFont};
PIFontSize fsz[5] = { PI_TinySizeFont, PI_SmallSizeFont, PI_NormalSizeFont, 
		      PI_BigSizeFont, PI_HugeSizeFont };
PIFontName fn[4] = { PI_CourierFont, PI_HelveticaFont, 
		     PI_TimesFont, PI_SymbolFont};
char * fnstr[4] = { "Courier-Font", "Helvetica-Font", 
		     "Times-Font", "Symbol-Font"};
char * attstr[4] = { "RomanFont" , "BoldFont", "ItalicFont", "BoldItalicFont"};
char * fszstr[5] = { "TinySizeFont", "SmallSizeFont", "NormalSizeFont", 
		      "BigSizeFont", "HugeSizeFont" };

if (g->kind() != PI_PSFileGraphics ) EraseWindow();


int ia=0, js=0;
int k;
for(k=0; k<4; k++)
  if (att[k] == mFAtt)  {ia = k; break; }
for(k=0; k<5; k++)
  if (fsz[k] == mFSize)  {js = k; break; }

if ((mFSize != mSFSize) || (mFAtt != mSFAtt))
  for(k=0; k<10; k++)
    mSL[k] = mSH[k] = 0;
PIFont f(14, PI_DefaultFont);
g->SelFont(f);
  g->SelForeground(PI_Black);
g->DrawString(50,20,attstr[ia]);
g->DrawString(XSize()/2,20,fszstr[js]);


g->SelForeground(PI_Black);
g->SelLine(PI_NormalLine);
g->DrawBox(4, 4, XSize()-8, YSize()-8);

g->SelForeground(PI_Yellow);
g->SelLine(PI_ThickLine);
g->DrawBox(XSize()/4, YSize()/4, XSize()/2, YSize()/2);
g->SelLine(PI_NormalLine);
g->DrawBox(XSize()/4+10, YSize()/4+10, XSize()/2-20, YSize()/2-20);
g->SelLine(PI_ThinLine);
g->DrawBox(XSize()/4+20, YSize()/4+20, XSize()/2-40, YSize()/2-40);



int xpos, ypos;
PIGrCoord asc, desc;
double sl, sh;
char * s1 = "0123456789";
char * s2 = "PI GUI Library";

g->SelLine(PI_NormalLine);
for(k=0; k<4; k++) {
  PIFont fx(14,fn[k]);
  fx.SetFontSz(mFSize);
  fx.SetFontAtt(mFAtt);
  g->SelFont(fx);
  g->SelForeground(PI_Red);
  xpos = (double)XSize()*0.3;
  ypos = (double)YSize()*0.2*k+50;
  g->DrawString(xpos, ypos, fnstr[k]);
  g->SelForeground(PI_Black);
  xpos = 20;
  ypos = (double)YSize()*(0.2*k+0.1)+50;
  g->DrawString(xpos, ypos, s1);
  if ((mSL[2*k] == 0) || (mSH[2*k] == 0)) {
    mSL[2*k] = g->CalcStringWidth(s1);
    mSH[2*k] = g->GetFontHeight(asc, desc);
  }
  sl = mSL[2*k];  sh = mSH[2*k];
  g->DrawBox(xpos-0.05*sl, ypos-1.*sh, sl*1.1, sh*1.2);
  xpos = XSize()/2+20;
  g->SelForeground(PI_Blue);
  g->DrawString(xpos, ypos, s2);
  if ((mSL[2*k+1] == 0) || (mSH[2*k+1] == 0)) {
    mSL[2*k+1] = g->CalcStringWidth(s2);
    mSH[2*k+1] = g->GetFontHeight(asc, desc);
  }
  sl = mSL[2*k+1];  sh = mSH[2*k+1];
  g->SelForeground(PI_Blue);
  g->DrawBox(xpos-0.05*sl, ypos-1.*sh, sl*1.1, sh*1.2);
  xpos = XSize()/2+20;
}

g->SelForeground(PI_Green);
g->SelLine(PI_ThinLine);
for(k=0; k<4; k++) {
  xpos = 0.2*(k+1)*(double)XSize();
  ypos = 0.2*(k+1)*(double)YSize();
  g->DrawLine(xpos, 0, xpos, YSize()-1);
  g->DrawLine(0, ypos, XSize()-1, ypos);
}
return;
}

/* --Methode-- */
void StringDrawWdg::Keyboard(int key, PIKeyModifier kmod)
{

bool fgref = true;
switch (key) {
 case 'r':
   mFAtt = PI_RomanFont;
   break;
 case 'b':
   mFAtt = PI_BoldFont;
   break;
 case 'i':
   mFAtt = PI_ItalicFont;
   break;
 case 'I':
   mFAtt = PI_BoldItalicFont;
   break;
 case '1':
   mFSize = PI_TinySizeFont;
   break;
 case '2':
   mFSize = PI_SmallSizeFont;
   break;
 case '3':
   mFSize = PI_NormalSizeFont;
   break;
 case '4':
   mFSize = PI_BigSizeFont;
   break;
 case '5':
   mFSize = PI_HugeSizeFont;
   break;
 default:
   fgref = false;
}

if (fgref) Refresh(); 

return;
}
/* --Methode-- */
void StringDrawWdg::But1Press(int x, int y)
{
  Send(Msg(), PIMsg_Active);
}

/* ........................................................... */
/*                       Classe PITApp                         */
/* ........................................................... */
class PITApp : public PIApplication {
public:
     PITApp(int narg=0, char* arg[]=NULL);
     ~PITApp();
     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
private :
  PIMenu* m[2];
  PIText* txt;
  PIWindow* mcurwin;
  PSFile *mPS;
};


/* --Methode-- */
PITApp::PITApp(int narg, char* arg[])
: PIApplication(300, 100, narg, arg)
{

//  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  

m[0] = new PIMenu(Menubar(),"Actions");
m[0]->AppendItem("StringDrawWdg", 10101);
m[0]->AppendItem("->eps", 10111);
m[0]->AppendItem("->ps", 10112);
m[0]->AppendItem("Exit", 10105);
// On accroche le menu au Menubar
AppendMenu(m[0]);


// Creation d' zone texte multiligne
txt = new PIText(MainWin(), "mltext", true, true, 290, 90, 5, 5);
txt->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
// txt->SetMutiLineMode(true);
txt->SetTextEditable(false);
txt->SetText("");
txt->SetText("StringDrawWdg/Keyboard: \n r,b,i,I (Roman,bold,italic,bolditalic) \n Size 1,2,3,4,5");

mcurwin = NULL;
mPS = new PSFile("pist.ps", PI_Auto);
SetReady();
}

/* --Methode-- */
PITApp::~PITApp()
{
delete m[0]; 
delete txt;
delete mPS;
}  

static int numpsf = 0;
static int nbwin = 0;
/* --Methode-- */
void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
{

char strg[256];

// Gestion des actions en fonctions des messages

if ( ( ModMsg(msg) == PIMsg_Active) || (ModMsg(msg) == PIMsg_Close) ) {
  PIWdg *sndw;
  sndw = (PIWdg *)sender;      
  if (sndw->kind() ==  PIWindow::ClassId)  {
    if (ModMsg(msg) == PIMsg_Close)  { 
      delete (PIWindow *)sender;  
      mcurwin = NULL;  
      }
    else mcurwin = (PIWindow *)sender;
  }
}

else switch(UserMsg(msg))    {

    case 10101: // Creation d'un StringDrawWdg
      {
      nbwin++;
      sprintf(strg, "Creation StringDrawWdg   \n Fenetre No %d ", nbwin);
      sprintf(strg,"StringDrawWdg - %d", nbwin);
      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  400, 400, 150, 150);
      wp->SetAutoDelChilds(true);
      StringDrawWdg* exb  = new StringDrawWdg(wp, "bwdg", 400, 400, 0, 0);
      exb->SetBinding(PIBK_fixed,PIBK_elastic,PIBK_elastic,PIBK_elastic);
      wp->SetUserData(exb);
      wp->Show();
      }
    break;


    case 10111:          // -> eps
      if (mcurwin) {
        char buff[64];
        sprintf(buff, "pist_%d.eps", numpsf);        numpsf++;
        printf("Creating EPS File %s (Encapsulated PostScript) \n", buff);
        PSFile *mps;
	mps = new PSFile(buff, 0.75);
	mcurwin->PSPrint(mps,0,0);
	delete mps;
        }
      break;    
    
    case 10112:          // -> eps
      if (mcurwin) {
        printf("Current Window to Postscript file pist.ps \n");
	mcurwin->PSPrint(mPS,0,0);
        }
      break;        

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

  }
return;
}


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

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

delete app;
exit(0);
}


