// @(#)root/graf:$Name:  $:$Id: TPaveText.cxx,v 1.18 2002/10/28 15:38:32 brun Exp $
// Author: Rene Brun   20/10/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

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

#include "Riostream.h"
#include "TROOT.h"
#include "TPaveText.h"
#include "TPaveLabel.h"
#include "TVirtualPad.h"
#include "TMath.h"
#include "TLatex.h"
#include "TError.h"

ClassImp(TPaveText)

//______________________________________________________________________________
//  A PaveText is a Pave (see TPave) with text,lines or/and boxes.
//Begin_Html
/*
<img src="gif/pavetext.gif">
*/
//End_Html
//

//______________________________________________________________________________
TPaveText::TPaveText(): TPave(), TAttText()
{
//*-*-*-*-*-*-*-*-*-*-*pavetext default constructor*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  =============================

   fLines = 0;
}

//______________________________________________________________________________
TPaveText::TPaveText(Double_t x1, Double_t y1,Double_t x2, Double_t  y2, Option_t *option)
           :TPave(x1,y1,x2,y2,4,option), TAttText(22,0,1,62,0)
{
//*-*-*-*-*-*-*-*-*-*-*pavetext normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ============================
// a PaveText is a Pave with several lines of text
// The Pave is by default defined bith bordersize=5 and option ="br".
// The individual text items are entered via AddText
// By default, text items inherits from the default pavetext AttText.
// A title can be added later to this pavetext via TPaveText::SetLabel.
//
//  IMPORTANT NOTE:
//  Because TPave objects (and objects deriving from TPave) have their
//  master coordinate system in NDC, one cannot use the TBox functions
//  SetX1,SetY1,SetX2,SetY2 to change the corner coordinates. One should use
//  instead SetX1NDC, SetY1NDC, SetX2NDC, SetY2NDC.

   fLines   = new TList;
   fMargin  = 0.05;
   fLongest = 0;
}

//______________________________________________________________________________
TPaveText::~TPaveText()
{
//*-*-*-*-*-*-*-*-*-*-*pavetext default destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ============================

   if (!TestBit(kNotDeleted)) return;
   if (fLines) fLines->Delete();
   delete fLines;
   fLines = 0;
}

//______________________________________________________________________________
TPaveText::TPaveText(const TPaveText &pavetext) : TPave(), TAttText()
{
   TBuffer b(TBuffer::kWrite);
   TPaveText *p = (TPaveText*)(&pavetext);
   p->Streamer(b);
   b.SetReadMode();
   b.SetBufferOffset(0);
   fLines = 0;
   Streamer(b);
}

//______________________________________________________________________________
TBox *TPaveText::AddBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
{
//*-*-*-*-*-*-*-*-*Add a new graphics box to this pavetext*-*-*-*-*-*-*-*-*-*
//*-*              =======================================

   if (!gPad->IsEditable()) return 0;
   TBox *newbox = new TBox(x1,y1,x2,y2);

   if (!fLines) fLines = new TList;
   fLines->Add(newbox);
   return newbox;
}

//______________________________________________________________________________
TLine *TPaveText::AddLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
{
//*-*-*-*-*-*-*-*-*Add a new graphics line to this pavetext*-*-*-*-*-*-*-*-*-*
//*-*              ========================================

   if (!gPad->IsEditable()) return 0;
   TLine *newline = new TLine(x1,y1,x2,y2);

   if (!fLines) fLines = new TList;
   fLines->Add(newline);
   return newline;
}

//______________________________________________________________________________
TText *TPaveText::AddText(Double_t x1, Double_t y1, const char *text)
{
//*-*-*-*-*Add a new Text line to this pavetext at given coordinates*-*-*-*-*
//*-*      =========================================================

   TLatex *newtext = new TLatex(x1,y1,text);
   newtext->SetTextAlign(0);
   newtext->SetTextColor(0);
   newtext->SetTextFont(0);
   newtext->SetTextSize(0);
   Int_t nch = strlen(text);
   if (nch > fLongest) fLongest = nch;

   if (!fLines) fLines = new TList;
   fLines->Add(newtext);
   return newtext;
}

//______________________________________________________________________________
TText *TPaveText::AddText(const char *text)
{
//*-*-*-*-*-*-*-*-*Add a new Text line to this pavetext*-*-*-*-*-*-*-*-*-*-*-*
//*-*              ====================================

   return AddText(0,0,text);
}

//______________________________________________________________________________
void TPaveText::Clear(Option_t *)
{
//*-*-*-*-*-*-*-*-*-*Clear all lines in this pavetext*-*-*-*-*-*-*-*-*-*
//*-*                ================================

   if (!fLines) return;
   fLines->Delete();
   fLongest = 0;
}

//______________________________________________________________________________
void TPaveText::DeleteText()
{
//*-*-*-*-*-*-*-*-*Delete text at the mouse position*-*-*-*-*-*-*-*-*
//*-*              =========================================


   if (!gPad->IsEditable()) return;
   if (!fLines) return;
   Double_t ymouse, yobj;
   TObject *obj = GetObject(ymouse, yobj);             //get object pointed by the mouse
   if (!obj) return;
   if (!obj->InheritsFrom(TText::Class())) return;
   fLines->Remove(obj);
   delete obj;
}

//______________________________________________________________________________
void TPaveText::Draw(Option_t *option)
{
//*-*-*-*-*-*-*-*-*-*-*Draw this pavetext with its current attributes*-*-*-*-*
//*-*                  ===============================================

   AppendPad(option);

}

//______________________________________________________________________________
void TPaveText::DrawFile(const char *filename, Option_t *option)
{
//*-*-*-*-*-*-*-*-*Draw lines in filename in this pavetext*-*-*-*-*-*-*-*
//*-*              =======================================


   ReadFile(filename);

   AppendPad(option);

}

//______________________________________________________________________________
void TPaveText::EditText()
{
//*-*-*-*-*-*-*-*-*Edit text at the mouse position*-*-*-*-*-*-*-*-*
//*-*              =========================================


   if (!gPad->IsEditable()) return;
   Double_t ymouse, yobj;
   TObject *obj = GetObject(ymouse, yobj);             //get object pointed by the mouse
   if (!obj) return;
   if (!obj->InheritsFrom(TText::Class())) return;
   TText *text = (TText*)obj;
   gROOT->SetSelectedPrimitive(text);
   text->SetTextAttributes();
}

//______________________________________________________________________________
TText *TPaveText::GetLine(Int_t number) const
{
//*-*-*-*-*-*-*-*Get Pointer to line number in this pavetext*-*-*-*-*-*-*-*
//*-*            ===========================================

   TText *line;
   TIter next(fLines);
   Int_t nlines = 0;
   while ((line = (TText*) next())) {
      if (nlines == number) return line;
      nlines++;
   }
   return 0;
}

//______________________________________________________________________________
TText *TPaveText::GetLineWith(const char *text) const
{
//*-*-*-*-*Get Pointer to first containing string text in this pavetext*-*-*-*
//*-*      ============================================================

   TText *line;
   TIter next(fLines);
   while ((line = (TText*) next())) {
      if (strstr(line->GetTitle(),text)) return line;
   }
   return 0;

}

//______________________________________________________________________________
TObject *TPaveText::GetObject(Double_t &ymouse, Double_t &yobj) const
{
//*-*-*-*-*Get object pointed by the mouse in this pavetext*-*-*-*
//*-*      ================================================

   if (!fLines) return 0;
   Int_t nlines = GetSize();
   if (nlines == 0) return 0;

//*-*- Evaluate text size as a function of the number of lines

   ymouse   = gPad->AbsPixeltoY(gPad->GetEventY());
   Double_t yspace   = (fY2 - fY1)/Double_t(nlines);
   Double_t textsize = GetTextSize();
   Double_t y1,y,dy;
   if (textsize == 0)  {
      y1       = gPad->GetY1();
   }
   Double_t ytext = fY2 + 0.5*yspace;
   Int_t valign;

//*-*- Iterate over all lines
//*-*- Copy pavetext attributes to line attributes if line attributes not set
   dy = fY2 - fY1;
   TObject *line;
   TText *linet;
   TLine *linel;
   TBox  *lineb;
   TIter next(fLines);
   while ((line = (TObject*) next())) {
//*-*- Next primitive is a line
      if (line->IsA() == TLine::Class()) {
         linel = (TLine*)line;
         y1 = linel->GetY1();   if (y1 == 0) y1 = ytext; else y1 = fY1 + y1*dy;
         if (TMath::Abs(y1-ymouse) < 0.2*yspace) {yobj = y1; return line;}
         continue;
      }
//*-*- Next primitive is a box
      if (line->IsA() == TBox::Class()) {
         lineb = (TBox*)line;
         y1 = lineb->GetY1();   if (y1 == 0) y1 = ytext; else y1 = fY1 + y1*dy;
         if (TMath::Abs(y1-ymouse) < 0.4*yspace) {yobj = y1; return line;}
         continue;
      }
//*-*- Next primitive is a text
      if (line->InheritsFrom(TText::Class())) {
         linet = (TText*)line;
         ytext -= yspace;
         Double_t yl     = linet->GetY();
         Short_t talign = linet->GetTextAlign();
         if (talign == 0) talign = GetTextAlign();
         if (yl > 0 && yl <1) {
            ytext = fY1 + yl*dy;
         }
         valign = linet->GetTextAlign()%10;
         y = ytext;
         if (valign == 1) y = ytext -0.5*yspace;
         if (valign == 3) y = ytext +0.5*yspace;

         if (TMath::Abs(y-ymouse) < 0.5*yspace) {yobj = y; return line;}
      }
   }
   return 0;
}

//______________________________________________________________________________
Int_t TPaveText::GetSize() const
{
//  return number of text lines (ignoring Tlines, etc)

   Int_t nlines = 0;
   TIter next(fLines);
   TObject *line;
   while ((line = (TObject*) next())) {
      if (line->InheritsFrom(TText::Class())) nlines++;
   }
   return nlines;
}

//______________________________________________________________________________
void TPaveText::InsertLine()
{
//*-*-*-*-*-*-*-*-*Add a new lineine at the mouse position*-*-*-*-*-*-*-*-*
//*-*              =======================================


   if (!gPad->IsEditable()) return;
   Double_t ymouse, yobj;
   TObject *obj = GetObject(ymouse, yobj); //get object pointed by the mouse
   Double_t yline = (ymouse-fY1)/(fY2-fY1);
   TLine *newline = AddLine(0,yline,0,yline);
   if (obj) {
      fLines->Remove(newline);        //remove line from last position
      if (yobj < ymouse) fLines->AddBefore(obj,newline);
      else               fLines->AddAfter(obj,newline);
   }
}

//______________________________________________________________________________
void TPaveText::InsertText(const char *text)
{
//*-*-*-*-*-*-*-*-*Add a new Text line at the mouse position*-*-*-*-*-*-*-*-*
//*-*              =========================================


   if (!gPad->IsEditable()) return;
   Double_t ymouse, yobj;
   TObject *obj = GetObject(ymouse, yobj); //get object pointed by the mouse
   TText *newtext = AddText(0,0,text);     //create new text object
   if (obj) {
      fLines->Remove(newtext);        //remove text from last position
      if (yobj < ymouse) fLines->AddBefore(obj,newtext); //insert new text at right position
      else               fLines->AddAfter(obj,newtext);  //insert new text at right position
   }
}

//______________________________________________________________________________
void TPaveText::Paint(Option_t *option)
{
//*-*-*-*-*-*-*-*-*-*-*Paint this pavetext with its current attributes*-*-*-*
//*-*                  ================================================


//*-*- Draw the pave
   TPave::ConvertNDCtoPad();
   TPave::PaintPave(fX1,fY1,fX2,fY2,GetBorderSize(),option);
   PaintPrimitives(kPaveText);
}

//______________________________________________________________________________
void TPaveText::PaintPrimitives(Int_t mode)
{
//*-*-*-*-*-*-*-*Paint list of primitives in this pavetext*-*-*-*-*-*-*-*
//*-*            =========================================
   if (!fLines) return;
   Double_t dx = fX2 - fX1;
   Double_t dy = fY2 - fY1;
   Double_t textsize = GetTextSize();
   Int_t nlines = GetSize();
   if (nlines == 0) nlines = 5;

//*-*- Evaluate text size as a function of the number of lines

   Double_t x1,y1,x2,y2,y;
   y1       = gPad->GetY1();
   y2       = gPad->GetY2();
   Float_t margin    = fMargin*(fX2-fX1);
   Double_t yspace   = (fY2 - fY1)/Double_t(nlines);
   Double_t textsave = textsize;
   TObject *line;
   TText *linet;
   TLatex *latex;
   TIter next(fLines);
   Double_t longest = 0;
   Double_t w;
   if (textsize == 0)  {
      textsize = 0.85*yspace/(y2 - y1);
      while ((line = (TObject*) next())) {
         if (line->IsA() == TLatex::Class()) {
            latex = (TLatex*)line;
            Float_t tangle = latex->GetTextAngle();
            if (latex->GetTextSize() != 0) continue;
            latex->SetTextSize(textsize);
            w = latex->GetXsize();
            latex->SetTextSize(0);
            latex->SetTextAngle(tangle); //text angle was redefined in GetXsize !
            if (w > longest) longest = w;
         }
      }
      if (longest > 0.96*dx) textsize *= 0.96*dx/longest;
      if (mode == kDiamond) textsize *= 0.66;
      SetTextSize(textsize);
   }
   Double_t yfont;
   if (GetTextFont()%10 > 2)
      yfont = (gPad->PixeltoY(Int_t(-textsize))-gPad->PixeltoY(0))/(y2-y1)*dy;
   else
      yfont = textsize*dy;
   Double_t ytext = fY2 + 0.5*yspace;
   Double_t xtext = 0;
   Int_t halign, valign;

//*-*- Iterate over all lines
//*-*- Copy pavetext attributes to line attributes if line attributes not set
   TLine *linel;
   TBox  *lineb;
   next.Reset();
   while ((line = (TObject*) next())) {
//*-*- Next primitive is a line
      if (line->IsA() == TLine::Class()) {
         linel = (TLine*)line;
         x1 = linel->GetX1();   if (x1 == 0) x1 = fX1; else x1 = fX1 + x1*dx;
         x2 = linel->GetX2();   if (x2 == 0) x2 = fX2; else x2 = fX1 + x2*dx;
         y1 = linel->GetY1();   if (y1 == 0) y1 = ytext; else y1 = fY1 + y1*dy;
         y2 = linel->GetY2();   if (y2 == 0) y2 = ytext; else y2 = fY1 + y2*dy;
         linel->PaintLine(x1,y1,x2,y2);
         continue;
      }
//*-*- Next primitive is a box
      if (line->IsA() == TBox::Class()) {
         lineb = (TBox*)line;
         x1 = lineb->GetX1();
         if (x1) x1 = fX1 + x1*dx;
         else    x1 = fX1 + gPad->PixeltoX(1) - gPad->PixeltoX(0);
         x2 = lineb->GetX2();
         if (x2) x2 = fX1 + x2*dx;
         else    x2 = fX2;
         y1 = lineb->GetY1();   if (y1 == 0) y1 = ytext; else y1 = fY1 + y1*dy;
         y2 = lineb->GetY2();   if (y2 == 0) y2 = ytext; else y2 = fY1 + y2*dy;
         lineb->PaintBox(x1,y1,x2,y2);
         continue;
      }
//*-*- Next primitive is a text
      if (line->IsA() == TText::Class()) {
         linet = (TText*)line;
         ytext -= yspace;
         Double_t xl     = linet->GetX();
         Double_t yl     = linet->GetY();
         Short_t talign = linet->GetTextAlign();
         Color_t tcolor = linet->GetTextColor();
         Style_t tfont  = linet->GetTextFont();
         Size_t  tsize  = linet->GetTextSize();
         if (talign == 0) linet->SetTextAlign(GetTextAlign());
         if (tcolor == 0) linet->SetTextColor(GetTextColor());
         if (tfont  == 0) linet->SetTextFont(GetTextFont());
         if (tsize  == 0) linet->SetTextSize(GetTextSize());
         if (xl > 0 && xl <1) {
            xtext = fX1 + xl*dx;
         } else {
            halign = linet->GetTextAlign()/10;
            if (halign == 1) xtext = fX1 + margin;
            if (halign == 2) xtext = 0.5*(fX1+fX2);
            if (halign == 3) xtext = fX2 - margin;
         }
         if (yl > 0 && yl <1) {
            ytext = fY1 + yl*dy;
         }
         valign = linet->GetTextAlign()%10;
         y = ytext;
         if (valign == 1) y = ytext -0.5*yspace;
         if (valign == 3) y = ytext +0.5*yspace;

         linet->PaintText(xtext,y,linet->GetTitle());
         linet->SetTextAlign(talign);
         linet->SetTextColor(tcolor);
         linet->SetTextFont(tfont);
         linet->SetTextSize(tsize);
      }
//*-*- Next primitive is a Latex text
      if (line->IsA() == TLatex::Class()) {
         latex = (TLatex*)line;
         ytext -= yspace;
         Double_t xl     = latex->GetX();
         Double_t yl     = latex->GetY();
         Short_t talign = latex->GetTextAlign();
         Color_t tcolor = latex->GetTextColor();
         Style_t tfont  = latex->GetTextFont();
         Size_t  tsize  = latex->GetTextSize();
         if (talign == 0) latex->SetTextAlign(GetTextAlign());
         if (tcolor == 0) latex->SetTextColor(GetTextColor());
         if (tfont  == 0) latex->SetTextFont(GetTextFont());
         if (tsize  == 0) latex->SetTextSize(GetTextSize());
         if (xl > 0 && xl <1) {
            xtext = fX1 + xl*dx;
         } else {
            halign = latex->GetTextAlign()/10;
            if (halign == 1) xtext = fX1 + margin;
            if (halign == 2) xtext = 0.5*(fX1+fX2);
            if (halign == 3) xtext = fX2 - margin;
         }
         if (yl > 0 && yl <1) {
            ytext = fY1 + yl*dy;
         }
         valign = latex->GetTextAlign()%10;
         y = ytext-0.5*yfont;
         if (valign == 1) y = ytext -0.5*yspace;
         if (valign == 3) y = ytext +0.5*yspace;
         latex->PaintLatex(xtext,y,latex->GetTextAngle(),
                                   latex->GetTextSize(),
                                   latex->GetTitle());
         latex->SetTextAlign(talign);
         latex->SetTextColor(tcolor);
         latex->SetTextFont(tfont);
         latex->SetTextSize(tsize);
         latex->SetX(xl);  //paintlatex modifies fX and fY
         latex->SetY(yl);
      }
   }

   SetTextSize(textsave);

   // if a label create & paint a pavetext title
   if (fLabel.Length() > 0) {
      dy = gPad->GetY2() - gPad->GetY1();
      x1 = fX1 + 0.25*dx;
      x2 = fX2 - 0.25*dx;
      y1 = fY2 - 0.02*dy;
      y2 = fY2 + 0.02*dy;
      TPaveLabel *title = new TPaveLabel(x1,y1,x2,y2,fLabel.Data(),GetDrawOption());
      title->SetFillColor(GetFillColor());
      title->SetTextColor(GetTextColor());
      title->SetTextFont(GetTextFont());
      title->Paint();
      delete title;
   }
}

//______________________________________________________________________________
void TPaveText::Print(Option_t *option) const
{
//*-*-*-*-*-*-*-*-*-*-*Dump this pavetext with its attributes*-*-*-*-*-*-*-*
//*-*                  =======================================
   TPave::Print(option);
   if (fLines) fLines->Print();
}

//______________________________________________________________________________
void TPaveText::ReadFile(const char *filename, Option_t *option, Int_t nlines, Int_t fromline)
{
//*-*-*-*-*-*-*-*-*Read lines of filename in this pavetext*-*-*-*-*-*-*-*-*
//*-*              =======================================
//
//  Read from line number fromline a total of nlines
//
//  Note that this function changes the default text alignment to left/center
//
   Int_t ival;
   Float_t val;
   TText *lastline = 0;
   TString opt = option;
   if (!opt.Contains("+")) {
      Clear();
      fLongest = 0;
   }
   SetTextAlign(12);
//*-*- Get file name
   Int_t nch = strlen(filename);
   if (nch == 0) return;

   char *fname = StrDup(filename);
   if (fname[nch-1] == ';') { nch--; fname[nch]=0;}

   ifstream file(fname,ios::in);
   if (!file.good()) {
      Error("ReadFile", "illegal file name");
      delete [] fname;
      return;
   }

   const int linesize = 255;
   char currentline[linesize];
   char *ss, *sclose, *s= 0;

   Int_t kline = 0;
   while (1) {
     file.getline(currentline,linesize);
     if (file.eof())break;
     if (kline >= fromline && kline < fromline+nlines) {
        s = currentline;
        if (strstr(s,"+SetText")) {
           ss = s+8;
           sclose = strstr(ss,")");
           if (!sclose) continue;
           *sclose = 0;
           lastline = (TText*)fLines->Last();
           if (!lastline) continue;
           if (strstr(ss,"Color(")) {
              sscanf(ss+6,"%d",&ival);
              lastline->SetTextColor(ival);
              continue;
           }
           if (strstr(ss,"Align(")) {
              sscanf(ss+6,"%d",&ival);
              lastline->SetTextAlign(ival);
              continue;
           }
           if (strstr(ss,"Font(")) {
              sscanf(ss+5,"%d",&ival);
              lastline->SetTextFont(ival);
              continue;
           }
           if (strstr(ss,"Size(")) {
              sscanf(ss+5,"%f",&val);
              lastline->SetTextSize(val);
              continue;
           }
           if (strstr(ss,"Angle(")) {
              sscanf(ss+6,"%f",&val);
              lastline->SetTextAngle(val);
              continue;
           }
        }
        AddText(s);
      }
      kline++;
  }
  file.close();
  delete [] fname;

}

//______________________________________________________________________________
void TPaveText::SaveLines(ofstream &out, const char *name)
{
    // Save lines of this pavetext as C++ statements on output stream out

   if (!fLines) return;
   Int_t nlines = GetSize();
   if (nlines == 0) return;

//*-*- Iterate over all lines
   char quote = '"';
   TObject *line;
   TText *linet;
   TLatex *latex;
   TLine *linel;
   TBox  *lineb;
   TIter next(fLines);
   while ((line = (TObject*) next())) {
//*-*- Next primitive is a line
      if (line->IsA() == TLine::Class()) {
         linel = (TLine*)line;
         if (gROOT->ClassSaved(TLine::Class())) {
             out<<"   ";
         } else {
             out<<"   TLine *";
         }
         out<<"line = "<<name<<"->AddLine("
            <<linel->GetX1()<<","<<linel->GetY1()<<","<<linel->GetX2()<<","<<linel->GetY2()<<");"<<endl;
         if (linel->GetLineColor() != 1) {
            out<<"   line->SetLineColor("<<linel->GetLineColor()<<");"<<endl;
         }
         if (linel->GetLineStyle() != 1) {
            out<<"   line->SetLineStyle("<<linel->GetLineStyle()<<");"<<endl;
         }
         if (linel->GetLineWidth() != 1) {
            out<<"   line->SetLineWidth("<<linel->GetLineWidth()<<");"<<endl;
         }
         continue;
      }
//*-*- Next primitive is a box
      if (line->IsA() == TBox::Class()) {
         lineb = (TBox*)line;
         if (gROOT->ClassSaved(TBox::Class())) {
             out<<"   ";
         } else {
             out<<"   TBox *";
         }
         out<<"box = "<<name<<"->AddBox("
            <<lineb->GetX1()<<","<<lineb->GetY1()<<","<<lineb->GetX2()<<","<<lineb->GetY2()<<");"<<endl;
         if (lineb->GetFillColor() != 18) {
            out<<"   box->SetFillColor("<<lineb->GetFillColor()<<");"<<endl;
         }
         if (lineb->GetFillStyle() != 1001) {
            out<<"   box->SetFillStyle("<<lineb->GetFillStyle()<<");"<<endl;
         }
         if (lineb->GetLineColor() != 1) {
            out<<"   box->SetLineColor("<<lineb->GetLineColor()<<");"<<endl;
         }
         if (lineb->GetLineStyle() != 1) {
            out<<"   box->SetLineStyle("<<lineb->GetLineStyle()<<");"<<endl;
         }
         if (lineb->GetLineWidth() != 1) {
            out<<"   box->SetLineWidth("<<lineb->GetLineWidth()<<");"<<endl;
         }
         continue;
      }
//*-*- Next primitive is a text
      if (line->IsA() == TText::Class()) {
         linet = (TText*)line;
         if (gROOT->ClassSaved(TText::Class())) {
             out<<"   ";
         } else {
             out<<"   TText *";
         }
         if (!linet->GetX() && !linet->GetY()) {
            TString s = linet->GetTitle();
            s.ReplaceAll("\"","\\\"");
            out<<"text = "<<name<<"->AddText("
               <<quote<<s.Data()<<quote<<");"<<endl;
         } else {
            out<<"text = "<<name<<"->AddText("
               <<linet->GetX()<<","<<linet->GetY()<<","<<quote<<linet->GetTitle()<<quote<<");"<<endl;
         }
         if (linet->GetTextColor()) {
            out<<"   text->SetTextColor("<<linet->GetTextColor()<<");"<<endl;
         }
         if (linet->GetTextFont()) {
            out<<"   text->SetTextFont("<<linet->GetTextFont()<<");"<<endl;
         }
         if (linet->GetTextSize()) {
            out<<"   text->SetTextSize("<<linet->GetTextSize()<<");"<<endl;
         }
         if (linet->GetTextAngle() != GetTextAngle()) {
            out<<"   text->SetTextAngle("<<linet->GetTextAngle()<<");"<<endl;
         }
         if (linet->GetTextAlign()) {
            out<<"   text->SetTextAlign("<<linet->GetTextAlign()<<");"<<endl;
         }
      }
//*-*- Next primitive is a Latex text
      if (line->IsA() == TLatex::Class()) {
         latex = (TLatex*)line;
         if (gROOT->ClassSaved(TLatex::Class())) {
             out<<"   ";
         } else {
             out<<"   TText *";
         }
         if (!latex->GetX() && !latex->GetY()) {
            TString sl = latex->GetTitle();
            sl.ReplaceAll("\"","\\\"");
            out<<"text = "<<name<<"->AddText("
               <<quote<<sl.Data()<<quote<<");"<<endl;
         } else {
            out<<"text = "<<name<<"->AddText("
               <<latex->GetX()<<","<<latex->GetY()<<","<<quote<<latex->GetTitle()<<quote<<");"<<endl;
         }
         if (latex->GetTextColor()) {
            out<<"   text->SetTextColor("<<latex->GetTextColor()<<");"<<endl;
         }
         if (latex->GetTextFont()) {
            out<<"   text->SetTextFont("<<latex->GetTextFont()<<");"<<endl;
         }
         if (latex->GetTextSize()) {
            out<<"   text->SetTextSize("<<latex->GetTextSize()<<");"<<endl;
         }
         if (latex->GetTextAngle() != GetTextAngle()) {
            out<<"   text->SetTextAngle("<<latex->GetTextAngle()<<");"<<endl;
         }
         if (latex->GetTextAlign()) {
            out<<"   text->SetTextAlign("<<latex->GetTextAlign()<<");"<<endl;
         }
      }
   }
}

//______________________________________________________________________________
void TPaveText::SavePrimitive(ofstream &out, Option_t *)
{
    // Save primitive as a C++ statement(s) on output stream out

//   if (!strcmp(GetName(),"stats")) return;
//   if (!strcmp(GetName(),"title")) return;
   char quote = '"';
   out<<"   "<<endl;
   if (gROOT->ClassSaved(TPaveText::Class())) {
       out<<"   ";
   } else {
       out<<"   "<<ClassName()<<" *";
   }
   if (fOption.Contains("NDC")) {
      out<<"pt = new "<<ClassName()<<"("<<fX1NDC<<","<<fY1NDC<<","<<fX2NDC<<","<<fY2NDC
      <<","<<quote<<fOption<<quote<<");"<<endl;
   } else {
      out<<"pt = new "<<ClassName()<<"("<<gPad->PadtoX(fX1)<<","<<gPad->PadtoY(fY1)<<","<<gPad->PadtoX(fX2)<<","<<gPad->PadtoY(fY2)
      <<","<<quote<<fOption<<quote<<");"<<endl;
   }
   if (strcmp(GetName(),"TPave")) {
      out<<"   pt->SetName("<<quote<<GetName()<<quote<<");"<<endl;
   }
   if (fLabel.Length() > 0) {
      out<<"   pt->SetLabel("<<quote<<fLabel<<quote<<");"<<endl;
   }
   if (fBorderSize != 4) {
      out<<"   pt->SetBorderSize("<<fBorderSize<<");"<<endl;
   }
   SaveFillAttributes(out,"pt",0,1001);
   SaveLineAttributes(out,"pt",1,1,1);
   SaveTextAttributes(out,"pt",22,0,1,62,0);
   SaveLines(out,"pt");
   out<<"   pt->Draw();"<<endl;
}

//______________________________________________________________________________
void TPaveText::SetAllWith(const char *text, Option_t *option, Double_t value)
{
//*-*-*-*-*-*Set attribute option for all lines containing string text*-*-*-*-*
//*-*        ================= =======================================
//
// Possible options are all the AttText attributes
//       Align, Color, Font, Size and Angle
//

   TString opt=option;
   opt.ToLower();
   TText *line;
   TIter next(fLines);
   while ((line = (TText*) next())) {
      if (strstr(line->GetTitle(),text)) {
         if (opt == "align") line->SetTextAlign(Int_t(value));
         if (opt == "color") line->SetTextColor(Int_t(value));
         if (opt == "font")  line->SetTextFont(Int_t(value));
         if (opt == "size")  line->SetTextSize(value);
         if (opt == "angle") line->SetTextAngle(value);
      }
   }
}

//______________________________________________________________________________
void TPaveText::Streamer(TBuffer &R__b)
{
   // Stream an object of class TPaveText.

   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
      if (R__v > 1) {
         TPaveText::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c);
         return;
      }
      //====process old versions before automatic schema evolution
      TPave::Streamer(R__b);
      TAttText::Streamer(R__b);
      if (R__v > 1) fLabel.Streamer(R__b);
      R__b >> fLongest;
      R__b >> fMargin;
      R__b >> fLines;
      R__b.CheckByteCount(R__s, R__c, TPaveText::IsA());
      //====end of old versions

   } else {
      TPaveText::Class()->WriteBuffer(R__b,this);
   }
}
