module es.gamemanager;

private import opengl;
private import openglu;
private import SDL;
private import SDL_mixer;
private import std.string;
private import std.math;
private import es.basis;
private import es.screen;
private import es.sound;
private import es.rand;
private import es.mouse;

private import es.field;
private import es.ship;
private import es.enemy;
private import es.shot;

private import es.pointer;
private import es.stage;
private import es.shape;
///
private import es.moving;
///




public Rand rand;
public Screen screen;

public Field field;
public Stage stage;
public Ship ship;
public Pointer pointer;
public Camera cam;

public EnemyPool ep;

public Mouse mouse;

public ShotPool sp;

private GameManager gameManager;
private GameState inGameState;
private GameState inTitleState;


public const int TEMPO = 15;

public real mousex;
public real mousey;

public bool mouseReleased;
public bool mousePressed;

public bool noPlay;

public bool getMouseReleased(){
  bool mr =mouseReleased;
  mouseReleased = false;
  return mr;
}

public class GameManager{
	
	public:
	const int SCREEN_WIDTH = 480;
	const int SCREEN_HEIGHT = 480;
	const int SCREEN_BPP = 0;

	static int count;
	private:
	GameState state;
	GameState nextState;
	
	
	public this(Mouse mo){
		mouse = mo;
		gameManager = this;
	}
	public void start(){
		rand = new Rand();
		screen = new Screen();
		
		field = new Field();
		pointer = new Pointer();
		ship = new Ship();
		ep = new EnemyPool(512);
		sp = new ShotPool(256);
	
		mouse.start(screen);
	
		
		stage = new Stage();
		cam = new Camera();

		
		count = 0;

		Sound_init();

		inGameState = new InGameState();
		inTitleState = new InTitleState();
		state = inTitleState;
		state.start();
		
		reset();
		nextState = null;
		
		noPlay = true;
		
//		Sound_PlayMusic(music_kind.MUSIC1);
	}
	public void move(){
		MouseState ms = mouse.getState();
		if(
		(ms.button & MouseState.Button.LEFT) ||
		(ms.button & MouseState.Button.RIGHT)){
			mousePressed = true;
		}else{
			mousePressed = false;
			mouseReleased = true;
		}
		mousex = ms.x;
		mousey = ms.y;
		
		
		state.move();
		if(nextState !is null){
			state = nextState;
			
			state.start();
			nextState = null;
		}
		count ++;
		
	}
	public void draw(){
		state.draw();
	}
	public void returnPushed(){
		
		setNextState("titleState");
		
	}
	public void setNextState(char[] name){
		switch(name){
				case "gameState":nextState = inGameState;break;
				case "titleState":nextState = inTitleState;break;
				default:break;
		}
	}
	public void reset(){
		mousex = screen.SCREEN_WIDTH/2.0;
		mousey = screen.SCREEN_HEIGHT/2.0;
	}
	public void clear(){

	}
	public void close(){
		clear();
		Sound_free();
		Mix_CloseAudio();
	}

}

public abstract class GameState{
	protected:

	public void start();
	public void move();
	public void draw();
	public char[] name();
}
public class InGameState:GameState{
	private:

	int count;

	Shape BULLET_SHAPE;
	const char[] _name = "gameState";
	public this(){
	}
	
	public void start(){
		
		ship.start();
	    pointer.start();
	   	 sp.start();
   		 cam.start();
   		 field.start();
	    ep.clear();
		stage.start(1);
		/*
		Moving mov= new Dart(1.0);
		ep.addEnemy(null, THREEWAY, mov,10, 0 ,0 ,0 ,1.00 ,1.0);
		*/
		count = 0;
		
	}
	public void move(){
//		ship.fx ++;
		SDL_ShowCursor(SDL_DISABLE);
		stage.update();
		ep.move();
		sp.move();
		ship.move();
		field.move();
		
		pointer.move();
		
		
		if(ship.shield < 0) gameManager.setNextState("titleState");
		
		
		count ++;

	}
	public void draw(){
		screen.setProjection();
		glPushMatrix();
    	cam.update();
	    cam.setCamera();
		background(0,50,60);
		glPopMatrix();
		
		ship.draw();
		ep.draw();
		sp.draw();
		field.draw();
		
		pointer.draw();
		
	}

	public char[] name(){
		return _name;
	}
}
public class InTitleState:GameState{
	private:

	int count;
	
	bool onStart;
	bool onMusic;

	const char[] _name = "titleState";
	public this(){
	}
	
	public void start(){
		SDL_ShowCursor(SDL_ENABLE);
		
		ship.shield = ship.MAXSHIELD;
 	   pointer.fx = ship.fx;
 	   pointer.fy = ship.fy;
	}
	public void move(){
		if(dist(screen.SCREEN_WIDTH / 2 ,screen.SCREEN_HEIGHT / 2 ,mousex,mousey) < 20 * screen.SCREEN_HEIGHT / 480){
//      cursor(HAND);

     		 if(mousePressed && getMouseReleased()){
     		   gameManager.setNextState("gameState");
        
    		  }
			  onStart = true;
   		 }else{
		 	onStart = false;
		 	 if(dist(screen.SCREEN_WIDTH / 2 + screen.SCREEN_HEIGHT * 2.0 / 5.0 ,screen.SCREEN_HEIGHT * 9.0 / 10.0 ,mousex, mousey) <  20 * screen.SCREEN_HEIGHT / 480){
			
		 
//      cursor(HAND);
    		if(mousePressed && getMouseReleased()){
	  	
        		if(noPlay){
        			  noPlay = false;
        			  Sound_PlayMusic(music_kind.MUSIC1);
	      		  }else{
				  	noPlay = true;
					Sound_HaltMusic();
	      		  }
		    	}
				onMusic = true;
			
	  
    		}else{
				onMusic = false;
	//      cursor(ARROW);
  	 		 }
 	 	  	}
	}
		
	
	public void draw(){
		
		screen.setProjection();
		
		glPushMatrix();
    	cam.update();
	    cam.setCamera();
		background(0,50,60);
		glPopMatrix();
		
	    glPushMatrix();
	    ship.inTitle(onStart);
	    glPopMatrix();
		
		glPushMatrix();
		cam.inTitle();
	    cam.setCamera();
		if(noPlay){
			glColor3d(0.5,0.5,0.5);
	    	fillArc(screen.SCREEN_HEIGHT * 4.08 / 5.0 ,-screen.SCREEN_HEIGHT * 4.08 / 5.0 ,screen.SCREEN_HEIGHT / 12 ,screen.SCREEN_HEIGHT / 12);
		    field.draw();
		}else{
			glColor3d(1.0,1.0,1.0);
	    	fillArc(screen.SCREEN_HEIGHT * 4.08 / 5.0 ,-screen.SCREEN_HEIGHT * 4.08 / 5.0 ,screen.SCREEN_HEIGHT / 12 ,screen.SCREEN_HEIGHT / 12);
		    field.draw();
		}
		if(onMusic){
			if(noPlay){
				glColor3d(1.0,1.0,1.0);
		    	arc(screen.SCREEN_HEIGHT * 4.08 / 5.0 ,-screen.SCREEN_HEIGHT * 4.08 / 5.0 ,screen.SCREEN_HEIGHT / 12 ,screen.SCREEN_HEIGHT / 12);
			}else{
				glColor3d(0.5,0.5,0.5);
		    	arc(screen.SCREEN_HEIGHT * 4.08 / 5.0 ,-screen.SCREEN_HEIGHT * 4.08 / 5.0 ,screen.SCREEN_HEIGHT / 12 ,screen.SCREEN_HEIGHT / 12);
			}
		}
		
	    glPopMatrix();
		    /*
	    stroke(122);
	    if(noPlay)fill(122);
	    else fill(255);
		*/
	    //ellipse(modelX(width / 2 ,height / 2 ,0) ,modelY(width / 2 ,height / 2 ,0) ,80 ,80);
	    //ellipse((width / 2 + height  / 3.0) / 2.0 ,(width * 5.0 / 6.0) / 2.0 ,height / 6 ,height / 6);
	    //translate(height * 5.0 / 6.0 ,height * 5.0 / 6.0  ,0.0);
	    //translate(screenX(height / 2  - 50 ,height / 2  - 50 ,0) ,screenY(height / 2  - 50 ,height / 2  - 50 ,0),screenZ(height / 2  - 50 ,height / 2  - 50 ,0));
	    //ellipse(0 ,0 ,height / 6 ,height / 6);
	/*
	   if(noPlay){
	     if(myChannel.state == Ess.PLAYING)myChannel.stop();
	   }else{
	     if(myChannel.state == Ess.STOPPED)myChannel.resume();
	   }
	   */
	 }
	
	public char[] name(){
			return _name;
	}
}

public void background(real r, real g, real b){
	glColor3d(r/255.0,g/255.0,b/255.0);
	glBegin(GL_QUADS);
	glVertex3d(-screen.SCREEN_WIDTH*2,-screen.SCREEN_HEIGHT*2,0);
	glVertex3d(-screen.SCREEN_WIDTH*2,screen.SCREEN_HEIGHT*2,0);
	glVertex3d(screen.SCREEN_WIDTH*2,screen.SCREEN_HEIGHT*2,0);
	glVertex3d(screen.SCREEN_WIDTH*2,-screen.SCREEN_HEIGHT*2,0);
	glEnd();
}

public class Camera{
  public real eyeX ,eyeY ,eyeZ;

  public this(){
    start();
  }
  public void start(){
    eyeX = 0;
    eyeY = 0;
    eyeZ = (screen.SCREEN_HEIGHT/2.0) / tan(PI*60.0 / 360.0);
  }
  public void inTitle(){
    eyeX = 0;
    eyeY = 0;
    eyeZ = (screen.SCREEN_HEIGHT) / tan(PI*60.0 / 360.0);
 
  }
 
   public void update(){
    eyeX = ship.x * screen.SCREEN_HEIGHT / 480;
    eyeY = ship.y * screen.SCREEN_HEIGHT / 480;
    eyeZ = ship.z + (screen.SCREEN_HEIGHT/2.0) / tan(PI*60.0 / 360.0);
    
//	eyeX += 300.0;
  }
   public void setCamera(){
   	glTranslated(-eyeX ,-eyeY ,-eyeZ);
//    camera(eyeX ,eyeY ,eyeZ ,centerX ,centerY ,centerZ ,upX ,upY ,upZ);
  }
}
  