/* CEDITOR */

#include <allegro.h>
#include <gstream.h>
#include "CMap.hpp"
#include "CDisplay.hpp"
#include "CMain.hpp"
#include "Interaction.hpp"

CApp App;		// R. I. P.
CCam cam;		// L. V. B.
CMap map;

//TODO: this is a hack, also contained in cmain.cpp
BITMAP *text_box;

int cur_gfx = 0;
int cur_layer = 0;
int cur_sprite = 0;
int fill_gfx = 0;

void ResetTimers()
{
     App.timer = 0;
     speed_counter = 0;
}

int key_space = 0;
int key_rctrl = 0;
int key_lctrl = 0;

char *Do_PortalSelect()
{
	char buffer[1024];
	memset(&buffer,0,sizeof(char)*1024);
	
	if (alert("Select where the portal leads to!", "", NULL, "OK", NULL, NULL, NULL) == 1)
	{
		if(file_select_ex("Portal leads to?", buffer, "map", 1000, 0, 0) )
		{
			if( exists(buffer) )
			{
			//	map.LoadTileset(buffer);
			//alert("Tileset loaded!", NULL, NULL, NULL, "Ok", NULL, NULL);
			}			
	
			else 
			{
			//alert("Couldn't Find Tileset", NULL, NULL, NULL, "Damn", NULL, NULL);
			}
			
			
		}
	}
	return buffer;
}


void Do_LoadTileset()
{
	char buffer[255];	
	memset(&buffer,0,sizeof(char)*255);
	strcpy(buffer,get_filename(buffer));
	//append_filename(buffer, (buffer), ".\\", 255);
	
	if (alert("Do you want to load a TILESET?", "The current tileset will be finito.", NULL, "Yes", "No", NULL, NULL) == 1)
	{
		if(file_select_ex("Load your map", buffer, "bmp", 1000, 0, 0) )
		{
			if( exists(buffer) )
			{
				map.LoadTileset(buffer);
				alert("Tileset loaded!", NULL, NULL, NULL, "Ok", NULL, NULL);
			}			
	
			else 
			{
				alert("Couldn't Find Tileset", NULL, NULL, NULL, "Damn", NULL, NULL);
			}
			
			
		}
	}
}

void Do_LoadSpriteset()
{
	char buffer[255];	
	memset(&buffer,0,sizeof(char)*255);
	strcpy(buffer,get_filename(buffer));
	//append_filename(buffer, (buffer), ".\\", 255);
	
	if (alert("Do you want to load a SPRITE-Set?", "The current spriteset will be finito.", NULL, "Yes", "No", NULL, NULL) == 1)
	{
		if(file_select_ex("Load your map", buffer, "bmp", 1000, 0, 0) )
		{
			if( exists(buffer) )
			{
				map.LoadSpriteset(buffer);
				alert("Spriteset loaded!", NULL, NULL, NULL, "Ok", NULL, NULL);
			}			
	
			else 
			{
				alert("Couldn't Find Spriteset", NULL, NULL, NULL, "Damn", NULL, NULL);
			}
			
			
		}
	}
}


int new_map()
{
	char buffer[255];
	gstream gs(screen);
	
	std::string name;
	int width, height, layers;
	
	gs.save_input_approver();	// first save old approver
	gs.set_input_approver(ia_allow_integer); // then set a digit approver
	
	gs.set_insert_mode(true);	// set insert mode
	gs.set_max_input_length(9);	// and max 9 digits
	
	clear_bitmap(screen);
	
	gs.set_input_approver(ia_allow_everything); // then set a digit approver
	gs.set_insert_mode(true);	// set insert mode
	gs.set_max_input_length(50);	// and max 9 digits
	gs.goto_xy(0,0);
	gs << "Enter map name: ";
	gs >> name;
	gs << "\n";
	
	gs.set_input_approver(ia_allow_integer); // then set a digit approver
	gs.set_insert_mode(true);	// set insert mode
	gs.set_max_input_length(9);	// and max 9 digits
	
	// Width of the map 
	gs << "Enter the Map Width: ";
	gs.set_input_string(itoa(map.GetWidth(), buffer,10));
	gs >> width;
	gs << "\n";
	
	// Height of the map
	gs << "Enter the Map Height: ";
	gs.set_input_string(itoa(map.GetHeight(), buffer,10));
	gs >> height;
	gs << "\n";
	
	/*
	// Max Layers
	gs << "Enter the Map Layer's: ";
	gs.set_input_string(itoa(map.GetLayers(), buffer,10));
	gs >> layers;
	*/

	gs << "\n\n Configurations:   #1 Walls(collide), Objs, (1 layer total)\n";
	gs << "                       #2 Overlapping Walls, Objs, Wall(collide) -- (2 layers total)\n";
	gs << "                       #3 ??? Can't think of one \n";
	
	gs << "Enter config: ";
	gs >> map.config;

	if(map.config == 1)
	{
		layers = 1;
	}
	
	else if(map.config == 2)
	{
		layers = 2;
	}
	
	else 
	{
		map.config = 1;
		layers = 1;
		
	}

	// TODO: shouldn't have 16x16 need to ask the user...
	map.InitMap(width, height, 16, 16, layers);
	map.name = name;
	
	return 0;
}

int loader()
{
	char buffer[255];	
	
	memset(&buffer,0,sizeof(char));
	strcpy(buffer,get_filename(buffer));
	append_filename(buffer, (buffer), ".\\data\\", 255);
	
	if (alert("Do you want to load a map?", "The current map will be lost.", NULL, "Yes", "No", NULL, NULL) == 1)
	{
		if(file_select_ex("Load your map", buffer, "MAP", 1000, 0, 0) )
		{
			if( exists(buffer) )
			{
				map.LoadMap(buffer, true);
				alert("Map loaded!", NULL, NULL, NULL, "Ok", NULL, NULL);
			}			
	
			else 
			{
				alert("Couldn't Find Map", NULL, NULL, NULL, "Damn", NULL, NULL);
			}
			
			
		}
	}

	//allegro_message("%d %d %d %s", map.portal.size(), map.portal[0].x, map.portal[0].y, map.portal[0].name.c_str());
	//strcpy(name_str, map.name.c_str());
}

int saver()
{	
	char buf[255];
	
	memset(&buf,0,sizeof(char));
	append_filename(buf, (buf), ".\\data\\", 255);

if (alert("Do you want to save this map?", NULL, NULL, "Yes", "No", NULL, NULL) == 1 )
	{	
	
	if(file_select_ex("Save your map", buf, "MAP", 1000, 0,  0))
	{
		if( exists(buf) )
			{
				if( alert("Are you sure you want to overwrite this map?", NULL, NULL, "Yes", "No", NULL, NULL) == 1 )
				{
					map.name = get_filename(buf);
					map.SaveMap(buf);
					alert("Saved!", NULL, NULL, NULL, "Ok", NULL, NULL);
				}
			}
			
			else 
			{
				map.name = get_filename(buf);
				map.SaveMap(buf);
				alert("Saved!", NULL, NULL, NULL, "Ok", NULL, NULL);
			}
	}
	
	}

	
//	strcpy(name_str,get_filename(buf));

}

int quitter(void)
{
   int r;
 
   r = alert3("Data may have been modified.",
	      "Do you want to save before quitting?", NULL,
	      "Save", "Quit", "Cancel", 's', 'q', 27);

/* Quit */
   if (r == 2)
   {
	   App.done = true;
	   return 1;
   }

 /* Cancel */  
   if (r == 3)
      return D_O_K;

/* Save */
   saver();
   return D_CLOSE;
}


// from the grabber sources
static MENU file_menu[32] =
{
   { "&New\t(ctrl+N)",               new_map,           NULL,       0, NULL  },	
   { "&Load\t(ctrl+L)",             loader,           NULL,       0, NULL  },
   { "&Save\t(ctrl+S)",             saver,            NULL,       0, NULL  },
   { "&Quit\t(ctrl+Q)",             quitter,          NULL,       0, NULL  },
   { NULL,                          NULL,             NULL,       0, NULL  }
};

static MENU menu[32] = 
{ 
   { "&File",                       NULL,             file_menu,  0, NULL  },
    { NULL,                          NULL,             NULL,       0, NULL  }
   
};

void EditorLogic()
{
	if (mouse_b & 2)
	{
		do_menu(menu, mouse_x, mouse_y);
	}

	if(mouse_b & 1)
	{
		if(mouse_y/map.sizeh+cam.y/map.sizeh < map.GetHeight() && mouse_x/map.sizew+cam.x/map.sizew < map.GetWidth())
		{
			map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].gfx = cur_gfx;
			if(key[KEY_RCONTROL] || key[KEY_LCONTROL])
      			SET_BIT(map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_WALKABLE);
            else if(key[KEY_DEL])
            {

                REMOVE_BIT(map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_WALKABLE);
       			map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].gfx = fill_gfx;
            }
            else
            	REMOVE_BIT(map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_WALKABLE);
		}
	}
	
	if(key[KEY_T]) Do_LoadTileset();
    if(key[KEY_Y]) Do_LoadSpriteset();
}


void RenderEditor(CMap &map)
{
	// Show all the map stats
	textprintf(Display.GetSurface(), font, 0, 0, makecol(255,0,0), "Name: %s", map.name.c_str() );
	textprintf(Display.GetSurface(), font, 200, 0, makecol(255,0,0), "TS: %s", map.tileset_name.c_str() );
	textprintf(Display.GetSurface(), font, 400, 0, makecol(255,0,0), "SS: %s", map.spriteset_name.c_str() );
	textprintf(Display.GetSurface(), font, 0, 10, makecol(255,0,0), "Width: %d Height: %d Layers: %d x %d y %d maxportal %d", map.GetWidth(), map.GetHeight(), map.GetLayers(), mouse_x/16+cam.x/16, mouse_y/16+cam.y/16, map.max_portal);
	textprintf(Display.GetSurface(), font, 0, 20, makecol(255,0,0), "CurLayer: %d Config: %d  CurGFX %d CurSprite %d Battle: %d Cine %d Cam y%d MAXEVENT %d", cur_layer, map.config, cur_gfx, cur_sprite, map.isbattle, map.cine_id, cam.y, map.max_event);
	stretch_blit( map.sprite_bmp, Display.GetSurface(),  0,  cur_sprite*16, 16, 16,
                                                        0, 30, 10, 10);
}




//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//             Timing Routines
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
volatile int speed_counter = 0;

void increment_speed_counter()
{
    speed_counter++;
}
END_OF_FUNCTION(increment_speed_counter);

volatile int frame_count, fps  = 0;

void fps_proc(void)
{
   fps = frame_count;
   frame_count = 0;
}
END_OF_FUNCTION(fps_proc);

void SetTimers(void)
{
        LOCK_VARIABLE(speed_counter);
        LOCK_FUNCTION(increment_speed_counter);
        install_int_ex(increment_speed_counter, BPS_TO_TIMER(60));

        LOCK_VARIABLE (frame_count);
        LOCK_VARIABLE (fps);        // Lock FPS
        LOCK_FUNCTION (fps_proc);  // Lock FPScounter
        install_int(fps_proc, 1000);
        frame_count = fps = 0;
}



/////////////////////////
//CApp
/////////////////////////
CApp::CApp()
{
        done = FALSE;
}

CApp::~CApp()
{
}

//Callback to exit
void exit_callback()
{
App.done = true;
}

void SetTimers(int speed)
{
        LOCK_VARIABLE(speed_counter);
        LOCK_FUNCTION(increment_speed_counter);
        install_int_ex(increment_speed_counter, BPS_TO_TIMER(speed));

        LOCK_VARIABLE (frame_count);
        LOCK_VARIABLE (fps);        // Lock FPS
        LOCK_FUNCTION (fps_proc);  // Lock FPScounter
        install_int(fps_proc, 1000);
        frame_count = fps = 0;
}


int key_pgup;
int key_pgdn;
int key_1;
int key_2;
int key_home;
int key_end;



int main(int argc, char *argv[])
{
  Display.CreateWindow(640, 480, 16, false);
  install_mouse();
  install_keyboard();
  
  SetTimers(60);
  
  CPortal portal;
  cam.x = 0;
  cam.y = 0;
  
  map.InitMap(100, 100, 16, 16, 2);
  map.LoadTileset("./data/town_set.bmp");
  map.LoadSpriteset("./data/sprites.bmp");
  
  int portaling = 0;

while (!App.done)
{

  while (speed_counter > 0)
  {    
    // Logic:
    if(key[KEY_ESC]) Display.Shutdown();
	
	update_key(KEY_PGDN,  &key_pgdn );
	update_key(KEY_PGUP,  &key_pgup );
	update_key(KEY_HOME,  &key_home );
	update_key(KEY_END,   &key_end );
	update_key(KEY_1,  &key_1 );
	update_key(KEY_2,  &key_2 );

	if(key_pgup == 1)
	{
        cur_gfx++;
	}
	
	if(key_pgdn == 1) 
	{
       cur_gfx--;
	}
	
	if(key_home == 1)
	{
       if(cur_sprite+1<map.sprite_bmp->h/map.sizeh) cur_sprite++;
    }
    
    if(key_end == 1)
	{
       if(cur_sprite-1>=0) cur_sprite--;
    }
	
	if(key_1 == 1)
	{
		if(cur_layer < map.GetLayers()-1 ) cur_layer++;
		//cur_layer++;
	}
	
	if(key_2 == 1)
	{
		if(cur_layer > 0 ) cur_layer -- ;
		//cur_layer--;
	}

	if(key[KEY_RIGHT])
	{
		cam.x++;
	}
	if(key[KEY_LEFT])
	{
		if(cam.x > 0 )
			cam.x--;
	}
	
	if(key[KEY_UP])
	{
		if(cam.y > 0)
			cam.y --;
	}

	if(key[KEY_DOWN])
	{

   if(map.GetHeight()-30 > cam.y/16)
		cam.y ++;

	}

    static int battling = 0;
    if(key[KEY_B])
    {
      if(battling == 0)
      {
        if(map.isbattle == false) map.isbattle = true;
        else map.isbattle = false;
      }

        static std::string orig_map;
        static std::string temp_name;
     
     if(map.isbattle == true && battling == 0)
     {
        orig_map = get_filename(map.name.c_str());
        temp_name = "";
        temp_name = "./data/";
		temp_name += get_filename(Do_PortalSelect());
		map.LoadMap(temp_name, true);
		allegro_message("Press B again once you select the position you want!");
		 battling = 1;
                   /*
        clear(screen);
        gstream gs(screen);
    	gs.save_input_approver();	// first save old approver
	    gs.set_input_approver(ia_allow_integer); // then set a digit approver
     	gs.set_insert_mode(true);	// set insert mode
    	gs.set_max_input_length(9);	// and max 9 digits
    	gs.set_input_approver(ia_allow_everything); // then set a digit approver
    	gs.set_insert_mode(true);	// set insert mode
     	gs.set_max_input_length(50);
    	gs.goto_xy(0,0);
    	gs << "Battle Where do you want to go after the battle?: ";
    	gs >>  event.name;
    	gs << "\n";
    	gs << "Enter MSG Text(Max of 1024 chars): ";
    	gs >> event.text;
    	*/
     }
     
     else if(battling == 1)
     {
        int holderx =  mouse_x/16*16+cam.x/16*16;
        int holdery =  mouse_y/16*16+cam.y/16*16;
        allegro_message("Battle exits accepted! ");
        map.LoadMap("./data/"+orig_map, true);
        map.battle_destmap = temp_name;
        map.battle_x = holderx;
        map.battle_y = holdery;
        allegro_message("%d %d battlexy", map.battle_x, map.battle_y);
        battling = 0;
        map.isbattle = true;
        map.SaveMap("./data/"+orig_map);

        
     }
        
        while(key[KEY_B]) {}
    }
	
	// TODO: Since the portal is only on the ground level I should change this to reflect only layer 0
	
	// Add A Portal!

	static std::string temp_name = "null";
	
	
	// WARNING AUTO SAVES THE MAP *** COULD BE A PROB *** 
	if(key[KEY_Z])
	{

	 if(portaling == 0)// No double portals!
	 {
	 if(!CHECK_BIT(map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_PORTAL))
	 {
		SET_BIT(map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_PORTAL);
		
		portal.srcx =  (mouse_x/16+cam.x/16)*16;//(mouse_x+cam.x)/map.sizew*map.sizew;
		portal.srcy =  (mouse_y/16+cam.y/16)*16;//(mouse_y+cam.y)/map.sizew*map.sizew;
		portal.name = "./data/";
		
		portal.name += get_filename(Do_PortalSelect());

		allegro_message("portal name %s map name %s", portal.name.c_str(), map.name.c_str());
		temp_name = map.name.c_str();
		map.SaveMap("./data/"+map.name); // save the bit!
		cam.x = 0;
		cam.y  = 0;
		map.LoadMap(portal.name, true);
		portaling = 1;
	 }
	 }
	 else if(portaling == 1)
	 {
		portal.destx = (mouse_x+cam.x)/map.sizew*map.sizew;//(mouse_x/16+cam.x/16)*16;//(mouse_x+cam.x)/map.sizew*map.sizew;
		portal.desty = (mouse_y+cam.y)/map.sizew*map.sizew;//(mouse_y/16+cam.y/16)*16;//(mouse_y+cam.y)/map.sizew*map.sizew;
		allegro_message("portal %s", portal.name.c_str());
		map.LoadMap("./data/"+temp_name, true);
            if(portal.name == map.name)
    		{
             clear(screen);
            gstream gs(screen);
        	gs.save_input_approver();	// first save old approver
    	    gs.set_input_approver(ia_allow_integer); // then set a digit approver
        	gs.set_insert_mode(true);	// set insert mode
         	gs.set_max_input_length(50);
        	gs.goto_xy(0,0);
        	gs << "Is this a cinematic portal? if so enter the Cine id!: ";
        	gs >>  portal.cine_id;
            }

            clear(screen);
            gstream gs(screen);
        	gs.save_input_approver();	// first save old approver
    	    gs.set_input_approver(ia_allow_integer); // then set a digit approver
        	gs.set_insert_mode(true);	// set insert mode
         	gs.set_max_input_length(50);
        	gs.goto_xy(0,0);
        	gs << "Enter a check_quest (questidnum): ";
        	gs >>  portal.check_quest;

		map.portal.push_back(portal);
		map.max_portal++;
        allegro_message("SaVED %d %d %d %d %s", map.portal[map.max_portal-1].srcx, map.portal[map.max_portal-1].srcy, map.portal[map.max_portal-1].destx, map.portal[map.max_portal-1].desty, map.portal[map.max_portal-1].name.c_str());
        allegro_message("%s", temp_name.c_str());
        map.SaveMap("./data/"+temp_name);
		portaling = 0;
	 }
/*
SET_BIT(map.tile[cur_layer][64/16][64/16].flags, FLAG_PORTAL);
CPortal portal;
portal.destx = 128;
portal.desty = 128;
portal.name="./data/test.map";
portal.srcx=64;
portal.srcy=64;
map.portal.push_back(portal);
map.max_portal++;
*/
	 
	 while( key[KEY_Z] ) {} 
	}
	
	// EVENT_SWITCH
	if(key[KEY_V])
	{
       SET_BIT(map.tile[1][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_EVENT);
       CEvent event;
       event.x = mouse_x/16+cam.x/16;
       event.y = mouse_y/16+cam.y/16;

        clear(screen);
        gstream gs(screen);
     	gs.set_insert_mode(true);	// set insert mode
    	gs.set_max_input_length(9);	// and max 9 digits
    	gs.set_input_approver(ia_allow_integer); // then set a digit approver
    	gs.set_insert_mode(true);	// set insert mode
     	gs.set_max_input_length(1024);
    	gs.goto_xy(0,0);
    	gs << "Enter EVENT_SWITCH QUESTID: \n";
        gs >> event.id;

       event.flags = EVENT_SWITCH;
       map.event.push_back(event);
       map.max_event++;
     while(key[KEY_V]) {}
    }
    
    // EVENT_CHEST
    if(key[KEY_Q])
	{
       SET_BIT(map.tile[1][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_EVENT);
       CEvent event;
       event.x = mouse_x/16+cam.x/16;
       event.y = mouse_y/16+cam.y/16;

        clear(screen);
        gstream gs(screen);
     	gs.set_insert_mode(true);	// set insert mode
    	gs.set_max_input_length(9);	// and max 9 digits
    	gs.set_input_approver(ia_allow_integer); // then set a digit approver
    	gs.set_insert_mode(true);	// set insert mode
     	gs.set_max_input_length(1024);
    	gs.goto_xy(0,0);
    	gs << "Enter EVENT_CHEST Item_id num: ";
        gs >> event.id;

       event.flags = EVENT_CHEST;
       map.event.push_back(event);
       map.max_event++;
     while(key[KEY_Q]) {}
    }

    // EVENT_TRAINER
     if(key[KEY_E])
	{
       SET_BIT(map.tile[1][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_EVENT);
       CEvent event;
       event.x = mouse_x/16+cam.x/16;
       event.y = mouse_y/16+cam.y/16;

        clear(screen);
        gstream gs(screen);
     	gs.set_insert_mode(true);	// set insert mode
    	gs.set_max_input_length(9);	// and max 9 digits
    	gs.set_input_approver(ia_allow_everything); // then set a digit approver
    	gs.set_insert_mode(true);	// set insert mode
     	gs.set_max_input_length(1024);
    	gs.goto_xy(0,0);
    	gs << "Enter EVENT_TRAINER Name:\n";
       	   char temp[1024];
           for(int i = 0; i<1024; ++i)
             temp[i] = ' ';
   	    gs.getline(temp, sizeof(char)*1024);
   	    event.name = temp;

    	gs << "\n\nEnter EVENT_TRAINER Text:\n";
    	   for(int i = 0; i<1024; ++i)
             temp[i] = ' ';
   	    gs.getline(temp, sizeof(char)*1024);
   	    event.text = temp;

       event.flags = EVENT_TRAINER;
       map.event.push_back(event);
       map.max_event++;
     while(key[KEY_Q]) {}
    }
	
//	if(key[KEY_V])
//       allegro_message("SaVED %d %d %d %d %s", map.portal[0].srcx, map.portal[0].srcy, map.portal[0].destx, map.portal[0].desty, map.portal[0].name.c_str());
	if(key[KEY_X])
	{

/*

	for(int i = 0; i<map.portal.size(); ++i)
		{
// allegro_message("%d", map.portal[i].srcx);//6
       ///     allegro_message("%d", map.portal.size());//6
       				std::vector<CPortal>::iterator pos;
//    					pos = map.portal.begin() + i;
    pos = map.portal.begin();
    int fuckyou = 0;
					map.portal.erase(pos+fuckyou);
					map.max_portal--;
        }
*/
                //  allegro_message("%d", map.portal.size());
	 // Make sure a portal exists
	 if(CHECK_BIT(map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_PORTAL))
	 {	
		for(int i = 0; i<map.portal.size(); ++i)
		{

			if( map.portal[i].srcx == (mouse_x/map.sizew+cam.x/map.sizew)*map.sizew &&
				map.portal[i].srcy == (mouse_y/map.sizeh+cam.y/map.sizeh)*map.sizeh )
				{
					std::vector<CPortal>::iterator pos; 
					pos = map.portal.begin() + i;
					map.portal.erase(pos);
					map.max_portal--;
				}
		}
		REMOVE_BIT(map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_PORTAL);
		
	 }
	
	 while(key[KEY_X]) {}
	}
	
	
	if(key[KEY_A])
	{
      cur_gfx = map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].gfx;
    }
	
	/*
	if(key[KEY_0])
	{
                  int i = 1;
//      for(int i = map.max_portal-1; i>0; ++i)
      {
					std::vector<CPortal>::iterator pos;
					pos = map.portal.begin() + i;
					map.portal.erase(pos);
					map.max_portal--;
      }
      while(key[KEY_0]) {}
    }
	*/
	

	if(key[KEY_M] && cur_layer == LAYER_EVENT)
	{
  		SET_BIT(map.tile[1][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_EVENT);
    
       CEvent event;
       event.x = mouse_x/16+cam.x/16;
       event.y = mouse_y/16+cam.y/16;
       
        clear(screen);
        gstream gs(screen);
    	gs.save_input_approver();	// first save old approver
	    gs.set_input_approver(ia_allow_integer); // then set a digit approver
     	gs.set_insert_mode(true);	// set insert mode
    	gs.set_max_input_length(9);	// and max 9 digits
    	gs.set_input_approver(ia_allow_everything); // then set a digit approver
    	gs.set_insert_mode(true);	// set insert mode
     	gs.set_max_input_length(1024);
    	gs.goto_xy(0,0);
    	gs << "Event - MSG(automatically pops up on passover!) Enter ID Name: ";
    	gs >>  event.name;
    	gs << "\n";
    	gs << "Enter MSG Text(Max of 1024 chars): ";
    	gs >> event.text;

	    gs.set_input_approver(ia_allow_integer); // then set a digit approver
    	gs << "\nEnter Quest Trigger(turns on the quest): ";
    	gs >> event.id;



       event.flags = EVENT_MSG;
       
       
       map.event.push_back(event);
       map.max_event++;
       while(key[KEY_M]) {}
    }
    
    if(key[KEY_S] && cur_layer == LAYER_EVENT)
	{
	   SET_BIT(map.tile[1][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_EVENT);
       CEvent event;
       event.x = mouse_x/16+cam.x/16;
       event.y = mouse_y/16+cam.y/16;

        clear(screen);
        gstream gs(screen);
    	gs.save_input_approver();	// first save old approver
	    gs.set_input_approver(ia_allow_integer); // then set a digit approver
     	gs.set_insert_mode(true);	// set insert mode
    //	gs.set_max_input_length(9);	// and max 9 digits
    	gs.set_input_approver(ia_allow_everything); // then set a digit approver
    	gs.set_insert_mode(true);	// set insert mode
     	gs.set_max_input_length(64);

    	gs.goto_xy(0,0);
    	gs << "Event - Sign Enter ID Name\n: ";
    	char temp[1024];
    	for(int i = 0; i<1024; ++i)
          temp[i] = ' ';
  	    gs.getline(temp, sizeof(char)*1024);
   	    event.name = temp;
    	gs << "\n";

        std::string text1;
        std::string text2;
        std::string text3;
        std::string text4;
        std::string text5;
     	gs.set_max_input_length(64);
    	gs << "Enter Sign Text(Max of 1024 chars)\n:";
        getline(gs, text1);

        gs.set_max_input_length(64);
        gs << "\n:";
        getline(gs, text2);

        gs.set_max_input_length(64);
        gs << "\n:";
        getline(gs, text3);

        gs.set_max_input_length(64);
        gs << "\n:";
        getline(gs, text4);
        
        gs.set_max_input_length(64);
        gs << "\n(last):";
        getline(gs, text5);
        
        event.text = text1 + text2 + text3 + text4 + text5;
    	/*
    	gs << "Enter Sign Text(Max of 1024 chars)\n: ";
  		for(int i = 0; i<1024; ++i)
         temp[i] = ' ';
        gs.getline(temp, sizeof(char)*1024);
        event.text = temp;
        */
  		
       event.flags = EVENT_SIGN;
       map.event.push_back(event);
       map.max_event++;
       while(key[KEY_S]) {}
    }
    
    // Place an shop
    if(key[KEY_U] &&  cur_layer == LAYER_EVENT)
    {
	   SET_BIT(map.tile[1][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_EVENT);
       CEvent event;
       event.x = mouse_x/16+cam.x/16;
       event.y = mouse_y/16+cam.y/16;

        clear(screen);
        gstream gs(screen);
    	gs.save_input_approver();
    	gs.set_input_approver(ia_allow_everything);
    	gs.set_insert_mode(true);
     	gs.set_max_input_length(1024);
    	gs.goto_xy(0,0);
    	gs << "Event - Shopkeep placement: ";
    	char temp[1024];
    	for(int i = 0; i<1024; ++i)
          temp[i] = ' ';
   	    gs.getline(temp, sizeof(char)*1024);
   	    event.name = temp;
    	gs << "\n";
    	gs << "Enter Shopkeep's Text(Max of 1024 chars): ";
  		for(int i = 0; i<1024; ++i)
         temp[i] = ' ';
       gs.getline(temp, sizeof(char)*1024);
       event.text = temp;
    	gs << "\n";
    	gs << "Enter Shopkeep ID Num: ";
        gs >> event.id;
       event.flags = EVENT_SHOP_WEAPON;
       map.event.push_back(event);
       map.max_event++;
       while(key[KEY_U]) {}
    }
    
    // Place a inn
    if(key[KEY_I] && cur_layer == LAYER_EVENT)
    {
	   SET_BIT(map.tile[1][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_EVENT);
       CEvent event;
       event.x = mouse_x/16+cam.x/16;
       event.y = mouse_y/16+cam.y/16;

        clear(screen);
        gstream gs(screen);
    	gs.save_input_approver();
    	gs.set_input_approver(ia_allow_everything);
    	gs.set_insert_mode(true);
     	gs.set_max_input_length(1024);
    	gs.goto_xy(0,0);
    	gs << "Event - Inn placement: ";
    	char temp[1024];
    	for(int i = 0; i<1024; ++i)
          temp[i] = ' ';
   	    gs.getline(temp, sizeof(char)*1024);
   	    event.name = temp;
    	gs << "\n";
    	gs << "Enter Innkeep's Text(Max of 1024 chars): ";
  		for(int i = 0; i<1024; ++i)
         temp[i] = ' ';
       gs.getline(temp, sizeof(char)*1024);
       event.text = temp;

       event.flags = EVENT_INN;
       map.event.push_back(event);
       map.max_event++;
       while(key[KEY_I]) {}
    }
    
    
    // Place a cleric event -- yeah you have to press O
    if(key[KEY_O] && cur_layer == LAYER_EVENT)
    {
	   SET_BIT(map.tile[1][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_EVENT);
       CEvent event;
       event.x = mouse_x/16+cam.x/16;
       event.y = mouse_y/16+cam.y/16;

        clear(screen);
        gstream gs(screen);
    	gs.save_input_approver();
    	gs.set_input_approver(ia_allow_everything);
    	gs.set_insert_mode(true);
     	gs.set_max_input_length(1024);
    	gs.goto_xy(0,0);
    	gs << "Event - Cleric placement name: ";
    	char temp[1024];
    	for(int i = 0; i<1024; ++i)
          temp[i] = ' ';
   	    gs.getline(temp, sizeof(char)*1024);
   	    event.name = temp;
    	gs << "\n";
    	gs << "Enter Cleric's Text(Max of 1024 chars): ";
  		for(int i = 0; i<1024; ++i)
         temp[i] = ' ';
       gs.getline(temp, sizeof(char)*1024);
       event.text = temp;

       event.flags = EVENT_CLERIC;
       map.event.push_back(event);
       map.max_event++;
       while(key[KEY_O]) {}
    }
    
    
        if(key[KEY_9])
    {
        for(int i = 0; i<map.max_event; ++i)
        {
        if(map.event[i].x == mouse_x/16+cam.x/16 && map.event[i].y == mouse_y/16+cam.y/16)
        {
            std::vector<CEvent>::iterator pos;
            pos = map.event.begin() + i;
            map.event.erase(pos);
            map.max_event--;
        }
        }
        while(key[KEY_9]) {}
    }

    
    // place the npc
    if(key[KEY_N])
    {
       CNpc npc;
       npc.x = mouse_x/16*16+cam.x/16*16;
       npc.gfx = cur_sprite;
       npc.y = mouse_y/16*16+cam.y/16*16;
       npc.id = npc.gfx+1;
    //   if(map.isbattle)
       {
         clear(screen);
         gstream gs(screen);
         gs.save_input_approver();	// first save old approver
    	 gs.set_input_approver(ia_allow_integer); // then set a digit approver
         gs.set_insert_mode(true);	// set insert mode
         gs.set_max_input_length(9);	// and max 9 digits
         gs.goto_xy(0,0);
         gs << "Enter the ID num of the battle npc: ";
         gs >> npc.id;
         // TODO: add a check to see if it exists
       }
       map.npc.push_back(npc);
       map.max_npc++;
       while(key[KEY_N]) {}
    }
    
    if(key[KEY_COMMA])
    {
      for(int i = 0; i<map.GetHeight(); ++i)
      for(int j = 0; j<map.GetWidth(); ++j)
      {
         if( cur_gfx == map.tile[cur_layer][i][j].gfx )
         {
             SET_BIT(map.tile[cur_layer][i][j].flags, FLAG_WALKABLE);
         }
      }
      while(key[KEY_COMMA]) {}
    }
    
    // delete the npc
    if(key[KEY_M])
    {
     for(int i = 0; i<map.max_npc; ++i)
     {
         if( mouse_x/16*16+cam.x/16*16 == map.npc[i].x && map.npc[i].y == mouse_y/16*16+cam.y/16*16)
         {
            std::vector<CNpc>::iterator pos;
            pos = map.npc.begin() + i;
            map.npc.erase(pos);
            map.max_npc--;
            break;
         }
     }
    }

    if(key[KEY_W])
    {
       TOGGLE_BIT(map.tile[0][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_WAYPOINT);
       while(key[KEY_W]) {}
    }
    
    if(key[KEY_TILDE])
    {
        SET_BIT(map.tile[cur_layer][mouse_y/map.sizeh+cam.y/map.sizeh][mouse_x/map.sizew+cam.x/map.sizew].flags, FLAG_WALKABLE);
    }
    
    if(key[KEY_F])
    {
      for(int i = 0; i<map.GetHeight(); ++i)
       for(int j = 0; j<map.GetWidth(); ++j)
       {
           fill_gfx = cur_gfx;
           map.tile[cur_layer][i][j].gfx = fill_gfx;
       }
    }
    
   if(key[KEY_P] && key[KEY_LCONTROL])
    {
      if(mouse_x/map.sizew+cam.x/map.sizew < map.GetWidth() && mouse_y/map.sizeh+cam.y/map.sizeh < map.GetHeight())
      {
       map.player1_start_x = mouse_x/map.sizew+cam.x/map.sizew;
       map.player1_start_y = mouse_y/map.sizeh+cam.y/map.sizeh;
      }
    }
    else if(key[KEY_P])
    {
      if(mouse_x/map.sizew+cam.x/map.sizew < map.GetWidth() && mouse_y/map.sizeh+cam.y/map.sizeh < map.GetHeight())
      {
       map.player_start_x = mouse_x/map.sizew+cam.x/map.sizew;
       map.player_start_y = mouse_y/map.sizeh+cam.y/map.sizeh;
       }
    }
    
 
    
    if(key[KEY_C])
    {
    	char buffer[255];
    	int id_num = 0;
    	gstream gs(screen);

    	gs.save_input_approver();	// first save old approver
    	gs.set_input_approver(ia_allow_integer); // then set a digit approver

    	gs.set_insert_mode(true);	// set insert mode
    	gs.set_max_input_length(9);	// and max 9 digits

    	clear_bitmap(screen);

    	gs.set_max_input_length(50);	// and max 9 digits
    	gs.goto_xy(0,0);
    	gs << "What Cinematic ID do you want to assign?: ";
    	gs >> id_num;
    	gs << "\n";

    	map.cine_id = id_num;

      while(key[KEY_C]) {}
    }
    
    
    

	EditorLogic();
    speed_counter--;
  }

  // Rendering:
  map.DrawMapEditor(cur_layer, cam.x/16*16, cam.y/16*16);
  map.DrawObjects(NULL, cam.x/16*16, cam.y/16*16);
  RenderEditor(map);

  
  rect(Display.GetSurface(), (mouse_x/map.sizew)*map.sizew, (mouse_y/map.sizeh)*map.sizeh, (mouse_x/map.sizew)*map.sizew+map.sizew, (mouse_y/map.sizeh)*map.sizeh+map.sizeh, makecol(255,0,0));
  //rect(Display.GetSurface(),   (mouse_x/map.sizew+cam.x/map.sizew, (mouse_y/map.sizeh)*map.sizeh,   (mouse_x/map.sizew+cam.x/map.sizew)+map.sizew, (mouse_y/map.sizeh)*map.sizeh+map.sizeh, makecol(255,0,0));

  //[mouse_x/map.sizew+cam.x/map.sizew]
  frame_count++;
  show_mouse(screen);
  blit(Display.GetSurface(), screen, 0, 0, 0, 0, screen->w, screen->h);
  clear_bitmap(Display.GetSurface());

};//end while(!App.done)


  Display.Shutdown();
  return 0;
}
END_OF_MAIN();
