
#include "scrX11.H"
//#include "menu.H"
#include <map>

typedef map<string,layertype *, less<string> >::iterator layerit;
typedef map<string,layer_spritetype *, less<string> >::iterator spriteit;

class game_engine
{
public:
  // One line input
  game_engine()
  {
    scr=NULL;
    window=NULL;
    pal="";
  }
  ~game_engine()
  {
    if (scr!=NULL)
      delete scr;
    if (window!=NULL)
      delete window;
    if (pal!="")
      deinit_allsprites_kette();
  }
  
  istream& input(istream& ist)
  {
    string cmd;
    ist >> cmd;
    if (cmd=="list")
      {
	string cmd2;
	ist >> cmd2;
	if (cmd2=="sprites")
	  {
	    spriteit pos;
	    int no=0;
	    for (pos=sprites.begin();pos!=sprites.end();pos++,no++)
	      {
		cout <<no<<": "<<(*pos).first<<" "<<(*pos).second<<endl;
	      }
	  }
	else if (cmd2=="layers")
	  {
	    layerit pos;
	    int no=0;
	    for (pos=layers.begin();pos!=layers.end();pos++,no++)
	      {
		cout <<no<<": "<<(*pos).first<<" "<<(*pos).second<<endl;
	      }
	  }
      }
    else if (cmd=="pal")
      {
	ist >>pal;
	// Initialisation - use palette file "palette.ppm"
	// Attention the library always uses 8 Bit intern
	init_allsprites_kette(pal.c_str());
      }
    else if (cmd=="window")
      {
	string name;
	ist >>name;
	int mx,my,sx,sy;
	ist >>mx>>my>>sx>>sy;
	// Open a window s.a. scrX11.H
	//	if (ist.good())
	  {
	    window=new sprite_linear_nontransparent_screentype(0,0,sx,sy,mx,my,
							       pal.c_str(),name.c_str());
	    // Make a new screen 
	    // this is to use layers based on window as drawable (container for the layers)
	    scr=new screentype(window);
	  }
      }
    else if (cmd=="sprite")
      {
	string name;
	ist >>name;
       	if (ist.good())
	  {
	    spriteit pos;
	    pos=sprites.find(name);
	    if (pos!=sprites.end())
	      {
		cout <<"Sprite found\n";
		layer_spritetype *spr=(*pos).second;
		
		string cmd2;
		ist >>cmd2;
		if (cmd2=="modify")
		  {
		    int x=0,y=0;
		    float dir=0,zoom=1.0;
		    ist >>x>>y>>dir>>zoom;
		    spr->modify_sprite(x,y,dir,zoom);
		  }
		else if (cmd2=="delete")
		  {
		    (spr->get_layer())->del_sprite(spr);
		  }
		else
		  cerr <<"game_engine::input(): Should do something unknown \""<<cmd2<<"\" with sprite \""<<name<<"\""<<endl;
	      }
	    else
	      cerr << "game_engine::input(): Should modify unknown sprite \""<<name<<"\""<<endl;
	  }
      }
    else if (cmd=="new")
      {
	string cmd2;
	ist>>cmd2;
	if (cmd2=="layer")
	  {
	    string name;
	    ist >> name;
	    // Add a layer
	    cout <<"Added Layer "<<name<<endl;
	    layertype *n=scr->add_layer();
	    layers[name]=n;
	  }
	else if (cmd2=="sprite")
	  {
	    string lname;
	    string name;
	    string source;
	    ist >>lname>>name>>source;
	    int x=0,y=0;
	    float dir=0,zoom=1.0;
	    //	    if (ist.good())
	      {
		ist >>x>>y>>dir>>zoom;
		map<string ,layertype *, less<string> >::iterator pos;
		pos=layers.find(lname);
		if (pos!=layers.end())
		  {
		    cout <<"Layer found\n";
		    layertype *l=(*pos).second;
		    cout <<"Create sprite: "<<source.c_str()<<endl;
		    layer_spritetype *spr=l->add_sprite(source.c_str());
		    sprites[name]=spr;
		  }
		else
		  cerr << "game_engine::input(): Should add sprite \""<<name<<"\"to unknown layer \""<<lname<<"\""<<endl;
	      }
	  }
      }
    else
      {
	cerr <<"game_engine::input(): Unknown command \""<<cmd<<"\""<<endl;
      }
    return ist;
  }
private:
  sprite_linear_nontransparent_screentype *window;    
  string pal;
  screentype *scr;
  map<string, layertype *, less<string> > layers;
  
  
  map<string, layer_spritetype *, less<string> > sprites;
  
};

int main()
{
  game_engine game;
  string cmd;
  while (getline(cin,cmd))
    {
      streambuf *buf=new strstreambuf(cmd.c_str(),cmd.length());
      istream ist(buf);
      game.input(ist);
    }



  /*
  while (1)
    {
      int xcon=RAND_MAX/800;
      int ycon=RAND_MAX/600;
      int con=RAND_MAX/255;
      int x=(random()/xcon)-1;
      int y=(random()/ycon)-1;

      ball2->copysprite_clip(x-400,y-300,screen);
      rechtecktype rect(300,200,600,400);
      ball->copysprite_clip_to(x-400,y-300,screen,rect,0);
      int x1=x-ball->mx;
      int y1=y-ball->my;
      int x2=x1+ball->sx-1;
      int y2=y1+ball->sy-1;
        if (x1<0) x1=0;
      if (y1<0) y1=0;
      if (x2>=800) x2=799;
      if (y2>=600) y2=599;
      //      cout <<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;
      screen->map_box(x1,y1,x2-x1+1,y2-y1+1);
    }*/

      /*
	while (1)
      {
	int x=(random()/xcon)-1;
	int y=(random()/ycon)-1;
	int farbe=(random()/con)-1;
	screen->fuellen(x,y,farbe);
	screen->map();
      }*/
  //  deinit_allsprites_kette(); 

}






