/*
 *  EpeeEngine.h
 *  
 *	
 *  Epee Engine
 *  Created by Alan Uthoff on 3/12/06.
	Copyright (C) 2006

	This Code is free software; you can redistribute it and/or
    modify it under the terms of the zlib/libpng License as published 
	by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.
	This software is provided 'as-is', without any express or implied warranty.
	
	In no event will the authors be held liable for any damages arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose, 
	including commercial applications, and to alter it and redistribute 
	it freely, subject to the following restrictions:

    1. The origin of this software must not be misrepresented; 
	   you must not claim that you wrote the original software. 
	   If you use this software in a product, an acknowledgment 
	   in the product documentation would be appreciated but is not required.

    2. Altered source versions must be plainly marked as such, 
		and must not be misrepresented as being the original software.

    3. This notice may not be removed or altered from any source distribution.


 */


#define Version_Number_h .27
#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
 #include <sstream>
 //#include <stdexcept>
#include "SDL_ttf.h"
#include "SDL_rotozoom.h"
#include "SDL_framerate.h"
#include "SDL_mixer.h"
#include "SDL_image.h"
#include "tinyxml.h"


#ifndef _EPEEENGINE_h_
#define _EPEEENGINE_h_



#if defined (WIN32)
//#include <windows.h>

    #if defined(_MSC_VER)
        #include "SDL.h"

    #else
         #include "SDL/SDL.h"
    #endif
//#include <gl/gl.h>
#define True_Type_Font_Location "C:\\WINDOWS\\Fonts\\" //windows
#define True_Type_Font_Defalut  "ARIAL.TTF" //windows 
#else

#if defined (__APPLE__)
#include "SDL/SDL.h"
#define True_Type_Font_Location "/Library/Fonts/"   //Macintosh
#define True_Type_Font_Defalut  "Chalkboard.ttf" //Macintosh
#endif

#endif


 



#define Type_Image 1
#define Type_TextBox 2
#define Type_Button 3
#define Type_ButtonTB 4
#define Type_Animation 5

//user defined events
#define ANIMATION_EVENT 29
#define TEXT_BOX_CHANGED_EVENT 30

//#define Anim_Funtion_Rotate 1
//#define Anim_Funtion_Motion 2

//error defintions
#define EPEE_NO_ERROR 0
#define TEXTBOX_CONVERION_ERROR 1
#define SOUND_PLAYING_ERROR 10
#define SOUND_ERROR         11
#define SOUND_LOADING_ERROR 12
#define SOUND_DELETING_ERROR 13
#define SOUND_NOT_FOUND      14
#define NULL_POINTER_PASSED 20
#define SPROCKET_NOT_FOUND 30
#define SPROCKET_ERROR     31
#define SPROCKET_DELETING_ERROR 32
#define RENDERLIST_NOT_FOUND 40
#define RENDERLIST_DELETING_ERROR 41
#define RENDERING_ERROR 50

//textbox Justifications
#define TEXT_LEFT_JUSTIFIED 100
#define TEXT_RIGHT_JUSTIFIED 102
#define TEXT_CENTER_JUSTIFIED 103

#define FONT_QUALITY_LOW 0
#define FONT_QUALITY_HIGH 1
using namespace std;


class EpeeEngineError
{
public:
		std::string m_sError_Message;
	int m_iErrorCode;
	void * ObjectWhereErrorOccured;
	EpeeEngineError(std::string _message,int _code,void * obj)
	{
	m_sError_Message=_message;
	m_iErrorCode=_code;
	ObjectWhereErrorOccured=obj;
	}
		EpeeEngineError()
	{
	m_sError_Message=" ";
	m_iErrorCode=0;
	ObjectWhereErrorOccured=NULL;
	}
		



};



	



class FileLookUp
{

	public:
		FileLookUp();
		FileLookUp(std::string _Symbol, std::string _fileName)
		{
		
		 m_ssymbol=_Symbol;
		 m_sfilename=_fileName;

		}
		std::string m_ssymbol;
		std::string m_sfilename;
		

};



class Sound 
{

	std::string m_sFileName;
	std::string m_sName;
	Mix_Chunk * m_pSound; 
	int m_iChannel;
	int m_iNumberOfTimesToLoop;
	int m_iVolume;
public:
	Sound(std::string _Name ,std::string _FileName,int _Channel=0,int _NumberOfTimesToLoop=0, int _Volume=MIX_MAX_VOLUME)
	{
		m_sName=_Name;
		m_sFileName=_FileName;
		m_iChannel=_Channel;
		m_pSound=NULL;
		m_iNumberOfTimesToLoop=_NumberOfTimesToLoop;
		if (_Volume>=0)
		{
			m_iVolume=_Volume;
		}
		else
		{
			m_iVolume=MIX_MAX_VOLUME;
		}
		
	}

	~Sound()
	{
		if (m_pSound) {
			Mix_FreeChunk(m_pSound);

		}
	}

	int GetVolume()
	{
		
		return m_iVolume;
	}
	bool SetVolume(int _Volume)
	{
		
		if (m_pSound)
		{
			m_iVolume=_Volume;
			Mix_VolumeChunk(m_pSound,m_iVolume);
			return true;
		}
		else
		{
			return false;
		}
	}
	bool LoadSound()
	{
		
	if (m_pSound)
	{
		Mix_FreeChunk(m_pSound);
	}

	m_pSound=Mix_LoadWAV(m_sFileName.c_str());
	
	if (m_pSound)
	{
		Mix_VolumeChunk(m_pSound,m_iVolume);
		return true;
	}
	else
	{
		return false;
	}
	
	
	}

	Mix_Chunk * GetMixChunkPointer()
	{
		return m_pSound;
	}

	bool SetChannel(int _ChannelToSetTo)
	{
		m_iChannel=_ChannelToSetTo;
		if (m_iChannel==_ChannelToSetTo)
		{
			return true;
		}
		else
			return false;
	}

	int GetChannel()
	{
		return m_iChannel;
	}
	
	bool SetNumberOfTimesToLoop(int _NumberOfTimesToLoop)
	{
		m_iNumberOfTimesToLoop=_NumberOfTimesToLoop;
		if (m_iNumberOfTimesToLoop==_NumberOfTimesToLoop)
		{
			return true;
		}
		else
			return false;
	}

	int GetNumberOfTimesToLoop()
	{
		return m_iNumberOfTimesToLoop;
	}
	std::string GetName()
	{
		return m_sName;
	}
};
class Sprockets //Base Class
{	int m_iz;
	std::string m_sName;
	int m_iSprocketType;
	bool m_bDraw;
	int m_iCurrentPostion;
	double m_iRotation;
	double m_iScaleX;
	double m_iScaleY;
	bool m_iAntiAliased;
	bool m_bblit;
	EpeeEngineError m_cCurrentError;
	
protected:
		bool m_bactive;

		bool  m_bDontMoveButton;
SDL_Rect m_cBox;
SDL_Surface *m_porignalSurface;
public:
	 Sprockets(std::string _NameMain,int _TypeMain)
	{
	m_sName	= _NameMain;
	m_iSprocketType=_TypeMain;
	m_bDraw=true;
	m_iz=0;
	m_bDraw=true;
	m_iCurrentPostion=0;
	 m_iRotation=0;
			 m_iScaleX=1;
			 m_iScaleY=1;
			 m_iAntiAliased=0;
			 m_porignalSurface=NULL;
			 m_bblit=true;
			 m_bactive=true;
			 m_bDontMoveButton=true;
			 	m_cCurrentError.m_iErrorCode=EPEE_NO_ERROR;
		m_cCurrentError.m_sError_Message=" ";
		m_cCurrentError.ObjectWhereErrorOccured=NULL;
	}
	Sprockets(std::string _NameMain,int _TypeMain, int _x, int _y,int _z)
	{
	m_sName	= _NameMain;
	m_iSprocketType=_TypeMain;
	m_cBox.x=_x;
	m_cBox.y=_y;
	m_iz=_z;
	m_bDraw=true;
	m_iCurrentPostion=0;
	 m_iRotation=0;
			 m_iScaleX=1;
			 m_iScaleY=1;
			 m_iAntiAliased=0;
			 m_porignalSurface=NULL;
			 m_bblit=true;
			  m_bactive=true;
			  m_bDontMoveButton=true;
			  	m_cCurrentError.m_iErrorCode=EPEE_NO_ERROR;
		m_cCurrentError.m_sError_Message=" ";
		m_cCurrentError.ObjectWhereErrorOccured=NULL;
	}
	Sprockets()
	{
	m_sName=" ";
	m_iSprocketType=Type_Image;
		m_cCurrentError.m_iErrorCode=EPEE_NO_ERROR;
		m_cCurrentError.m_sError_Message=" ";
		m_cCurrentError.ObjectWhereErrorOccured=NULL;
	}
	virtual ~Sprockets()
	{
            if(m_porignalSurface)
	SDL_FreeSurface(m_porignalSurface);
	}

	
	friend class EpeeEngine;
	friend class RenderList;


	void SetLocation(int _x,int _y)
	{
		m_cBox.x=_x;
		m_cBox.y=_y;
	}

   
	 int GetLocationX()
	{
		return m_cBox.x;
	}

	 int GetLocationY()
	{
		return m_cBox.y;
	}
	std::string GetName()
	{
		return m_sName;
	}
	int GetLocationZ ()
	{
		return m_iz; 
	}
	EpeeEngineError GetLastError()
	{
		return m_cCurrentError; 
	}
	
	void SetLastError(EpeeEngineError _error)
	{
		m_cCurrentError.m_iErrorCode=_error.m_iErrorCode;
		m_cCurrentError.m_sError_Message=_error.m_sError_Message;
		m_cCurrentError.ObjectWhereErrorOccured=_error.ObjectWhereErrorOccured;
		cerr<<"Error Has Occured In "<<this->GetName()<<"Error: "<<m_cCurrentError.m_sError_Message<<endl;

	}
	void ClearError()
	{
			m_cCurrentError.m_iErrorCode=EPEE_NO_ERROR;
		m_cCurrentError.m_sError_Message=" ";
		m_cCurrentError.ObjectWhereErrorOccured=NULL;
	}

	 virtual void SetHeightWidth(unsigned int _Height,unsigned int _Width)
	{
		m_cBox.h=_Height;
		m_cBox.w=_Width;
		
	 }

	unsigned int GetHeight()
	{
		return m_cBox.h;
	}
	unsigned int GetWidth ()
	{
		return m_cBox.w;
	}
   
	bool SetDraw(bool _Draw)
	{
		m_bDraw=_Draw;
			if(m_bDraw==_Draw)
				return true;
			else
				return false;
	}
	bool GetDraw()
	{
		return m_bDraw;
	}
	int GetType()
	{
		return m_iSprocketType; 
	}
  
   
   
   bool SetScalingFactor(double _ScalingX,double _ScalingY)
	{
		m_iScaleX=_ScalingX;
		m_iScaleY=_ScalingY;
		if (m_iScaleX==_ScalingX && m_iScaleY==_ScalingY )
		return true;
		else
		return false;
		
	}
	
	
	 bool SetScalingFactorY(double _ScalingY)
	{
		m_iScaleY=_ScalingY;
		if (m_iScaleY==_ScalingY )
		return true;
		else
		return false;
		
	}
	 bool SetScalingFactorX(double _ScalingX)
	{
		m_iScaleX=_ScalingX;
		if (m_iScaleX==_ScalingX )
		return true;
		else
		return false;
		
	}
	
	double  GetScalingFactorX()
	{
		return m_iScaleX;
	
	}
	double  GetScalingFactorY()
	{
		return m_iScaleY;
	
	}
	bool SetRotation(double _Degrees )
	{
		m_iRotation=_Degrees;
		if (m_iRotation==_Degrees)
		return true;
		else
		return false;
		
	}
   double GetRotation()
	{
		return m_iRotation;
	}
	
	bool SetAntiAliased(bool _AntiAliased )
	{
		m_iAntiAliased=_AntiAliased;
		if (m_iAntiAliased==_AntiAliased)
		return true;
		else
		return false;
		
	}
	bool GetAntiAliased()
	{
		return m_iAntiAliased;
	}
   
   int GetCurrentVectorPostion()
   {
       return m_iCurrentPostion;
   }

   virtual Sprockets * WasClicked(int _mouselocationX, int _mouselocationY)
	{
	
	if(m_bactive )
	{
		
		
		if( ( _mouselocationX >  m_cBox.x ) && ( _mouselocationX <  m_cBox.x +  m_cBox.w ) && (_mouselocationY >  m_cBox.y ) && (_mouselocationY < m_cBox.y + m_cBox.h ) )
		{
			return this;
		}
		
		
	
	
	}
	
	
	return NULL;
	
}
void DisableClick()
{	
	m_bactive=false;
}
void EnableClick()
{
	m_bactive=true;
}
bool GetIsClickEnabled()
{
	return m_bactive;
}

void DisableAndTurnOffDraw()
{
m_bactive=false;
SetDraw(false);
}

void EnableAndTurnOnDraw()
{
m_bactive=true;
SetDraw(true);
}


void SetDontMoveOnClick(bool _flag)
{
m_bDontMoveButton=_flag;
}

bool GetDontMoveOnClick()
{
	return m_bDontMoveButton;
}
    
protected:

 
	bool GetBlit()
   {
        return this->m_bblit;


    }
		virtual SDL_Surface * SetSurface()
	{
        return NULL; 
    }
		virtual SDL_Surface * GetSprocketSurface()
    {
                return m_porignalSurface;
                }
    /*virtual  SDL_Surface * GetSurface()
    {
             return m_porignalSurface;
             }*/
		SDL_Rect * GetRect()
	{
			return  &m_cBox;
	}
          bool SetCurrentArrayPostion(int _newPostion)
          {
             m_iCurrentPostion=_newPostion;
             if(  m_iCurrentPostion==_newPostion)
             {
                  return true;
              }
              else
              return false;
          }
	void SetType(int _type)
	{
		m_iSprocketType=_type;	
	}
	void SetLocationZ(int _z)
	{
		m_iz=_z;//do not call this function call ChangeSprocketZ instead
	}
void SetBlit(bool _blit)
{
m_bblit=_blit;
}
	
};


class RenderList
{


	std::string m_sNameOfRenenderList;
std::vector  <Sprockets*> m_vSprocketsList;
Sprockets  * m_pLastSprocketFound;
int m_uiTotalSprocketsCreated;
EpeeEngineError m_cCurrentError;

public:
	
	RenderList(std::string _name)
{
	m_sNameOfRenenderList=_name;
	 m_pLastSprocketFound=NULL;
m_uiTotalSprocketsCreated=0;
this->ClearError()	;
}
~RenderList()
{
		unsigned int TotalSprocketsDeleted=0;
	
	while(m_vSprocketsList.size()!=0)
				{

					
					
					DestroySprocket(m_vSprocketsList[0]->GetName());
					TotalSprocketsDeleted++;

					

				}

	if (m_uiTotalSprocketsCreated!=0) {
	cerr<<"*****WARING MEMORY LEAK****"<<endl;
	cerr<<"There are still "<<m_uiTotalSprocketsCreated<<" Sprockets that where not deleted"<<endl;
}
	
	
}
friend class EpeeEngine;
	EpeeEngineError GetLastError()
	{
		return m_cCurrentError; 
	}
	
	void SetLastError(EpeeEngineError _error)
	{
		m_cCurrentError.m_iErrorCode=_error.m_iErrorCode;
		m_cCurrentError.m_sError_Message=_error.m_sError_Message;
		m_cCurrentError.ObjectWhereErrorOccured=_error.ObjectWhereErrorOccured;
		cerr<<"Error Has Occured In "<<this->GetName()<<"Error: "<<m_cCurrentError.m_sError_Message<<endl;

	}
	void ClearError()
	{
			m_cCurrentError.m_iErrorCode=EPEE_NO_ERROR;
		m_cCurrentError.m_sError_Message=" ";
		m_cCurrentError.ObjectWhereErrorOccured=NULL;
	}
std::string GetName()
	{
		return m_sNameOfRenenderList;
	}

bool InsertSprocket(Sprockets * _newSprocket,bool _new=true)
{
#if defined DEBUG_ME

	int tempz=0;
		if(m_vSprocketsList.size()!=0)
		tempz=m_vSprocketsList[m_vSprocketsList.size()-1]->GetLocationZ();


#endif
if (m_vSprocketsList.size()!=0 && !(m_vSprocketsList[m_vSprocketsList.size()-1]->GetLocationZ() > _newSprocket->GetLocationZ()))
{
//m_vSprocketsList.push_back(_newSprocket);
	for(unsigned int index2=0; index2<m_vSprocketsList.size();index2++)
	{
		
		if(_newSprocket->GetLocationZ()>=m_vSprocketsList[index2]->GetLocationZ())
		{
		m_vSprocketsList.insert(m_vSprocketsList.begin()+index2,_newSprocket);
	    _newSprocket->SetCurrentArrayPostion(index2);
		if(_new)
		m_uiTotalSprocketsCreated++;
    	break;
		}
		
	}


}
else
{
m_vSprocketsList.push_back(_newSprocket);
if(_new)
m_uiTotalSprocketsCreated++;
}
////need to add in accounts for z / depth
	return true;

}



bool DestroySprocket(std::string _name)
{
	Sprockets * temp=NULL;
	bool retunval=false;
		for(unsigned int index = 0;index<m_vSprocketsList.size();index++)
	{
			if(m_vSprocketsList[index]->GetName()==_name)
			{
				if(m_pLastSprocketFound!=NULL)
				{
               if(m_pLastSprocketFound->GetName()==_name)
                    m_pLastSprocketFound=NULL;
				}
			   temp=m_vSprocketsList[index];
				m_vSprocketsList.erase(m_vSprocketsList.begin()+index);
				delete temp;
				 m_uiTotalSprocketsCreated--;
				retunval=true;
				index=m_vSprocketsList.size();

			}
		}
		if (!retunval) {
		
//	m_sCurrentError="Could Not Find And Delete Sprocket ";
//	m_sCurrentError=m_sCurrentError+_name;
			 EpeeEngineError temperror("Could Not Find And Delete Sprocket "+_name,SPROCKET_DELETING_ERROR,this);
				 SetLastError(temperror);

		}
	return retunval;
}
bool UpdateVectorlocation()
{
     for(unsigned int index = 0;index<m_vSprocketsList.size();index++)
	{
             m_vSprocketsList[index]->SetCurrentArrayPostion(index);
             
             
             }
             return true;
 }

	bool ChangeSprocketZ(Sprockets * _SprocketToChange,int _newZ)
{
	
UpdateVectorlocation();
m_vSprocketsList.erase(m_vSprocketsList.begin()+_SprocketToChange-> GetCurrentVectorPostion());
_SprocketToChange->SetLocationZ(_newZ);
InsertSprocket(_SprocketToChange);
return true;

}

	Sprockets *  FindSprockets(std::string _name)
{
	#if defined(DEBUG_ME)
	std::string temp_name=" ";
#endif
	if(m_pLastSprocketFound!=NULL)
	{
	
if(this->m_pLastSprocketFound->GetName()==_name)
{
         return m_pLastSprocketFound;
         } 
	}   
for (unsigned int index=0;index<m_vSprocketsList.size();index++)
{
#if defined(DEBUG_ME)
temp_name=m_vSprocketsList[index]->GetName();
	if(temp_name==_name)
			{
                         m_pLastSprocketFound=m_vSprocketsList[index];
			   return m_vSprocketsList[index];

			}
#else


                           


if(m_vSprocketsList[index]->GetName()==_name)
			{
               m_pLastSprocketFound=m_vSprocketsList[index];
			   return m_vSprocketsList[index];

			}

#endif
	

}
	//m_sCurrentError="Could Not Find Sprocket ";
//	m_sCurrentError=m_sCurrentError+_name;
//cerr<<"Could Not Find Sprocket "<<_name<<endl;
	 EpeeEngineError temperror("Could Not Find Sprocket "+_name,SPROCKET_NOT_FOUND,this);
				 this->SetLastError(temperror);
return NULL;
	}

unsigned int GetTotalSprockesCreated()
{
	return m_uiTotalSprocketsCreated;
}

void RemoveSprocketFromList(Sprockets * _sprocketToErase)
{
for(unsigned int index = 0;index<m_vSprocketsList.size();index++)
	{
			if(m_vSprocketsList[index]->GetName()==_sprocketToErase->GetName())
			{
			m_vSprocketsList.erase(m_vSprocketsList.begin()+index);
			break;
			}
}
m_pLastSprocketFound=NULL;
m_uiTotalSprocketsCreated--;
}


};

class textBox :public Sprockets
{

	

	std::string m_sTrue_Type_Font_Location;
	std::string m_sTextBoxMessage;
	std::string m_sFont;
	int m_iFontPoint;
	SDL_Color m_cColorOfText;
	//unsigned int m_uix;
	//unsigned int m_uiy;
	bool m_bblit;
	TTF_Font *m_pLoadedFont;
	bool m_bEditable;
	bool m_bNumbersOnly;
	int m_iJustify;
	int m_iOffsetXJustiy;
	bool m_bDoNotClipTextHeight;
	bool m_bDoNotClipTextWidth;
	int m_bQuality;
	//	unsigned int m_uiheight;
//	unsigned int m_uiwidth;

public:

	
	 protected:
 	textBox(int _Obj_Type,std::string _NameTextBox,int _x,int _y,int _z,std::string _TextBoxMessage=" ",unsigned int _height=-1,unsigned int _width=-1,std::string _Font=True_Type_Font_Defalut,int _FontPoint=18,unsigned int _red=255,unsigned int _blue=255 ,unsigned int _green=255,std::string _FontPath = True_Type_Font_Location):Sprockets(_NameTextBox,_Obj_Type)
	{
	
	 m_sTextBoxMessage=_TextBoxMessage;
	 SetLocation(_x,_y);
	 
	 SetLocationZ(_z);
	// m_sFont=_Font;
	 m_bQuality=FONT_QUALITY_LOW;
	 m_iFontPoint=_FontPoint;
		m_cColorOfText.r=_red;
			m_cColorOfText.b=_blue;
			m_cColorOfText.g=_green;
		m_sTrue_Type_Font_Location=_FontPath;//True_Type_Font_Location  is defined at the top of the file
	m_bblit=true;
	m_pLoadedFont=NULL;
	m_bEditable=false;
	m_bNumbersOnly=false;
		m_iJustify=TEXT_LEFT_JUSTIFIED;
		m_iOffsetXJustiy=0;
    //m_pLoadedFont=
		this->SetFont(_Font);
	 SetHeightWidth(_height,_width);
	 
	}
	 public:
	textBox(std::string _NameTextBox, int _x, int _y,int _z,std::string _TextBoxMessage=" ",unsigned int _height=-1,unsigned int _width=-1,std::string _Font=True_Type_Font_Defalut,int _FontPoint=18,unsigned int _red=255,unsigned int _blue=255 ,unsigned int _green=255,std::string _FontPath = True_Type_Font_Location):Sprockets(_NameTextBox,Type_TextBox)
	{
	
	 m_sTextBoxMessage=_TextBoxMessage;
	 SetLocation(_x,_y);
	 
	 SetLocationZ(_z);
	 //m_sFont=_Font;
	 m_bQuality=FONT_QUALITY_LOW;
	 m_iFontPoint=_FontPoint;
		m_cColorOfText.r=_red;
			m_cColorOfText.b=_blue;
			m_cColorOfText.g=_green;
		m_sTrue_Type_Font_Location= _FontPath;//True_Type_Font_Location  is defined at the top of the file
	m_bblit=true;
	m_pLoadedFont=NULL;
	m_bEditable=false;
	m_bNumbersOnly=false;
	m_iJustify=TEXT_LEFT_JUSTIFIED;
	m_iOffsetXJustiy=0;
    //m_pLoadedFont=
	this->SetFont(_Font);
	this->SetHeightWidth(_height,_width);
	
	}

	
	textBox()
	{
             }

	~textBox()
	{
	if(m_pLoadedFont)
         		 TTF_CloseFont(m_pLoadedFont);
	}
	
	friend class EpeeEngine;
	bool GetClipTextHeight()
	{
		return m_bDoNotClipTextHeight;
	}
		bool GetClipTextWidth()
	{
		return m_bDoNotClipTextWidth;
	}
	void SetQuality(int _Quality)
	{
		if(_Quality!=m_bQuality && _Quality>=FONT_QUALITY_LOW && _Quality<=FONT_QUALITY_HIGH )
		{
		m_bQuality=_Quality;
			this->SetBlit(true);
		}
	}
	int GetQuality()
	{
		return m_bQuality;

	}
		bool CanStringFitInTextBox(std::string _StringToFit)
	{
			int w=0,h=0;
			if (m_pLoadedFont) 
			{
				if (TTF_SizeText(m_pLoadedFont,_StringToFit.c_str(),&w,&h)) 
				{
					return false;
				}
				if(w<=this->m_cBox.w )
					return true;
				else
					return false;
			}
			else
				return false;

	}
	void SetText(std::string _text,bool _setevent=false)
	{
			if(m_bEditable)
			{
				if(!CanStringFitInTextBox(_text))
				return;
			}
		if (m_sTextBoxMessage!=_text)
		{
			SetBlit(true);
		}
		
		m_sTextBoxMessage=_text;
		if(GetBlit())
		{
		if(m_bDoNotClipTextHeight || m_bDoNotClipTextWidth)
		{
			if(m_bDoNotClipTextHeight )
			 {
				SetHightBasedOfRenderedText();
				
			 }
			 if(m_bDoNotClipTextWidth)
			 {
				SetWidthBasedOfRenderedText();
				
			 }
		}
		}
		
		if (_setevent) {
		
		SDL_Event event;

		event.type = SDL_USEREVENT;
		event.user.code = TEXT_BOX_CHANGED_EVENT;
		event.user.data1 = this;
		event.user.data2 = 0;
		SDL_PushEvent(&event);
		}
		SetJustifyOffset();
		
	}

	 virtual void SetHeightWidth(unsigned int _Height,unsigned int _Width)
	{
		
		 if (_Height==-1 || _Width==-1) 
		 {
			 if(_Height==-1)
			 {
				SetHightBasedOfRenderedText();
				_Height=this->GetHeight();
				m_bDoNotClipTextHeight=true;
			 }
			 else
			 {
				m_bDoNotClipTextHeight=false;
			 }
			 if(_Width==-1)
			 {
				SetWidthBasedOfRenderedText();
				_Width=this->GetWidth();
				m_bDoNotClipTextWidth=true;
			 }
			 else
			 {
				 m_bDoNotClipTextWidth=false;
			 }
		 
		
			

		}
		 else
		 {
			  m_bDoNotClipTextWidth=false;
			  m_bDoNotClipTextHeight=false;

		 }
		
			Sprockets::SetHeightWidth(_Height,_Width);
		
				
		 
		
	 }

	void SetHightBasedOfRenderedText()
	{
			int w=0,h=0;
			if (m_pLoadedFont) {
			
			if (TTF_SizeText(m_pLoadedFont,m_sTextBoxMessage.c_str(),&w,&h)) {
				return;
			}
			
	Sprockets::SetHeightWidth(h,this->GetWidth());
			}

	}		
		void SetWidthBasedOfRenderedText()
	{
			int w=0,h=0;
			if (m_pLoadedFont) {
			if (TTF_SizeText(m_pLoadedFont,m_sTextBoxMessage.c_str(),&w,&h)) {
				return;
			}
			
		Sprockets::SetHeightWidth(this->GetHeight(),w);

			}
	}
	int GetJustifyOffset()
	{
		return m_iOffsetXJustiy;
	}
	int GetTextJustification()
	{
		return m_iJustify;
	}

	void SetTextJustification(int _justify)
	{
		if (_justify==TEXT_LEFT_JUSTIFIED || _justify==TEXT_RIGHT_JUSTIFIED || _justify ==TEXT_CENTER_JUSTIFIED) {
		m_iJustify=_justify;
		 SetJustifyOffset();
		
		}
	}

	std::string GetText ()
	{
		return m_sTextBoxMessage;
	}


template <typename value> value GetTextToNumericData(value temp)
	{value tempint=0;
			std::istringstream tempstream(m_sTextBoxMessage);
			if (!(tempstream>>tempint)) {
				std::string tempstring ="Could not convert"+m_sTextBoxMessage+"to the specified data type";
				 EpeeEngineError temperror(tempstring,TEXTBOX_CONVERION_ERROR,this);
				this->SetLastError(temperror);
				return 0;
			}
			this->ClearError();
			return tempint;
	}

	int GetTextToInt()
	{int tempint=0;
			/*std::istringstream tempstream(m_sTextBoxMessage);
			if (!(tempstream>>tempint)) {
				std::string tempstring ="Could not convert"+m_sTextBoxMessage+" to an int";
				 EpeeEngineError temperror(tempstring,TEXTBOX_CONVERION_ERROR,this);
				this->SetLastError(temperror);
				return 0;
			}
			this->ClearError();*/
			return GetTextToNumericData(tempint);
	}
	float GetTextToFloat()
	{float tempint=0;
			/*std::istringstream tempstream(m_sTextBoxMessage);
			if (!(tempstream>>tempint)) {
				std::string tempstring ="Could not convert"+m_sTextBoxMessage+" to an float";
				 EpeeEngineError temperror(tempstring,TEXTBOX_CONVERION_ERROR,this);
				this->SetLastError(temperror);
				return 0;
			}
			this->ClearError();*/
			return GetTextToNumericData(tempint);
	}


	template <typename datatype> bool  SetTextFromNumericData(datatype _value,bool _setevent=false)
	{datatype tempint=_value;
			std::ostringstream tempstream;
			if (!(tempstream<<_value)) {
				
				std::string tempstring ="Could not convert numeric data to string";
				 EpeeEngineError temperror(tempstring,TEXTBOX_CONVERION_ERROR,this);
				this->SetLastError(temperror);
				return false;
				
			}
			this->SetText(tempstream.str(),_setevent);
			this->ClearError();
			return true;
	}




	bool  SetTextFromInt(int _value,bool _setevent=false)
	{/*int tempint=_value;
			std::ostringstream tempstream;
			if (!(tempstream<<_value)) {
				
				std::string tempstring ="Could not convert int to string";
				 EpeeEngineError temperror(tempstring,TEXTBOX_CONVERION_ERROR,this);
				this->SetLastError(temperror);
				return false;
				
			}
			this->SetText(tempstream.str(),_setevent);
			this->ClearError();
			return true;*/
		return SetTextFromNumericData( _value, _setevent);
	}

	bool SetTextFromFloat(float _value,bool _setevent=false)
	{/*float tempint=_value;
			std::ostringstream tempstream;
			if (!(tempstream<<_value)) {
				
				std::string tempstring ="Could not convert float to string";
				 EpeeEngineError temperror(tempstring,TEXTBOX_CONVERION_ERROR,this);
				this->SetLastError(temperror);
				return false;
				
			}
			this->SetText(tempstream.str(),_setevent);
			this->ClearError();
			return true;*/
	return SetTextFromNumericData( _value, _setevent);
	}


	std::string GetFont()
	{
		return m_sFont;
	}
	void SetFont(std::string _FontArg)
	{
		if(m_sFont!=_FontArg)
		{
		
		m_sFont=_FontArg;
		LoadFont();
		}
	}
	int GetFontPoint()
	{
		return m_iFontPoint;
	}
	void SetFontPoint(int _FontPointArg)
	{	if(m_iFontPoint!=_FontPointArg)
		{
		m_iFontPoint=_FontPointArg;
		LoadFont();
		}
	}
	SDL_Color GetTextColor()
	{
		return m_cColorOfText;
	}
	bool SetTextColor(unsigned int _red,unsigned int _blue ,unsigned int _green)
	{
		if(m_cColorOfText.r!=_red || m_cColorOfText.b!=_blue || m_cColorOfText.g!=_green)
		{
			m_cColorOfText.r=_red;
			m_cColorOfText.b=_blue;
			m_cColorOfText.g=_green;
			SetBlit(true);;
		}

	return true;
	}
	
	std::string GetFontPath()
	{
		return m_sTrue_Type_Font_Location;
	}
	void SetFontPath(std::string _Location)
	{
		m_sTrue_Type_Font_Location=_Location;
		LoadFont();
	}
	void SetEditable(bool _flag)
	{
		m_bEditable=_flag;

	}
	bool GetEditable()
	{
		return m_bEditable;
	}
		void SetNumbersOnly(bool _flag)
	{
		m_bNumbersOnly=_flag;

	}
	bool GetNumbersOnly()
	{
		return m_bNumbersOnly;
	}
	 protected:

	 TTF_Font * GetFontPointer()
	{
             return m_pLoadedFont;
          }

	SDL_Surface * SetSurface()
	{
		SDL_Rect temp;
		std::string spaceFilledString=" ";
		std::string Space=" ";
		int SpaceSizeWidth=0;
		unsigned int number_of_spaces_needed=0;
		if((m_iJustify==TEXT_RIGHT_JUSTIFIED || m_iJustify ==TEXT_CENTER_JUSTIFIED) &&  m_iOffsetXJustiy>0)
		{
			
			temp.x=m_iOffsetXJustiy;
			if (m_pLoadedFont!=NULL) 
			{
			TTF_SizeText(m_pLoadedFont,Space.c_str(),&SpaceSizeWidth,NULL);
			number_of_spaces_needed=temp.x/SpaceSizeWidth;
			std::string temp(number_of_spaces_needed,' ');
			spaceFilledString=temp;
			}
		}
		else
		{
			temp.x=this->m_cBox.x;
		}
		temp.y=0;
		temp.w=0;
		temp.h=0;
		
		if (m_pLoadedFont!=NULL) 
		{
		
         if(m_porignalSurface)
         {
         SDL_FreeSurface(m_porignalSurface);
	      }
		spaceFilledString=spaceFilledString+m_sTextBoxMessage;
		switch (m_bQuality)
		{
		case FONT_QUALITY_HIGH :
			m_porignalSurface=TTF_RenderText_Blended( m_pLoadedFont,spaceFilledString.c_str(),m_cColorOfText);
		break;
		case FONT_QUALITY_LOW:
			m_porignalSurface=TTF_RenderText_Solid( m_pLoadedFont,spaceFilledString.c_str(),m_cColorOfText);
		break;
		default:
			m_porignalSurface=TTF_RenderText_Solid( m_pLoadedFont,spaceFilledString.c_str(),m_cColorOfText);
		break;
		}

	   
        
         if(m_porignalSurface)
		 {
			
		 SetBlit(false);
		 }
         else
         SetBlit(true);
        return    m_porignalSurface; 
	}
	else
	{
		return NULL;
	}
	return NULL;
     }

	void LoadFont()
	{
         std::string FontToLoad=m_sTrue_Type_Font_Location+ m_sFont;
         if(m_pLoadedFont)
         {
         TTF_CloseFont(m_pLoadedFont);
         m_pLoadedFont=TTF_OpenFont(FontToLoad.c_str(),m_iFontPoint);
         }
         else
         {
            m_pLoadedFont=TTF_OpenFont(FontToLoad.c_str(),m_iFontPoint);
         }
         if(!m_pLoadedFont)
         {
                           cerr<<"could not load font "<<FontToLoad.c_str()<<" for Sprocket "<<GetName()<<endl;
                           
                           }
                           else
                           {
							    
                                cout<<"loaded  font "<<FontToLoad.c_str()<<" for Sprocket "<<GetName()<<endl;
                           }
                           
         	SetBlit(true);
         
     }

protected:
	void SetJustifyOffset()
	{
	
		std::string tempforJustiying="";
		int w=0,h=0,spacesizewidth=0;
		if (m_iJustify!=TEXT_LEFT_JUSTIFIED && m_pLoadedFont!=NULL) {
			
			
			if (TTF_SizeText(m_pLoadedFont,m_sTextBoxMessage.c_str(),&w,&h)) {
				return;
			}
			switch(m_iJustify) {
			case TEXT_RIGHT_JUSTIFIED:
				m_iOffsetXJustiy=this->GetWidth()-w;
				break;
			case TEXT_CENTER_JUSTIFIED:
					m_iOffsetXJustiy=this->GetWidth()-w;
					m_iOffsetXJustiy=m_iOffsetXJustiy/2;
				break;
		
			}
		}

	}

};



class image :public Sprockets
{SDL_Rect m_cOrgialDem;
	std::string m_sFileName;
	SDL_Rect ClipingRect;
	/*double m_iRotation;
	double m_iScaleX;
	double m_iScaleY;
	bool m_iAntiAliased;*/
	bool m_bClip;
	bool m_bTransparency;

public:
	image (std::string _FileNameImage, std::string _NameImageHere,int _x,int _y,int _z,bool _Transparency=false):Sprockets( _NameImageHere,Type_Image ,_x, _y, _z)
	{
		m_sFileName=_FileNameImage;
			/* m_iRotation=0;
			 m_iScaleX=1;
			 m_iScaleY=1;
			 m_iAntiAliased=0;*/
			 m_bClip=false;
			 m_bTransparency=_Transparency;
			 

	}
	
	~image()
	{
               
	}
	friend class EpeeEngine;
	
	std::string GetFileName()
	{
		return m_sFileName;
	}
	void SetClippingRect(int _x,int _y,int _w,int _h)
	{
		ClipingRect.x=_x;
		ClipingRect.y=_y;
		ClipingRect.w=_w;
		ClipingRect.h=_h;
		m_bClip=true;
	}
	bool GetClip()
	{
		return m_bClip;
	}
	int GetClippingX()
	{
		return ClipingRect.x;
	}
	int GetClippingY()
	{
		return ClipingRect.y;
	}
	int GetClippingW()
	{
		return ClipingRect.w;
	}
	int GetClippingH()
	{
		return ClipingRect.h;
	}

	void SetTransparency (bool _Transparency)
	{
		m_bTransparency=_Transparency;
		//this->GetSprocketSurface()->flags=this->GetSprocketSurface()->flags & 0x11101111;
		//#define SDL_SRCALPHA	0x00010000
	}
	bool GetTransparency()
	{
		return m_bTransparency;
	}

 protected:
	 bool LoadFileSurface()
	{
		 //SDL_Surface * Temp_Surface;
		if(m_sFileName==" ")
		{
			cerr<<"no file name associated with "<<GetName()<<endl;
			
			return false;
		}
			m_porignalSurface=IMG_Load(m_sFileName.c_str());
		//Temp_Surface=IMG_Load(m_sFileName.c_str());
		//if (Temp_Surface) {
		//m_porignalSurface=SDL_DisplayFormat(Temp_Surface);
		//SDL_FreeSurface(Temp_Surface);
		//}
		//else
		//{
		//m_porignalSurface=NULL;
		//}
	//	m_porignalSurface=SDL_LoadBMP(m_sFileName.c_str()); 
         cout<<"Image File Name "<<m_sFileName.c_str()<<endl;
         if(m_porignalSurface)
         {
			 m_cOrgialDem.h=m_porignalSurface->h;
			m_cOrgialDem.w=m_porignalSurface->w;
			m_cOrgialDem.x=0;
				m_cOrgialDem.y=0;
			 m_cBox.h=m_porignalSurface->h;
			 m_cBox.w=m_porignalSurface->w;
                              cout<<"Loaded image correctly"<<endl;
         return true;
         }
         else
         {
             cerr<<"Loaded image INcorrectly "<<IMG_GetError()<<endl;
			 cout<<"Loaded image INcorrectly "<<IMG_GetError()<<endl;
         return false;
         }
     }

	image (std::string _FileNameImage, std::string _NameImageHere,int _x,int _y,int _z,int _type,bool _Transparency=false):Sprockets( _NameImageHere,_type ,_x, _y, _z)
	{
		m_sFileName=_FileNameImage;
		 m_bClip=false;
		m_bTransparency=_Transparency;
		
	}
	 image()
	{
		 
		 
	}
	image(std::string _FileNameImage)
	{
		m_sFileName=_FileNameImage;
		
	}
SDL_Rect * GetClippingRect()
{
return &ClipingRect;
}

SDL_Rect * GetOrignalRect()
{
return &m_cOrgialDem;
}
	

};








class Animation : public image
{
private:
	int m_ianimationFPS;
	float m_iFrameEverInMillSecounds;
	int m_iStripNumFrames;
	int m_iNumberOfRows;
	int m_iCurrentFrame;
	int m_iLoop;
	float m_iCurrentTime;
	float m_iPrevTime;
	bool m_bPlaying;
	int m_iNumberofTimesPlayed;
	bool m_bReversPlay;
	int m_iframeEvent;
		unsigned int WidthForBoxInPixles;
				unsigned int HeightForBoxInPixles;
	
public:
	Animation(std::string _FileName,std::string _AnimationName,int _fps,int _x,int _y, int _z,int _AnimStripFrames,int _StartFrame=0,int _Loop=1,bool _Transparency=false,bool _StartNow=true, int _NumberOfRows=1):image( _FileName, _AnimationName, _x, _y, _z,Type_Animation,_Transparency)
	{
		m_ianimationFPS=_fps;
		m_iFrameEverInMillSecounds=1000/m_ianimationFPS;
		if(_AnimStripFrames>=0)
		{
		m_iStripNumFrames=(_AnimStripFrames-1);
		}
		else
		{
		m_iStripNumFrames=0;
		}
		if(_NumberOfRows<0)
		{
		m_iNumberOfRows=1;
		}
		else
		{
	    m_iNumberOfRows=_NumberOfRows;
		}
		
		if (_Loop>=0) {
		m_iLoop=_Loop;
		}
		else{
		m_iLoop=1;
		}
		
		m_iPrevTime=0;
		m_iCurrentTime=SDL_GetTicks();
		m_bPlaying=_StartNow;
		JumpToFrame(_StartFrame);
		m_iNumberofTimesPlayed=0;
		m_bReversPlay=false;
		m_iframeEvent=-1;
	
	}
	
	
	/*
	virtual void AttachSript()
	{
		
		
	}*/
	void  JumpToFrame(int _Frame)
	{
		if (_Frame>=0 && _Frame<=m_iStripNumFrames) {
			m_iCurrentFrame=_Frame;
			SetClipingBoxForFrame();
		}

	}
	void UpdateTime()
	{
		
	float time=SDL_GetTicks()-m_iCurrentTime;


		
		CheckForNextFrame(time);
			//cout<<"Animation Upate Current Frame "<<m_iCurrentFrame<<" Time Diffrence "<<m_iCurrentTime-m_iPrevTime<<" frame pre millsecound "<<m_iFrameEverInMillSecounds<<endl;
		
			SetClipingBoxForFrame();
			
		


	}
	int GetFPS()
	{
		return m_ianimationFPS;
	}
	
	void SetFPS(int _fps)
	{
		m_ianimationFPS=_fps;
		m_iFrameEverInMillSecounds=1000/m_ianimationFPS;
		UpdateTime();
	
	}
		void SetClipingBoxForFrame()
		{
		
			if(m_porignalSurface)
         {
               int CurrentRow=0;
			   if(((m_iCurrentFrame+1)%(m_iStripNumFrames+1)))
			   {
				   CurrentRow=((m_iCurrentFrame+1)/(m_iStripNumFrames+1));
			   }
			   else
			   {
				   CurrentRow=((m_iCurrentFrame+1)/(m_iStripNumFrames+1));
				   CurrentRow--;
			   }
			   WidthForBoxInPixles=GetOrignalRect()->w/(m_iStripNumFrames+1);
		       HeightForBoxInPixles=GetOrignalRect()->h/m_iNumberOfRows;
		       int xpostion=0;
               if(CurrentRow!=0)
               {
               xpostion=WidthForBoxInPixles*((( (m_iCurrentFrame+1)-( CurrentRow*(m_iStripNumFrames+1) )))-1);
               }
               else
               {
                  xpostion=WidthForBoxInPixles*m_iCurrentFrame;
               }
               SetClippingRect(xpostion,HeightForBoxInPixles*CurrentRow ,WidthForBoxInPixles,HeightForBoxInPixles);
				
				
			}

		}
		void StopAnimation()
		{
			m_bPlaying=false;
		}
		void PlayAnimation()
		{
			m_bPlaying=true;
			m_iNumberofTimesPlayed=0;

		}
		void SetLoop(int _Loop)
		{
				if (_Loop>=0) {
				m_iLoop=_Loop;
				}
				else{
				m_iLoop=1;
				}
		}
		int GetLoop()
		{
			return m_iLoop;
		}
		int GetCurrentFrame()
		{
			return m_iCurrentFrame;
		}

		bool GetReversPlay()
		{
			return m_bReversPlay;
		}
		void SetReversPlay(bool _BackWards)
		{
			m_bReversPlay=_BackWards;
		}
		int GetTotalNumberOfFrames()
		{
			return ((m_iStripNumFrames+1)*m_iNumberOfRows)-1;
		}
		int GetTotalNumberOfRows()
		{
            return m_iNumberOfRows;
        }
        int GetTotalNumberOfFramesPerRow()
		{
			return m_iStripNumFrames;
		}
        
		int GetNumberOfTimesPlayed()
		{
			return m_iNumberofTimesPlayed;
		}
		void SetFrameEvent(int _frame)
		{
			m_iframeEvent=_frame;
		}
		int GetFrameEvent()
		{
			return m_iframeEvent;
		}
		bool IsPlaying()
		{
			return m_bPlaying;
		}

private:
		
		void CheckForNextFrame(float _time)
	{
		if (_time>=m_iFrameEverInMillSecounds)
		{
			m_iCurrentTime=SDL_GetTicks();
			if ((m_iCurrentFrame<this->GetTotalNumberOfFrames() && m_bReversPlay==false)|| ((m_iCurrentFrame-1)>=0 && m_bReversPlay==true)) {
			bool setevent=false;
				if (m_bPlaying) {
					if (m_bReversPlay) {
						m_iCurrentFrame--;

							if (m_iCurrentFrame<=m_iframeEvent && m_iframeEvent!=-1) {
								setevent=true;
							}
							else
							{
								setevent=false;
							}

					}
					else
					{
					m_iCurrentFrame++;
					if (m_iCurrentFrame>=m_iframeEvent && m_iframeEvent!=-1) {
						setevent=true;
							}
							else
							{
							setevent=false;	
							}
					}
					if (setevent && m_bPlaying) {
					
						SDL_Event event;

						event.type = SDL_USEREVENT;
						event.user.code = ANIMATION_EVENT;
						event.user.data1 = this;
						event.user.data2 = 0;
						SDL_PushEvent(&event);
						m_iframeEvent=-1;

				}

						

				}
			
			}
			else
			{
				if (m_bPlaying)
                 {
						m_iNumberofTimesPlayed++;
							if (m_iNumberofTimesPlayed>=m_iLoop && m_iLoop!=0) 
                            {
								StopAnimation();
							}
						    else
							{
							
						if (m_bReversPlay) 
                        {
						m_iCurrentFrame=this->GetTotalNumberOfFrames();
						}
						else
						{
						
						m_iCurrentFrame=0;
						}
					
				             }
							

				}

			}
		SetClipingBoxForFrame();	

		}
			
			

		}


		
		
	
	
};














class Button :public image
{
	
//bool m_bDontMove;
//bool m_bactive;
	int m_ibuttonheight;
	int m_ibuttonwidth;
	int m_ibuttonx;
	int m_ibuttony;

public:
	//SButton(std::string _ButtonFileNameImage, std::string _ButtonNameImageHere,unsigned int _Buttonx,unsigned int _Buttony,int _Buttonz,bool _SButtonactive=true):imageBMP( _ButtonFileNameImage):Sprockets(  _ButtonNameImageHere,Type_Button ,_Buttonx ,_Buttony,_Buttonz )
	//{
	//	m_bactive=_SButtonactive;
	//}

Button(std::string _ButtonFileNameImage, std::string _ButtonName,int _Buttonx,int _Buttony,int _Buttonz,bool _Transparency=false,bool _SButtonactive=true):image( _ButtonFileNameImage, _ButtonName, _Buttonx, _Buttony, _Buttonz,Type_Button,_Transparency)
{
	m_bactive=_SButtonactive;
	 m_ibuttonheight=-1;
	m_ibuttonwidth=-1;
	m_ibuttonx= -1;
	m_ibuttony=-1;
	m_bDontMoveButton=false;
	

}
Button(std::string _ButtonName,int _Buttonx,int _Buttony,int _Buttonz,int m_iButtonHeight,int m_iButtonwidth,bool _Transparency=false,bool _SButtonactive=true):image(" ", _ButtonName, _Buttonx, _Buttony, _Buttonz,Type_Button,_Transparency)
{
	m_bactive=_SButtonactive;
	 m_ibuttonheight=m_iButtonHeight;
	 m_ibuttonwidth=m_iButtonwidth;
	 m_ibuttonx= _Buttonx;
	 m_ibuttony=_Buttony;
	 m_bDontMoveButton=false;

	
}

Button()
{
	
}
~Button(){
	
}

virtual Sprockets * WasClicked(int _mouselocationX, int _mouselocationY)
{
	SDL_Rect *clipbox =GetRect();
	if(m_bactive)
	{
		
	if( m_ibuttonheight ==-1 &&  m_ibuttonwidth==-1)
	{
		
		if( ( _mouselocationX > clipbox->x ) && ( _mouselocationX < clipbox->x + clipbox->w ) && (_mouselocationY > clipbox->y ) && (_mouselocationY < clipbox->y + clipbox->h ) )
		{
			return this;
		}
		
		
	}
	
	else
	{
		
		
		if( ( _mouselocationX >  m_ibuttonx ) && ( _mouselocationX <  m_ibuttonx +  m_ibuttonwidth ) && (_mouselocationY >  m_ibuttony ) && (_mouselocationY <  m_ibuttony + m_ibuttonheight ) )
		{
			return this;
		}
		
		
	}
	
	}
	
	
	return NULL;
	
}
/*
void Disable()
{	
	m_bactive=false;
}
void Enable()
{
	m_bactive=true;
}
bool GetActive()
{
	return m_bactive;
}

void DisableAndTurnOffDraw()
{
m_bactive=false;
SetDraw(false);
}

void EnableAndTurnOnDraw()
{
m_bactive=true;
SetDraw(true);
}


void SetDontMoveOnClick(bool _flag)
{
m_bDontMoveButton=_flag;
}

bool GetDontMoveOnClick()
{
	return m_bDontMoveButton;
}
*/
	
};



class ButtonTB :public textBox
{
	
//bool m_bDontMoveButton;
//bool m_bactive;
	//int m_ibuttonheight;
	//int m_ibuttonwidth;
	int m_ibuttonx;
	int m_ibuttony;

public:
	//SButton(std::string _ButtonFileNameImage, std::string _ButtonNameImageHere,unsigned int _Buttonx,unsigned int _Buttony,int _Buttonz,bool _SButtonactive=true):imageBMP( _ButtonFileNameImage):Sprockets(  _ButtonNameImageHere,Type_Button ,_Buttonx ,_Buttony,_Buttonz )
	//{
	//	m_bactive=_SButtonactive;
	//}

	ButtonTB(std::string _ButtonName,int _Buttonx,int _Buttony,int _Buttonz,std::string _ButtonText ,bool _SButtonactive=true,unsigned int _ButtonTB_height=30,unsigned int _ButtonTB_width=100,std::string _ButtonTB_Font=True_Type_Font_Defalut,int _ButtonTB_FontPoint=18,unsigned int _ButtonTB_red=255,unsigned int _ButtonTB_blue=255 ,unsigned int _ButtonTB_green=255,std::string _ButtonFontPath=True_Type_Font_Location):textBox(Type_ButtonTB,_ButtonName, _Buttonx,_Buttony,_Buttonz,_ButtonText, _ButtonTB_height, _ButtonTB_width,_ButtonTB_Font,_ButtonTB_FontPoint,_ButtonTB_red, _ButtonTB_blue ,_ButtonTB_green,_ButtonFontPath)

{
	m_bactive=_SButtonactive;
//	 m_ibuttonheight=-1;
	//m_ibuttonwidth=-1;
	m_ibuttonx= -1;
	m_ibuttony=-1;
	m_bDontMoveButton=false;
	

}


ButtonTB()
{
	
}
~ButtonTB(){
	
}
/*
virtual Sprockets * WasClicked(int _mouselocationX, int _mouselocationY)
{
	SDL_Rect *clipbox =GetRect();
	if(m_bactive)
	{
		
	if( m_ibuttonheight ==-1 &&  m_ibuttonwidth==-1)
	{
		
		if( ( _mouselocationX > clipbox->x ) && ( _mouselocationX < clipbox->x + clipbox->w ) && (_mouselocationY > clipbox->y ) && (_mouselocationY < clipbox->y + clipbox->h ) )
		{
			return this;
		}
		
		
	}
	
	else
	{
		
		
		if( ( _mouselocationX >  m_ibuttonx ) && ( _mouselocationX <  m_ibuttonx +  m_ibuttonwidth ) && (_mouselocationY >  m_ibuttony ) && (_mouselocationY <  m_ibuttony + m_ibuttonheight ) )
		{
			return this;
		}
		
		
	}
	
	}
	
	
	return NULL;
	
}*/
/*
void Disable()
{	
	m_bactive=false;
}
void Enable()
{
	m_bactive=true;
}
bool GetActive()
{
	return m_bactive;
}


void SetDontMoveOnClick(bool _flag)
{
	m_bDontMoveButton=_flag;
}

bool GetDontMoveOnClick()
{
	return m_bDontMoveButton;
}
*/

	
};

















//==============For other Class funtions see above=====================



/*
class Sprockets
public memeber funtions
	 Sprockets(std::string _NameMain,int _TypeMain)
	 Sprockets(std::string _NameMain,int _TypeMain,int _x,int _y,int _z)
	 Sprockets()
	

	void SetLocation( int _x,unsigned int _y)
	unsigned int GetLocationX()
	unsigned int GetLocationY()
	std::string GetName()
	int GetLocationZ ()
	void SetheightWidth(unsigned int _height,unsigned int _Width)
	unsigned int Getheight()
	unsigned int GetWidth ()
	bool SetDraw(bool _Draw)//set to false for the sprocket not to be drawn on screen (setting it to false will not remove it from the renderable list) or true for it to be drawn on screen 
	bool GetDraw()
	int GetType()
    bool SetScalingFactor(double _ScalingX,double _ScalingY)
    bool SetScalingFactorX(double _ScalingX)
    bool SetScalingFactorY(double _ScalingY)
	double  GetScalingFactorX()
	double  GetScalingFactorY()
	bool SetRotation(double _Degrees )
    double GetRotation()
	bool SetAntiAliased(bool _AntiAliased )
	bool GetAntiAliased()      
    int GetCurrentVectorPostion()//returns the current index of where the sprocket is in the rendable list



class textBox : public Sprockets
public member funtions
textBox(std::string _NameTextBox,unsigned int _x,unsigned int _y,int _z,std::string _TextBoxMessage=" ",unsigned int _height=30,unsigned int _width=100,std::string _Font=True_Type_Font_Defalut,int _FontPoint=18,unsigned int _red=255,unsigned int _blue=255 ,unsigned int _green=255):Sprockets(_NameTextBox,Type_TextBox)
	
	~textBox()
	void SetText(std::string _text)//set the text that will be displayed in the textBox
	std::string GetText ()//get the text that the textBox is diplaying
	std::string GetFont()//get the font of the textBox
	void SetFont(std::string _FontArg)//set the font of the textBox
	int GetFontPoint()//Gets the size of the font
	void SetFontPoint(int _FontPointArg)//gets the size of the font
	SDL_Color GetTextColor()
	bool SetTextColor(unsigned int _red,unsigned int _blue ,unsigned int _green)//sets the color of the text in the textBox


class image: public Sprockets
public member funtions
	image (std::string _FileNameImage, std::string _NameImageHere,unsigned int _x,unsigned int _y,int _z,bool _Transparency=false):Sprockets( _NameImageHere,Type_Image ,_x, _y, _z)
  ~image()
	  std::string GetFileName()//get the name of the file assonated with the image
	void SetClippingRect(int _x,int _y,int _w,int _h)//Sets the clipping rectangle for the image
	bool GetClip() //gets if the drawing function uses the clipping rectangle
	int GetClippingX()
	int GetClippingY()
	int GetClippingW()
	int GetClippingH()
	void SetTransparency (bool _Transparency) //if true is passed then any pixels with the same color as the top left pixle will not be drawn 
	bool GetTransparency()//returns ture if the transparency flag is set flase otherwise
	

class Animation : public image 
public member functions
		Animation(std::string _FileName,std::string _AnimationName,int _fps,unsigned int _x,unsigned int _y, int _z,int _AnimStripFrames,int _StartFrame=0,int _Loop=1,bool _Transparency=false,bool _StartNow=true):image( _FileName, _AnimationName, _x, _y, _z,Type_Animation,_Transparency)
		void  JumpToFrame(int _Frame) //jumps the frame to _Frame
		void UpdateTime()//updates the current time for the animation and check to see if the frame needs to be incrmated
		int GetFPS()//returns the current frames per seconds for the animation
		void SetFPS(int _fps,unsigned int _time)//set the frames per seconds for the animation
		void SetClipingBoxForFrame() //sets cliping box for the current frame
		void StopAnimation()//Stops Animation
		void PlayAnimation()//Plays Animation and resets the number of times the animation has played
		void SetLoop(int _Loop)//sets the number of times to loop the animation
		int GetLoop()//returns the number of times the animation should loop
		int GetCurrentFrame()//get the current frame that is being displayed
		bool GetReversPlay()//returns true if the animation should play backwards false otherwise
		void SetReversPlay(bool _BackWards)//set to true to play animation backwards false otherwise
		int GetTotalNumberOfFrames()//gets the total number of frames in the animation. Frame one is always zero
		int GetNumberOfTimesPlayed()//gets the number if times the animation has played
		



class Button :image
public member funtions
	Button(std::string _ButtonFileNameImage, std::string _ButtonName,unsigned int _Buttonx,unsigned int _Buttony,int _Buttonz,bool _Transparency=false,bool _SButtonactive=true):image( _ButtonFileNameImage, _ButtonName, _Buttonx, _Buttony, _Buttonz,Type_Button,_Transparency)
    Button(std::string _ButtonName,unsigned int _Buttonx,unsigned int _Buttony,int _Buttonz,int m_iButtonheight,int m_iButtonwidth,bool _Transparency=false,bool _SButtonactive=true):image(" ", _ButtonName, _Buttonx, _Buttony, _Buttonz,Type_Button,_Transparency)
	Button()
	~Button()
	virtual Button * WasClicked(int _mouselocationX, int _mouselocationY)//determans if _mouselocationX and _mouselocationY are inclosed in the button (it the button was clicked by the user)
	void Disable()//disables the clickablity of the button
	void Enable()//enables the clickablity of the button
	bool GetActive()//returns where the button is enabled or disabled
	void DisableAndTurnOffDraw()//disables the button and hides the image
	void EnableAndTurnOnDraw()//enables the button and shows the image

class ButtonTB :textBox
public member funtions
    ButtonTB(std::string _ButtonName,unsigned int _Buttonx,unsigned int _Buttony,int _Buttonz,std::string _ButtonText ,bool _SButtonactive=true,unsigned int _ButtonTB_height=30,unsigned int _ButtonTB_width=100,std::string _ButtonTB_Font=True_Type_Font_Defalut,int _ButtonTB_FontPoint=18,unsigned int _ButtonTB_red=255,unsigned int _ButtonTB_blue=255 ,unsigned int _ButtonTB_green=255):textBox(Type_ButtonTB,_ButtonName, _Buttonx,_Buttony,_Buttonz,_ButtonText, _ButtonTB_height, _ButtonTB_width,_ButtonTB_Font,_ButtonTB_FontPoint,_ButtonTB_red, _ButtonTB_blue ,_ButtonTB_green)
  	Button()
	~Button()
	virtual ButtonTB * WasClicked(int _mouselocationX, int _mouselocationY)//determans if _mouselocationX and _mouselocationY are inclosed in the button (it the button was clicked by the user)
	void Disable()//disables the clickablity of the button
	void Enable()//enables the clickablity of the button
	bool GetActive()//returns where the button is enabled or disabled
	
 class sound 
 public member funtions
 int GetVolume()
 bool SetVolume(int _Volume)
 bool SetChannel(int _ChannelToSetTo)
 bool SetNumberOfTimesToLoop(int _NumberOfTimesToLoop)
 int GetChannel()
 int GetNumberOfTimesToLoop()
 std::string GetName()
 */




class EpeeEngine
{


public:
	EpeeEngine();
	EpeeEngine(std::vector<FileLookUp> filetable);
	~EpeeEngine();


	bool EventProcessing(SDL_Event *_event); //event processing for the graphics engin currently handles movement of buttons when pressed
	bool SetUp(unsigned int Screen_Width,unsigned int Screen_Heigth,bool FullSreenMod=false,std::string _WindowName="Your App Name Here",bool _Resize=false,int _fps=60,unsigned int _BitDepthOfScreen=16,bool Anyformat=false);
	bool SetUp(std::vector<FileLookUp> filetable,unsigned int Screen_Width,unsigned int Screen_Heigth,bool FullSreenMode=false,std::string _WindowName="Your App Name Here",bool _Resize=false,int _fps=60,unsigned int _BitDepthOfScreen=16,bool Anyformat=false);
	bool RenderSeen(bool _UpdateScreenNow=false); //call this to proccess the render list and pass true to this funtion for it to call updatescreen 
	bool UpdateScreen();// draws the proccesed render list to the screen
	
	image * CreateImageFromList(std::string _symbol,std::string _ImageName,int _x,int _y,int _z);//creates a new image from a filelist and adds it to renable list
    bool RemoveIteamFromRendableList(std::string _card); //removes the card from the rendable list
	
	bool SetNumberOfMixingChannels(int _NumberOfChannels);//Set up funtion for the sound list this need to be at lest on for sounds to work. This does not have any barring to the background music
	Sound *  FindSound(std::string _name);//returns a pointer to a sound object from the sound list
	Sound * CreateSound(std::string _GroupName,std::string _FileName,int _Channel=0,int _NumberOfTimesToLoop=0,int _Volume=MIX_MAX_VOLUME);//creates a new sound and adds it to the sound list
	bool DestroySound(std::string _name);//deletes the a sound from the sound list
	bool PlaySoundNow(Sound * _pSound);//plays a sound pointed to by _pSound
	bool StopSoundNow(int _Channel);
	bool SetAndPlayBackGroundMusic(std::string _NameOfAudio,int _NumberOfTimesToLoop,int _Volume=MIX_MAX_VOLUME);//creates and plays background music. THIS IS NOT ADDED TO THE SOUND LIST. you can only have one music file loaded and playing at a time
	bool StopBackGroundMusic();//stops the background music
	
	
	bool LoadConfigurationFile(std::string _FileName);


		
	float GetTimeSinceSetup(); //gets the number of milliseconds since setup was called
	void SleepDelay(Uint32 _millisecounds);	//sleeps for _millisecounds does not use up clock cycles
	textBox * CreateTextBox(std::string _Name,int _x,int _y,int _z,std::string _TextBoxMessage=" ",std::string _AddtoCurrentRenderlist="Current",unsigned int _height=-1,unsigned int _width=-1,std::string _Font=True_Type_Font_Defalut,int _FontPoint=18,unsigned int _red=255,unsigned int _blue=255 ,unsigned int _green=255,std::string _FontPath = True_Type_Font_Location);//creates a textbox and adds it to the rendable list
    image * CreateImage(std::string _fileName ,std::string _Name,int _x,int _y,int _z,std::string  _AddtoCurrentRenderlist="Current",bool _Transparency=false);//creates image and adds it to the rendable list
	Animation * CreateAnimation(std::string _fileName ,std::string _Name,int _x,int _y,int _z,int _NumberOfFrames,int _fps,int _StartFrame=0,int _Loop=1,int _NumberOfRowsOfFrames=1,bool _Transparency=false,bool _StartNow=true,std::string  _AddtoCurrentRenderlist="Current");//Creates an animation and adds it to the renderable list
	ButtonTB * CreateButtonTB(std::string _ButtonName,int _Buttonx,int _Buttony,int _Buttonz,std::string _ButtonText ,bool _SButtonactive=true,std::string  _AddtoCurrentRenderlist="Current",unsigned int _ButtonTB_height=30,unsigned int _ButtonTB_width=100,std::string _ButtonTB_Font=True_Type_Font_Defalut,int _ButtonTB_FontPoint=18,unsigned int _ButtonTB_red=255,unsigned int _ButtonTB_blue=255 ,unsigned int _ButtonTB_green=255,std::string _ButtonFontPath=True_Type_Font_Location);//creates a textbox that is a button on the screen and adds the button to the rendable list
	Button * CreateButton(std::string _localfileName ,std::string _localName,int _localx,int _localy,int _localz,bool _Transparency=false,bool _localactive=true,std::string  _AddtoCurrentRenderlist="Current");//creates a button that is attached to an image. the button is added to the rendable list
    Button * CreateButton(std::string _localName,int _localx,int _localy,int _localz,int _height,int _width,bool _Transparency=false,bool _localactive=true,std::string  _AddtoCurrentRenderlist="Current");//creates a button that is not attached to an image an is invsable to the user. this button is added to the rendable list but is not draw on the screen
   Sprockets * WasAButtonClicked(int _x, int _y);//returns the button that contanes the x and y values.
	
	textBox * FindTextBox(std::string _name);//returns a pointer to a textBox _name from the rendable list
	Button * FindButton(std::string _name);//returns a pointer to a Button _name from the rendable list
	ButtonTB * FindButtonTB(std::string _name);////returns a pointer to a ButtonTB _name from the rendable list
    image *FindImage(std::string _name);//returns a pointer to a Image _name from the rendable list
		Animation * FindAnimation(std::string _name);//returns a pointer to an Animation _name from the rendable list
		
		image* CloneImage(image * _imageToClone,std::string _nameOfImage,std::string _RenderList="Current",int _x=-1,int _y=-1,int _z=-1);

	textBox* CloneTextBox(textBox * _textBoxToClone,std::string _nameOfImage,std::string _RenderList="Current",int _x=-1,int _y=-1,int _z=-1 );
	//***********NOTE IMAGES,ANIMATIONS TEXTBOXES,AND BUTTONS ARE ALL SPROCKETS***********************
	bool DestroySprocket(std::string _name); // removes a sprocket from the rendable list
		Sprockets * FindSprockets(std::string _name,std::string _renderlist="Current"); //returns a pointer to a sprocket from the rendable list
	bool EpeeEngine::ChangeSprocketZ(Sprockets * _SprocketToChange,int _newZ,RenderList * _list=NULL);//changes the depth of a sprocket
		

	int GetFps(); // returns the current frames to a secound of the render engine
	bool SetFps(int _fps);//sets the frames to a secound of the render engine
	
	bool IsFoucsOnTextBox()
	{
		if (m_pCurrentEditedTextBox==NULL) {
			return false;
		}
		else
		{
			return true;
		}
		return false;
		
	}
std::string GetCurrentRenderList();
RenderList * GetCurrentRenderListptr();
	bool SetCurrentRentderList(std::string _ListToChangeTo);
	bool InsertRenderList(RenderList * _newRenderList);
	
bool DestroyRenderList(std::string _name);
bool RemoveIteamFromRendableList(std::string _card,std::string _renderList);
RenderList*  FindRenderList(std::string _name);
RenderList * CreateRenderList(std::string _name);
unsigned int GetTotalRenderList();
bool ValideVersionNumberOfCppWithHeader();
double GetVersionNumberH();
double GetVersionNumberCpp();
void TransferSprocketToNewRenderList(RenderList * _sorceRenderList,RenderList * _destinationRenderList,Sprockets * _sprocketToTransfer);

//template <typename datatype> datatype StringToNumericData(std::string _stringtoconvert,datatype temp);//temp is the data type that you want back
template <typename datatype> datatype StringToNumericData(std::string _stringtoconvert,datatype temp)
	{datatype tempint=0;

			std::istringstream tempstream(_stringtoconvert);
			if (!(tempstream>>tempint)) {
				std::string tempstring ="Could not convert"+_stringtoconvert+"to the specified data type";
				 EpeeEngineError temperror(tempstring,TEXTBOX_CONVERION_ERROR,this);
				 this->SetLastError(temperror);
				return 0;
			}
			this->ClearError();
			return tempint;
	}



//template <typename datatype> std::string  StringFromNumericData(datatype _value);
template <typename datatype> std::string StringFromNumericData(datatype _value)
	{datatype tempint=_value;
			std::ostringstream tempstream;
			if (!(tempstream<<_value)) {
				
				std::string tempstring ="Could not convert numeric data to string";
				 EpeeEngineError temperror(tempstring,TEXTBOX_CONVERION_ERROR,this);
				this->SetLastError(temperror);
				return "NULL";
				
			}
			this->ClearError();
			return tempstream.str(); 
			
			
	}

		
	//std::string GetLastError() {return m_sCurrentError;}//Returns the last error from the last funtion called
	 EpeeEngineError GetLastError() {return m_cLastError;}//Returns the last error from the last funtion called
	
	unsigned int GetTotalSprockesCreated();//returns that total number of sprockets created
	unsigned int GetTotalSoundsCreated();//returns the total number of sounds created
	void WriteRenderListToFile();//Writes the contents of the render list out to the cout file. Only works in debug right now
	void WriteSoundListToFile();//Writes the contents of the sound list out to the cout file. Only works in debug right now
	void TurnOnFPS();//Turns on the Frames Per Second in the upper left hand corner
	void TurnOffFPS();//Turns Off the Frames Per Second in the upper left hand corner
	void EpeeEngine::ToggleFullScreen(bool _FullScreen);//Toggles the window from fullscreen to window and back true for fullscreen false for windowed
    void ChangedResolution(int _Width, int _height,bool _useCurrentFlags=true,bool _FullScreen=false,bool _Resize=false,bool _AnyFormat=false);//Changes the current window resolution
	bool GetEvent(SDL_Event * _event); //Removes and polulates _event with the next event in the event que. Returns false if the is no events in the que returns true otherwise


	unsigned int GetCurrentScreenHeight();
	unsigned int GetCurrentScreenWidth();
private:
	void ClearError();
	void SetLastError(EpeeEngineError _error);
	void LoadAnimationFromFile(TiXmlElement *element);
	void LoadButtonTBFromFile(TiXmlElement *element);
	void  LoadButtonFromFile(TiXmlElement *element);
	void LoadTextBoxFromFile(TiXmlElement *element);
	void LoadImageFromFile(TiXmlElement *element);	
	bool WriteText(std::string TextToWrite,int x,int y,int point=12,std::string font="arial.ttf",int text_box_height=30,int text_box_width=200);
	bool WriteText(textBox* _TextBox);
	bool InsertIntoSprocketList(Sprockets * _newSprocket,RenderList * _List=NULL);
	bool DrawImage(image* _ImageToDraw);
	bool ScaleImageDraw(image* _ImageToDraw);
	void fpsDelay();
	bool UpdateVectorlocateion();
	bool PlaySoundNow(std::string _NameOfAudio,int _NumberOfTimesToLoop,int _Channel=-1);
	std::vector <FileLookUp> m_cfiletable;
	 Uint32 m_u32VideoFlags;
	//std::vector  <textBox*> m_vTextBoxList;
	//std::vector <Button> m_vButtonList;
//	std::vector  <Sprockets*> m_vSprocketsList;
	std::vector <RenderList*> m_vRenderList;
	std::vector <Sound*> m_vSounds;
	SDL_Surface *m_pscreen;
	EpeeEngineError m_cLastError;
	textBox * m_pCurrentEditedTextBox;
	 unsigned int m_iScreen_Heigth;
	unsigned int  m_iScreen_Width;
//	TTF_Font *m_pfont1;
	RenderList * m_uiCurrentRenderList;
	bool m_bFullScreen;
	bool m_bResizeAble;
	int m_ifps;
	FPSmanager m_cfpsManager;
	Mix_Music *m_pBackGroundMusic;
	std::string m_sCurrentError;
	Mix_Chunk * m_pSoundOne; 
	int m_iframe;
	int m_ifpstime;
	textBox * FrameRate;
	float m_fCurrentFrameRate;
	//Sprockets  * m_pLastSprocketFound;
	RenderList * m_LastRenderListFound;
	Sprockets * m_pDownedButton;
	unsigned int m_uiTotalRenderListsCreated;
		unsigned int m_uiTotalSoundsCreated;
		bool SetKeyColor(SDL_Surface * _SurfaceToKey);
		int m_bHardWareAccelration;//0 is software 1 is openGl soon 2 will be directX 
};

#endif
