
// Konzept:
// Menutype kriegt nur seine Events
// und hat aber auch nen calc();
// dann gibt es ein topmenu das die events des scr getted
// mit get_mausclicks(); (für die childs)
// calc -> verarbeitemausclicks () ??

// todo :
/*
Also buttons sind scheisse
viel zu viel aufwand welche zu kreieren
modifiedpushbutton ist eigentlich geil
damit kann man einige standard buttons machen
und diese dann verschieben und nen text davorhaengen falls noetig
die muessen sich laden und speichern koennen
dabei evtl. problem mit ableiten ??

Ziel:
Aus Bild mach Button
Und aus Button mach ModiefiedButton :-)))
*/

#include "iotype.H"
#include "sprite01.H"
#include <strstream.h>
#include <string>

// event_managertype **********************************************************************
// event_managertype **********************************************************************
// event_managertype **********************************************************************
// event_managertype **********************************************************************
// event_managertype **********************************************************************
// event_managertype **********************************************************************

/// Event Manager class
class event_managertype 
  : public rechtecktype, public zeigerelemtype<event_managertype>
{
public:
  // Typeinfo - Attention static =>  wird nicht vererbt !!! => use getheaderstring() (must be public)
  static const char *headerstring;
  // Get typename of object
  virtual const char *getheaderstring(){return headerstring;}
  // Create Event Manager from io buffer
  static event_managertype *create(iotype *ioptr,int8 mode);
  // Create Event Manager from file
  static event_managertype *create(const char *name)
  {
    iotype *ioptr=make_file_to_io_check(name);
    event_managertype *erg=create(ioptr,CFG_TEXT_MODE);
    delete ioptr;
    return erg;
  }

  event_managertype();
  virtual ~event_managertype();

  // Set parent sprite (sprite under this Event Manager)
  virtual void set_parentspriteptr(sprite_lineartype *_parentspriteptr);
  // Set output Buffer
  virtual void reset_ausgabe(ostream *_ausgabe);

  // calculate (normaly this should paint this Event Manager) see also listen2.H
  virtual int calc()=0;
  // paint into rectangle
  virtual int calc(const rechtecktype &rect)
    {return 0;}
  // Paint all parents into this rectangle (to restore background)
  virtual void paintparent(const rechtecktype &rect)
    {
      if (parent)
	parent->paintparent(rect);
      else
	calc(rect);
    }

  // Parse a input stream
  // returns 0 <=> understood input stream and deleted it   !=0 <=> didn't understand this event
  virtual int verarbeite_input(istream *ist)=0;

  // Test ButtonPress
  // NB: 0 <=> This is a mouseclick,  !=0 no mouseclick   
  // Stream is always "unchanged"
  inline int test_mausclick_input(istream *ist,int32 *y,int32 *y,int *button);
  
  // Get mouseclicks (ButtonPress) 
  // NB: 0 <=> Event is a mouseclick it is used and the stream is deleted !=0 <=> didn't understand this event
  int verarbeite_mausclick_input(istream *ist,int32 *x,int32 *y,int *button);

  // fetch output
  virtual istream &get_output();

  // set parent Event Manager
  void set_parent(event_managertype *_parent){parent=_parent;}

protected:
  // buffer
  strstreambuf *buffer;
  // output stream 
  ostream *ausgabe;
  // input stream
  istream *eingabe;
  // parent sprite
  sprite_lineartype *parentspriteptr;
  // do i have a own buffer ?
  int privatebuffer;
  // parent Event Manager
  event_managertype *parent;
private:
  // free buffer (if it is my private buffer)
  void deinit();
};





// root_event_managertype **********************************************************************
// root_event_managertype **********************************************************************
// root_event_managertype **********************************************************************
// root_event_managertype **********************************************************************
// root_event_managertype **********************************************************************


/// This is a event Manager which is able to get Events
/// f.e. the first Window (in this Window are all subwindows)
/// See also scrX11.H (sprite_linear_nontransparent_screentype)
/*
class root_event_managertype : public event_managertype
{
public:
  // Fetch all events and parse them 
  // returns 0 if everything is okay !=0 <=> close me
  int calc();
  // Get one Event 
  // Return event or NULL (non available)
  virtual istream *get_input()=0;
};
*/


// menutype ***************************************************************************
// menutype ***************************************************************************
// menutype ***************************************************************************
// menutype ***************************************************************************
// menutype ***************************************************************************
// menutype ***************************************************************************

/// Menu class (Submenu container)
class menutype : public event_managertype
{
public:
  // Typeinfo -Achtung statisch wird nicht vererbt !!! =>benutze getheaderstring() muss aber public sein!
  static const char *headerstring;
  const char *getheaderstring(){return headerstring;}

  menutype();
  ~menutype();

  // Paint me and my submenus
  int calc();
  // Paint me and my submenus into rectangle
  int calc(const rechtecktype &rect);

  void set_parentspriteptr(sprite_lineartype *_parentspriteptr);
  sprite_lineartype *get_parentspriteptr() const {return parentspriteptr;}

  void reset_ausgabe(ostream *_ausgabe);
  void change(iotype *ioptr,int8 mode);

  // Leitet den Event an den entsprechenden child weiter !!
  int verarbeite_input(istream *ist);

  event_managertype *addmenu(const char *filename);
  void addmenu(event_managertype *neu);

  // Kill all submenus
  void killmenus();
  void killmenu(event_managertype *menu);

  // return no of submenus
  uint32 anzmenus();
private:
  kette_changetype<event_managertype> childkette;
  // Menu Background 
  string spritename;
  spritetype *spriteptr;
  string defaultout;
  void init();
};


// buttontype ************************************************************
// buttontype ************************************************************
// buttontype ************************************************************
// buttontype ************************************************************
// buttontype ************************************************************

class buttontype : public event_managertype
{
public:
  static const char *headerstring;
  const char *getheaderstring(){return headerstring;}

  buttontype()
  {
    spriteptr=NULL;
    maxpect=false;
  }
  buttontype(spritetype *_spriteptr,const char *_msg,int32 _posx,int32 _posy)
  {
    spriteptr=_spriteptr;
    posx=_posx;
    posy=_posy;
    mx=spriteptr->mx-posx;
    my=spriteptr->my-posy;
    sx=spriteptr->sx;
    sy=spriteptr->sy;
    msg=_msg;
    maxpect=false;
  }
  buttontype(const string &_spritename,const char *_msg,const rechtecktype &rect) : spritename(_spritename)
    {
      *((rechtecktype *)this)=rect;
      maxpect=true;
      if (spritename!="")
	spriteptr=allsprites_ketteptr->make_elementadress(spritename.c_str());
      else 
	spriteptr=NULL;
      msg=_msg;
    }
  
  ~buttontype()
    {
      if (spritename!="")
	allsprites_ketteptr->delete_elementadress(spriteptr);
    }
  // Male buttontype (sprite)
  int calc();
  int calc(const rechtecktype &rect);

  int verarbeite_input(istream *ist);
  void change(iotype *ioptr,int8 mode);
  void set_msg(const string &_msg){msg=_msg;}
private:
  int32 posx,posy;
  spritetype *spriteptr;
  string msg;
  string spritename;
  bool maxpect;
};


// pushbuttontype **********************************************************************
// pushbuttontype **********************************************************************
// pushbuttontype **********************************************************************
// pushbuttontype **********************************************************************
// pushbuttontype **********************************************************************
// pushbuttontype **********************************************************************




class pushbuttontype : public event_managertype
{
public:
  // Typeinfo -Achtung statisch wird nicht vererbt !!! =>benutze getheaderstring() muss aber public sein!
  static const char *headerstring;
  const char *getheaderstring(){return headerstring;}

  pushbuttontype();
  ~pushbuttontype();

  // Male Pushbuttontype
  int calc();
  int calc(const rechtecktype &rect);
  void setindex(int32 _index);

  void change(iotype *ioptr,int8 mode);
  int verarbeite_input(istream *ist);
  
protected:
  // wird von calc aufgerufen 
  void ipaint(int x,int y);
  void ipaint(int x,int y,const rechtecktype &rect);

  uint32 aktindex;
  string_zeigerelemtype *aktmessage;
  kette_changetype <string_zeigerelemtype> messages;
  string spritename;
  spritetype *spriteptr;
  
private:
  void init();
  void deinit();
};





// modified_pushbuttontype **********************************************************************
// modified_pushbuttontype **********************************************************************
// modified_pushbuttontype **********************************************************************
// modified_pushbuttontype **********************************************************************
// modified_pushbuttontype **********************************************************************

// Ist nicht dazu da geladen und gespeichert zu werden sondern um direkt konstrukturiert zu werden !

class modified_pushbuttontype : public pushbuttontype
{
public:
  // Typeinfo -Achtung statisch wird nicht vererbt !!! =>benutze getheaderstring() muss aber public sein!
  static const char *headerstring;
  const char *getheaderstring(){return headerstring;}

  modified_pushbuttontype(){};
  modified_pushbuttontype(const char *filename,const char *_prefix,int32 _relx,int32 _rely);
  int verarbeite_input(istream *ist);
  void change(iotype *ioptr,int8 mode);
  int calc();
  int calc(const rechtecktype &rect);

private:
  string prefix;
  int32 relx,rely;
};







