// $Source: /usr/local/SimSoft/Sfx3D/src/gts/gtspal.cpp,v $
// $Revision: 1.2 $
// $Author: baum $
// $Date: 2001/11/29 15:18:10 $
//
// Login name of the user who locked the revision
// $Locker:  $
// Tag name used to checkout the file
// $Name: Release-14 $
// State assigned to revision
// $State: Exp $
//
//
// $Log: gtspal.cpp,v $
// Revision 1.2  2001/11/29 15:18:10  baum
// -Realzeitsteuerung eingebaut
// -Handsteuerung eingebaut
//

/*** Windows headers ***/
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
//#include <winnt.h>
#endif /*WIN32*/

#include "gtsglob.h"
#include "gtspal.h"
#include "XGraph/AllViews.h" // to use UnitPrimitives in "UnitPrim.h"

//==================================================================
//		Declaration
//		for class Bibliothek
//==================================================================

Bibliothek::Bibliothek (Ustring name)
{
  DatName = name;
  Oeffnen ();
  leseOffset ();
  leseInhaltverzeichnis ();
  Schliessen ();
//  AusgabeInhaltsverzeichnis ();
};  // ENDE Bibliothek

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bibliothek::~Bibliothek ()
{
  while (!BasisListe.isEmpty())
         delete BasisListe.removeFirst();
};  // ENDE ~Bibliothek

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Bibliothek::leseBasisNamen ()
{
  SFXToken tok;
  LCursor<Basis> zhilfe;
  unsigned satz;
  
  for (zhilfe = BasisListe; zhilfe; zhilfe++)
  {
    satz = zhilfe()->getTyp() * getTypMulti() + getTypOffset();
    if (!tok.findSentence (satz, *fbib))
       Msg.Error ("Bibliothek::leseNamen()",
                  "Satznr.= %d in TGB-Datei nicht vorhanden", satz);

    tok.nextToken (*fbib);
    tok.nextToken (*fbib); 
    zhilfe()->setName (tok());
    tok.EndOfLine (*fbib);
  }
}  // ENDE leseBasisNamen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Bibliothek::leseInhaltverzeichnis ()
{
  SFXToken tok;
  tok.Reset (*fbib);
  if (!tok.findSentence (2, *fbib))
       Msg.Error ("Bibliothek::LeseInhaltverzeichnis()",
                  "Satznr.= 2 in TGB-Datei nicht vorhanden");

  tok.nextToken (*fbib);
  int AnzEintraege = atoi (tok());
  tok.EndOfLine (*fbib);

  if (!tok.findSentence (3, *fbib))
       Msg.Error ("Bibliothek::LeseInhaltverzeichnis()",
                  "Satznr.= 3 in TGB-Datei nicht vorhanden");

   int bTyp, vTyp;
   for (int i = 1; i <= AnzEintraege; i++)
   {
     tok.nextToken (*fbib);  bTyp = atoi (tok());
     tok.nextToken (*fbib);  vTyp = atoi (tok());
     erzeugeInhaltsverzeichnis (bTyp, vTyp);
     if (i % 8 == 0)
	 {
       tok.EndOfLine (*fbib);
       tok.nextToken (*fbib);  
	 }
   }
   tok.EndOfLine (*fbib);
   leseBasisNamen();
}  // ENDE leseInhaltverzeichnis

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Bibliothek::erzeugeInhaltsverzeichnis (const unsigned bTyp, const unsigned vTyp)
{
  LCursor<Basis> zBasis = isObjectInListe (bTyp);

  if (zBasis == NULL)
  {
    Basis *zhilfe = new Basis (bTyp);
    EndeGliedern (*zhilfe);
    setVarianteInListe (*zhilfe, bTyp, vTyp);
  }
  else
  setVarianteInListe (*zBasis(), bTyp, vTyp);
}  //  ENDE erzeugeInhaltsverzeichnis

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LCursor<Basis> Bibliothek::isObjectInListe (const unsigned btyp)
{
   LCursor<Basis> zhilfe;

   for (zhilfe = BasisListe;
       (zhilfe && (zhilfe()->getTyp() != btyp)); zhilfe++) ;
   return zhilfe;
}  // ENDE BsttypInListe

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Bibliothek::setVarianteInListe
            (Basis &zhilfe, const unsigned btyp, const unsigned vtyp)
{
   Variante *z1hilfe = new Variante (btyp, vtyp);
   zhilfe.append (*z1hilfe);
}  // setVarianteInListe

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Bibliothek::AusgabeInhaltsverzeichnis ()
{
   Write ("PALTGB:  --->  %s\n", DatName.str());
   LCursor<Basis> zhilfe;
   for (zhilfe = BasisListe; zhilfe ; zhilfe++)
   {
     zhilfe()->AusgabeInhaltsverzeichnis ();
   }
}  // ENDE AusgabeInhaltsverzeichnis

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Bibliothek::leseOffset (void)
{
  SFXToken tok;
  if (!tok.findSentence (5, *fbib))
       Msg.Error ("Bibliothek::leseOffset()",
                  "Satznr.= 5 in TGB-Datei nicht vorhanden");

  tok.nextToken (*fbib);   ObjTypOffset    = atoi (tok());
  tok.nextToken (*fbib);   ObjTypMulti     = atoi (tok());
  tok.nextToken (*fbib);   ObjVarMulti     = atoi (tok());
  tok.nextToken (*fbib);   ObjSegOffset    = atoi (tok());
  tok.nextToken (*fbib);   ObjNumPosOffset = atoi (tok());
  tok.nextToken (*fbib);   ObjSymPosOffset = atoi (tok());
  tok.nextToken (*fbib);   ObjInfo1Offset  = atoi (tok());
  tok.nextToken (*fbib);   ObjInfo2Offset  = atoi (tok());
  tok.nextToken (*fbib);   ObjInfo3Offset  = atoi (tok());
  tok.nextToken (*fbib);   ObjTextOffset   = atoi (tok());
}  // leseOffset

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Bibliothek::Oeffnen ()
{
  fbib = new InputFile (DatName.str());
} // Oeffnen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Bibliothek::Schliessen ()
{
  fbib->close();
  delete fbib;
}  // Schliessen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Bibliothek::leseObject (const unsigned btyp, const unsigned vtyp)
{
  Variante *zObject = findObject (btyp, vtyp);

  if (!zObject) 
  {
    Msg.Warning ("Bibliothek::leseOffset()",
                  "Basistyp=%d, Varianttyp=%d in Bibliothek nicht gefunden",
                   btyp, vtyp);
    return false;
  }
  else
  if (!(zObject->gelesen())) zObject->read (*fbib);  // wurde schon gelesen?!

  return true;
}  // ENDE leseObject

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Variante* Bibliothek::findObject (const unsigned btyp, const unsigned vtyp)
{
   LCursor<Basis> zhilfe;
   for (zhilfe = BasisListe; zhilfe; zhilfe++)
       if ((zhilfe()->getTyp() == btyp)) break;

   if (zhilfe != NULL)
     return zhilfe()->findVariante (vtyp);
   return NULL;
}  // ENDE findObject

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ustring Bibliothek::getPalettenInfos (const int ptyp)
{
  Ustring buf;
  LCursor<Basis> zhilfe;
  if (ptyp < 0)
  {
    for (zhilfe = BasisListe; zhilfe ; zhilfe++)
    {
      buf += "{";
      buf += Ustring(zhilfe()->getTyp()) + "=" + zhilfe()->getName();
      buf += "}\t";
    }
    return buf;
  }
  else
  if (ptyp == 0)
  {
    zhilfe = BasisListe;
    if (zhilfe)
    {
      buf += "{";
      buf += Ustring(zhilfe()->getTyp()) + "=" + zhilfe()->getName();
      buf += "}\t";
    }
    return buf;
  }
  else
  {
    for (zhilfe = BasisListe; zhilfe ; zhilfe++)
      if (zhilfe()->getTyp() == (unsigned) ptyp) break;

    if (!zhilfe) return Ustring("{Variante fehlt}\t");

    buf += "{";
    buf += Ustring(zhilfe()->getTyp()) + "=" + zhilfe()->getName();
    buf += "}\t";
    return buf;
  }
} // ENDE getPalettenInfos

//==================================================================
//		Declaration
//		for class BstBasis
//==================================================================

Basis::Basis (unsigned typ)
  : ObjName (), ObjTyp (typ), ObjVariantListe ()
 { }

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Basis::~Basis () {
  while (!ObjVariantListe.isEmpty())
    delete ObjVariantListe.removeFirst();
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Basis::read (InputFile *fin, const unsigned beginSatz, const unsigned variantSatz)
{
  SFXToken tok;
  for (LCursor<Variante> zhilfe (ObjVariantListe); zhilfe; zhilfe++)
  {
    if (!tok.findSentence (beginSatz + zhilfe()->getVariante() * variantSatz, *fin))
       Msg.Error ("Basis::read()",
                  "Satznr.= %d in TGB-Datei nicht vorhanden",
                   beginSatz + zhilfe()->getVariante() * variantSatz);

    tok.nextToken (*fin);
    tok.nextToken (*fin);
    tok.nextToken (*fin);
    tok.nextToken (*fin);
    tok.nextToken (*fin);
    zhilfe()->setName (tok());
    tok.EndOfLine (*fin);
    zhilfe()->read (*fin);
  }
}  //  ENDE read

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Basis::append (const Variante& newVariante) {
  ObjVariantListe.append (newVariante);
}  // ENDE append

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Variante* Basis::findVariante (const unsigned variante) const
{
  for (LCursor<Variante> zhilfe (ObjVariantListe); zhilfe; zhilfe++)
    if ((zhilfe()->getVariante() == variante))
      return zhilfe();

  Msg.Warning ("Basis::findVariante",
                "Variante %d nicht gefunden", variante);
  return NULL;
}  // ENDE findVariante

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Basis::AusgabeInhaltsverzeichnis ()
{
  Write ("\nBasisTyp=%d  ", ObjTyp);
  Write ("==>%s<\n", ObjName.str());

  for (LCursor<Variante> zhilfe = ObjVariantListe; zhilfe ; zhilfe++) {
    Write ("     VariantTyp=%d  ", zhilfe()->getVariante());
    Write ("==>%s<\n", zhilfe()->getName().str());
  }
}  //  ENDE  AusgabeInhaltsverzeichnis

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Basis::setName (const char *name) {
  ObjName = Ustring (name);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Basis::setName (const Ustring& name) {
  ObjName = name;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unsigned Basis::getTyp  () const {
  return ObjTyp;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Ustring& Basis::getName () const {
  return ObjName;
}

//==================================================================
//		Declaration
//		for class Variante
//==================================================================

/*static*/ Attribute* Variante::ClassPermAttribute = ColorAttribute::create ("ForestGreen");

Variante::Variante (const unsigned typ, const unsigned variante)
 : ObjName (),          ObjTyp (typ),       ObjVariante (variante),
   ObjFlusswinkel (),   ObjKonturen (2),    ObjGelesen (false)
  { }

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Variante::~Variante () {
  while (ObjKonturen.Last()) ObjKonturen.removeLast()->dispose();
}  //  ENDE ~Variante

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Variante::read (InputFile& fin)
{
  SFXToken tok;
  unsigned begin  = ObjTyp      * PalBibliothek->getTypMulti() +
                    ObjVariante * PalBibliothek->getVarMulti() +
                    PalBibliothek->getTypOffset();
  unsigned satznr = begin;

  if (!tok.findSentence (satznr, fin))
       Msg.Error ("Variante::read()",
                  "Satznr.= %d in TGB-Datei nicht vorhanden", satznr);

  tok.nextToken (fin);
  tok.nextToken (fin);
  tok.nextToken (fin);
  tok.nextToken (fin);
  ObjFlusswinkel = Angle (atof(tok()));

  Pattern* pat = Pattern::create ();
  tok.nextToken (fin);
  pat->setName (tok());
  ObjKonturen.append (*pat);
  tok.EndOfLine (fin);

  satznr = begin + PalBibliothek->getSegOffset();
  if (!tok.findSentence (satznr, fin))
       Msg.Error ("Variante::read()",
                  "Satznr.= %d in TGB-Datei nicht vorhanden", satznr);
  readKontur (fin);

  ObjGelesen = true;
}  //  ENDE read

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Variante::setName (const char *name) {
  ObjName = Ustring (name);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Variante::setName (const Ustring& name) {
  ObjName = name;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unsigned  Variante::getTyp       () const {
  return ObjTyp;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unsigned  Variante::getVariante  () const {
  return ObjVariante;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Ustring& Variante::getName      () const {
  return ObjName;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const DynArray<Pattern> Variante::Konturen () const {
  return ObjKonturen;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Variante::readKontur (InputFile&)
{
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attribute* Variante::findAttribute (const float& r, const float& g, const float& b) {
  Ustring name (r); name += g; name += b;
  return Attribute::find (name.str ());
}

