#include "game.h"

///end of Game 
void do_trans(BITMAP *dest){//makes the bitmap transparent to a certin degree
    int i=0; //the current column of the bitmap we're in
    for(int t = 0; t<dest->h; t++){//go through all the rows in the bitmap
        for(i; i<dest->w; i+=4){//go thorough the row placing a transp pixel every 4  pixel
            putpixel(dest, i, t, makecol(255,0,255));//put the transp pixel
        }
        if(t%2 == 0)//keep rows alternating
           i = 0;
        else
           i = 1;
    }
}
void do_trans3(BITMAP *dest){//makes the bitmap transparent to a certin degree
    int i=0; //the current column of the bitmap we're in
    for(int t = 0; t<dest->h; t++){//go through all the rows in the bitmap
        for(i; i<dest->w; i++){//+=4){//go thorough the row placing a transp pixel every 4  pixel
            putpixel(dest, i, t, makecol(255,0,255));//put the transp pixel
        }
        if(t%2 == 0)//keep rows alternating
           i = 0;
        else
           i = 1;
    }
}
////// newer transs code

void do_trans2(BITMAP *dest){
    int color = makecol(255,0,255);
    int fourth_width = dest->w/4;
    for(int y = 0; y <= dest->h; ++y) 
	{
        unsigned short *pixel_ptr = (unsigned short *)dest->line[y];
        int x = 0;
        if( y & 1 ) {
            ++x;
            ++pixel_ptr;
        
        for(; x <= fourth_width; ++x ) 
		{
            *pixel_ptr = color;
            pixel_ptr += 4;
        }
		}
    }

}

void do_trans4(BITMAP *dest){
	int pixel;
    int x = 0;
    int color = makecol(255,0,255);
    int go_to = dest -> w /2;
    int color_depth = bitmap_color_depth(dest);

    for(int y = 0; y <= dest -> h; ++y){
        
        if(color_depth == 8)  
            unsigned char *pixel = dest -> line[y]; //this is if you're in 8 bpp
        if(color_depth == 15 || color_depth == 16) 
           unsigned short *pixel = (unsigned short *)dest -> line[y]; //this is if you're in 16 or 15 bpp
        else
            unsigned long *pixel = (unsigned long *)dest -> line[y]; //this is if you're in 32 bpp

        if(y & 1){
            ++pixel;
            ++x;
        }
        
        for(; x <= go_to; ++x){
		//*pixel = color;
            pixel = color; 

	//	color *pixel  ; // i put this in becaues  *pixel = color; dont work
            pixel += 2;
        }
    }

}
void Game::updateMiniMap(int lay)
{
	//seperate draw from update
	if(miniMapon == true)
	{
	int i,j,p,t,x,y,c;

	for (i=0; i<WORLD_X; i++)
	{
		for (j=0; j<WORLD_Y; j++)
		{
			if(worlds[0].areas.layers[0].cells[j][i].get_layer(lay-1)==lay)
			{
			p=worlds[0].areas.layers[0].cells[j][i].get_value(lay-1);
			t=worlds[0].areas.layers[0].cells[j][i].get_tileset(lay-1);
			x=p/32;
			y=p%32;
			c=getpixel(shrunk,t*8+x,y);
			//if (getpixel(world,i,j)>0)drawing fog of war on mini map
			//{
			if(p!=247)
				{
				putpixel(miniMap,508+i,360+j,c);	
				}
			//}
			}
		}
	}
	drawRectangle(miniMap,508,360,WORLD_X,WORLD_Y,makecol(128,128,128),0,0);
	//putpixel(bmp,508+px/32,360+py/32,makecol(255,255,255)); //put whit pictle for play placment
	drawRectangle(miniMap,508+views[0].get_screen_pos_x(),360+views[0].get_screen_pos_y(),views[0].get_GRID_WIDTH()-1,views[0].get_GRID_WIDTH()-1,makecol(255,255,255),0,0);
	}
}
void Game::drawMiniMap()
{
	//seperate draw from update
	if(miniMapon == true)
	{
	masked_blit(miniMap,views[0].get_buffer(),4,4,4,4,views[0].get_GRID_WIDTH()*32-8,views[0].get_GRID_HEIGHT()*32-8);
	}
}
// move the map with the mouse as the center
void Game::move_MiniMap(int x, int y)
{
	if(miniMapon == true)
	{
	views[0].set_screen_pos_x((x-508)-(views[0].get_GRID_WIDTH()/2));
	views[0].set_screen_pos_y((y-360)-(views[0].get_GRID_WIDTH()/2));

	if (views[0].get_screen_pos_x()<1) views[0].set_screen_pos_x(1);
	if (views[0].get_screen_pos_x()>(WORLD_X-views[0].get_GRID_WIDTH())) views[0].set_screen_pos_x((WORLD_X-views[0].get_GRID_WIDTH()));
	if (views[0].get_screen_pos_y()<1) views[0].set_screen_pos_y(1);
	if (views[0].get_screen_pos_y()>(WORLD_Y-views[0].get_GRID_HEIGHT())) views[0].set_screen_pos_y((WORLD_Y-views[0].get_GRID_HEIGHT()));
	}
}

void Game::hide_MiniMap()
{
miniMapon= false;
	destroy_bitmap(shrunk);

}

void Game::show_MiniMap(int w,int h)
{
	miniMapon= true;
	shrunk=create_bitmap(24,32);
	if (world!=NULL)
	{
		//destroy_bitmap(world);
	}
	world=create_bitmap(w,h);
	clear(world);

	stretch_blit((BITMAP*)data[TILES1].dat,shrunk,0,0,256,1024,0,0,8,32);
	stretch_blit((BITMAP*)data[TILES2].dat,shrunk,0,0,256,1024,8,0,8,32);
	stretch_blit((BITMAP*)data[TILES3].dat,shrunk,0,0,256,1024,16,0,8,32);
}

//// Game construters

Game::Game()
{
miniMap = create_bitmap(SCREEN_W,SCREEN_H);
do_trans3(miniMap);
miniMapon = false;


if(computerId==0)
{
	logonUnits.load("serverunit.txt");
}

	areasingame[0] = "area1.txt";
	areasingame[1] = "area2.txt";
	areasingame[2]= "area3.txt";
	areasingame[3]= "area4.txt";
music = load_datafile("music.dat");
 animations.load();

//DEFALT GETS ASINGE automaticly
//views[0]= View();
//worlds[0].world_setup(views[0]);

}
void Game::switchArea(int a)
{
current_area=a;
areasingame[0] = "area1.txt";
	areasingame[1] = "area2.txt";
	areasingame[2]= "area3.txt";
	areasingame[3]= "area4.txt";
worlds[0].areas.reload(areasingame[a-1]);
}


//Game gets
string Game::get_severmsg()
{
	return severmsg;
}
View *Game::get_views()
{
	return views;
}

World *Game::get_worlds()
{
	return worlds;
}

//sets
/*
void Game::set_severmsg(string msg)
{
	severmsg = msg;
}
*/

void blitBuffer(BITMAP *bmp)
{
	
	acquire_screen();
	blit(bmp,screen,0,0,0,0,SCREEN_W,SCREEN_H);
	release_screen();
}

//timer shit
/* these must be declared volatile so the optimiser doesn't mess up */
volatile int xt = 1;
/* timer interrupt handler */

void inc_xt(void)
{
   xt++;
   if (xt>60)
   {
	   xt=1;
   }
}
END_OF_FUNCTION(inc_xt);

unsigned short fps =0;
unsigned short new_fps =0;
unsigned short timer = 1;

void Game::do_game_logic()
{

if (ch_current_area!= 0)
{
switchArea(ch_current_area);
ch_current_area = 0;
}

			if (key[KEY_F1]) 
			{
				switchArea(1);
			}
			
			if (key[KEY_F2]) 
			{
				switchArea(2);
			}
			if (key[KEY_F3]) 
			{
				switchArea(3);
			}
			if (key[KEY_F4]) 
			{
				switchArea(4);
			}
		if (mouse_b & 1)
		{
			if (mouse_x>=508 && mouse_x<508+WORLD_X && 
				mouse_y>=360 && mouse_y<500+WORLD_Y) 
			{
				move_MiniMap(mouse_x,mouse_y);
			}
			
		}

	if (computerId != 0)
	{
		if (mouse_b & 2)
		{
			
			// check to see if after we pressed the mouse if we
			// are inside of the grid
			
				// if the area that we clicked is passable
				// then put down crosshairs and tell the player
				// to begin walking in that direction
				// Added the A* algorithm class to find the path to 
				// the crosshairs. It works about 85% accuracy. 
				if (worlds[0].areas.layers[0].cells[((mouse_y+get_views()[0].get_scroll_y())/TILESIZE)+get_views()[0].get_screen_pos_y()]
							[((mouse_x+get_views()[0].get_scroll_x())/TILESIZE)+get_views()[0].get_screen_pos_x()].get_passable(0)==0)
				{
					
					string pointx = NumberToString(mouse_x+get_views()[0].get_scroll_x()+get_views()[0].get_screen_pos_x()*TILESIZE) ;
					string pointy = NumberToString(mouse_y+get_views()[0].get_scroll_y()+get_views()[0].get_screen_pos_y()*TILESIZE);
					



//move object that callss move on chritor

		
		if (logonUnits.IsInList( computerId ))
		{




if(inputConter==10)
{

outboxbuffer +="0|"+NumberToString(computerId)+"|002|"+NumberToString(computerId)+ ','+ pointx +','+ pointy +
','+NumberToString(logonUnits.Get_Unit( computerId )->Get_X())+','+NumberToString(logonUnits.Get_Unit( computerId )->Get_Y())+
','+NumberToString(logonUnits.Get_Unit( computerId )->Get_direction() )+','+NumberToString(logonUnits.Get_Unit( computerId )->Get_frame())+"`~";
					textprintf_centre(screen, font, 40, 200, makecol(255, 255, 255), outboxbuffer.c_str());
inputConter=0;					//sleep(20);
}
else
{
inputConter++;
}
		}



					
				}
				
			
			
		}

	}

	if (inboxbuffer.length()  > 0)
	{
//textprintf(screen, font, 100, 10, makecol(255, 255, 255),outboxbuffer.c_str());
//Sleep(5000);
textout(views[0].get_buffer(),font,inboxbuffer.c_str(),50,30,makecol(5,255,5));
//	sleep(9);	
Packet * newpacket= new Packet ;

		newpacket->read();
		newpacket->exscute();
	}
if (untstringflag== true)
	{
		untstringflag= false;
textout(screen,font,untstring.c_str(),100,20,makecol(255,6,255));

//sleep(1);
	logonUnits.insert(untstring);  /////player
		///// need some this to delet the data fome untstring and the boxs 
	//untstring.erase(0,untstring.length());
	}
if (untStatstringflag== true)
	{
		untStatstringflag= false;
//textout(screen,font,untStatstring.c_str(),100,20,makecol(255,6,255));

//sleep(1);
		logonUnits.upDateStats(untStatstring);  /////player
		///// need some this to delet the data fome untstring and the boxs 
	//untstring.erase(0,untstring.length());
	}
if (sendlistflag== true)
	{
		logonUnits.listToString(sendliststring);
		sendlistflag =false;
		  
		///// need some this to delet the data fome untstring and the boxs 
	//untstring.erase(0,untstring.length());
	}		

	if (movestringflag== true)
	{
		movestringflag = false;
			
		logonUnits.setdest();  /////player
		///// need some this to delet the data fome untstring and the boxs 
	//untstring.erase(0,untstring.length());
	}	

if (deleteflag== true)
	{
//////////////////////////////////////////////////////////////bugg
		deleteflag = false;
			//deletetring = data;
		logonUnits.Delete(StringToNumber(deletetring)) ; /////playerdeletetring.erase(deletetring.length()
		///// need some this to delet the data fome untstring and the boxs 
	//untstring.erase(0,untstring.length());
	}
				
				
	if (talkstringflag== true)
	{
		talkstringflag = false;
			
		logonUnits.setdieolog();  /////player
		///// need some this to delet the data fome untstring and the boxs 
	//untstring.erase(0,untstring.length());
	}
	

	if ( battler.length()  > 0)
	{
	   logonUnits.battle(battler);
		battler="";
		play_sound(SAMPLE_HIT);
	}      
	if(serverdiolog.length()  > 0)
	{

		if (smsglife == 100)
		{
			serverdiolog="";
			smsglife=0;
		}
		else
		{
		smsglife++;
		}
	
}
                            
        
        // the game loop
logonUnits.sort();//we want mege sort instean for nlogn every time
logonUnits.setup_collision();//need better one sort then check side items bugg
//worlds[0].areas[0][0].players.setup_collision();
if (key[KEY_F7]) 
			{
			if(text==true)
			{
text= false;
				
			}
			else
			{
			text=true;
			}
			}




 if(text==true)
{              
 while(keypressed())
                {
                        int  newkey   = readkey();
                        char ASCII    = newkey & 0xff;
                        char scancode = newkey >> 8;
                        
                        // a character key was pressed; add it to the string
                        if(ASCII >= 32 && ASCII <= 126)
                        {
                                // add the new char, inserting or replacing as need be
                                if(insert || iter == edittext.end())
                                iter = edittext.insert(iter, ASCII);
                                else
                                edittext.replace(caret, 1, 1, ASCII);
                                
                                // increment both the caret and the iterator
                                caret++;
                                iter++;
                        }
                        // some other, "special" key was pressed; handle it here
                        else
                        switch(scancode)
                        {
                                case KEY_DEL:
                                if(iter != edittext.end()) iter = edittext.erase(iter);
                                break;
                                
                                case KEY_BACKSPACE:
                                if(iter != edittext.begin())
                                {
                                        caret--;
                                        iter--;
                                        iter = edittext.erase(iter);
                                }
                                break;
                                
                                case KEY_RIGHT:
                                if(iter != edittext.end())   caret++, iter++;
                                break;
                                
                                case KEY_LEFT:
                                if(iter != edittext.begin()) caret--, iter--;
                                break;
                                
                                case KEY_INSERT:
                                if(insert) insert = 0; else insert = 1;
                                break;
                                
								case KEY_ENTER:
                                if(iter != edittext.begin())
								{
									//this give runtime error
									if(computerId==severId)
									{
										//need to put in life contter
									serverdiolog = edittext;
									outboxbuffer +="9999|" + NumberToString(computerId) + "|003|" + NumberToString(computerId) + "," + edittext +"`~";
									
									}
									else
									{
									//need somthing for sending msg to serten clients
									outboxbuffer +="0|" + NumberToString(computerId) + "|003|" + NumberToString(computerId) + "," + edittext +"`~";
									}
									tra=edittext.length();
									caret-=(tra);
									iter-=(tra);
									edittext.erase(0,tra+1);
									
								}
                                break;
                                default:
                                
                                break;
                        }
                }
 }               
                
 if(computerId!=severId)	
{

if (key[KEY_F9]) 
	{
	
	}

}
if(computerId==severId)	
{	
	if (key[KEY_F11])
	{
		
		views[0].set_GRID_WIDTH(15);
		
	
	
		
		worlds[0].areas.layers[0].edit(views[0], animations);
		views[0].set_GRID_WIDTH(20);
	}

}

if (key[KEY_LEFT]) 
			{
			views[0].do_scroll(LEFT);	//if (sx>1) sx--;
			}
			if (key[KEY_RIGHT]) 
			{
			views[0].do_scroll(RIGHT);	//if (sx<(WORLD_X-GRID4_WIDTH-1)) sx++;
			}
			if (key[KEY_UP]) 
			{
			views[0].do_scroll(UP);	//if (sy>1) sy--;
			}
			if (key[KEY_DOWN]) 
			{
			views[0].do_scroll(DOWN);	//if (sy<(WORLD_Y-GRID4_HEIGHT-1)) sy++;
			}
if (key[KEY_F8]) 
{
	if(miniMapon==true)
	{
		hide_MiniMap();
	}
	else
	{
		
		show_MiniMap(WORLD_X,WORLD_Y);
	}
}

/*
if (mouse_x<14) 
		{	
			views[0].do_scroll(LEFT);
		}
		if (mouse_x>(SCREEN_W-10))
		{
			views[0].do_scroll(RIGHT);
		}
		if (mouse_y<11)
		{
			views[0].do_scroll(UP);
		}
		if (mouse_y>(SCREEN_H-10))
		{
			views[0].do_scroll(DOWN);
		}
*/

/*		
textprintf_centre(screen, font, SCREEN_W/2, 176, makecol(0, 0, 0),"x=%d, y=%d, z=%d", x, y, z);
for (int c=1; c<=5; c++) {
      textprintf_centre(screen, font, SCREEN_W/2, 62+c*10, makecol(0, 0, 0),x=%d, x);
      rest(1000);
   }
*/





//unscare_mouse();
/*


worlds[0].redraw(views, animations);
LOCK_VARIABLE(xt);
	LOCK_FUNCTION(inc_xt);

 	install_int(inc_xt, 1000);

	textprintf_centre(views[0].get_buffer(), font, SCREEN_W/2, 176, makecol(255, 255, 255),"%d", xt);
	if (timer  ==xt )
	{
		new_fps=fps;
		fps = 1;
		timer =1+ xt;

	}
	else
	{

		timer =1+ xt;
		fps++;
	}
//////////////////////////////////////////////////need to be in logic	
	textprintf_centre(views[0].get_buffer(), font, 40, 20, makecol(255, 255, 255),"FPS:%3d", new_fps);

*/
if(minconter==10)
{
updateMiniMap(1);
updateMiniMap(2);
updateMiniMap(3);
minconter=0;
}
else
{
minconter++;
}
}



//void Game::do_game_networking()



void Game::do_game_gfx()
{

/////////////////////////////////////////////need to be in logic	
worlds[0].redraw(views, animations,logonUnits);

drawMiniMap();
if(text==true)
{
// clear screen
                //clear(buffer);
                
                // output the string to the screen
                textout(get_views()->get_buffer(), font, edittext.c_str(), x, 10, WHITE);
                
                // output some stats using Allegro's printf functions
                textprintf(get_views()->get_buffer(), font,  x, 20, WHITE, "length:   %d", edittext.length());
                textprintf(get_views()->get_buffer(), font,  x, 30, WHITE, "capacity: %d", edittext.capacity());
                textprintf(get_views()->get_buffer(), font,  x, 40, WHITE, "empty`:   %d", edittext.empty());
                if(insert)
                textout(get_views()->get_buffer(), font, "Inserting", x, 50, WHITE);
                else
                textout(get_views()->get_buffer(), font, "Replacing", x, 50, WHITE);
                
                // draw the caret
                vline(get_views()->get_buffer(), caret * 8, 8, 18, WHITE);

}

if(serverdiolog.length()<=30)
	{
		textout(views[0].get_buffer(),font,serverdiolog.c_str(),get_views()[0].get_screen_pos_x()+150,get_views()[0].get_screen_pos_y()+30,makecol(255,255,255));
	}
	else if(serverdiolog.length()> 30)
	{
		textout(views[0].get_buffer(),font,serverdiolog.substr(0,30).c_str(),get_views()[0].get_screen_pos_x()+150,get_views()[0].get_screen_pos_y()+30,makecol(255,255,255));
		textout(views[0].get_buffer(),font,serverdiolog.substr(31,serverdiolog.length()).c_str(),get_views()[0].get_screen_pos_x()+150,get_views()[0].get_screen_pos_y()+40,makecol(255,255,255));
	}
LOCK_VARIABLE(xt);
	LOCK_FUNCTION(inc_xt);

 	install_int(inc_xt, 1000);

	textprintf_centre(views[0].get_buffer(), font, SCREEN_W/2, 176, makecol(255, 255, 255),"%d", xt);
	if (timer  ==xt )
	{
		new_fps=fps;
		fps = 1;
		timer =1+ xt;

	}
	else
	{

		timer =1+ xt;
		fps++;
	}
//////////////////////////////////////////////////need to be in logic	
	textprintf_centre(views[0].get_buffer(), font, 40, 20, makecol(255, 255, 255),"FPS:%3d", new_fps);
show_mouse( views[0].get_buffer() );
	blitBuffer(views[0].get_buffer());
	
}



void Game::play_song(int s)
{
//	if (snd==0)
		play_midi((MIDI*)music[s].dat, TRUE);
}

void Game::play_sound(int s)
{
//	if (snd==0)
	play_sample((SAMPLE*)music[s].dat, 255, 128, 1000,FALSE);
}

void Game::stop_song()
{
	play_midi(NULL,FALSE);
} 
