module br.ship;

private import SDL_mixer;
private import opengl;

private import util.parts;
private import util.key;
private import util.mouse;


private import util.beam;
private import util.particle;
private import util.animationImpl;
private import util.collision;
private import br.shapeImpl;
private import br.screen;
private import br.mainloop;
private import br.gamemanager;
private import br.shot;
private import br.append;
private import br.cursor;
private import br.sound;
private import br.particleImpl;




public class Ship:Parts{
	
	//import br.mainloop;
	public:
	int shield;
	bool miss;
	int starnum;
	static const int RIGHTX = 100;
	static const int LEFTX = -100;
	static const int POSY = -180;
	
	private{
//		static const Vector3 VEC_RIGHT = new Vector3(200.0 ,0 ,-800);
//		static const Vector3 VEC_LEFT = new Vector3(-200.0 ,0 ,-800);
		
		Key key;
		Mouse mouse;
		int pressing;
		int reload;
		double gradient;
		int cPressed;
		Vector3 target;
		bool right;
		int invincible;
//		Vector3[100] rpos0;
//		Matrix[100] rpose0;
	}
	public this(){}
	public this(Key key,Mouse mouse ,float x,float y){
		collisionManager.add(this ,collisionManager.kind.SHIP ,1);
		collisionManager.add(this ,collisionManager.kind.STAR ,1);
		collisionManager.add(this ,CollisionManager.kind.LASER ,2);
		this.key = key;
		this.mouse = mouse;
		shape = Head.getShape();
		start(x ,y);
		shipManager.add(this);

		setColor(R ,G ,B ,alpha,true);
		
	}
	
	
	public void start(float x ,float y){
		pos = new Vector3(RIGHTX ,POSY ,-800);
		rpos = cast(Vector3)pos.clone();
		
		target = new Vector3(RIGHTX ,POSY ,-800);//cast(Vector3)VEC_RIGHT.clone();
		right = true;
		
		Matrix po = new Matrix(); 
		setPoseBase(po);
		
		poseZ = rposeZ = 90.0;
		linkZ = rlinkZ = 0.0;
		
		drawing =  WIRE | POLYGON;
		gradient = 0.0;
		size =  40;
		collisionRange = 15;
		R = 0.70;G =1.0;B = 0.8;alpha = 1.0;
		
		
		pressing = 0;
		reload = 0;
		cPressed = 0;
		invincible=0;
		
		miss = false;
		starnum = 0;
		
		Parts p = new Warp(shape ,size ,1.0f ,1.0f ,1.0f ,alpha ,new Vector3(LEFTX ,POSY ,-800.0f));
		shipManager.add(p);
		p = new Warp(shape ,size ,1.0f ,1.0f ,1.0f ,alpha ,new Vector3(RIGHTX ,POSY ,-800.0f));
		shipManager.add(p);
		
		shield = 3;
//		addChild(p, "left", 0 ,DISRELATION);
		
	    //MyShip.getShape();//new SH_Pole(a ,b ,4);
		/*
		Parts p = new Tail();shipManager.add(p);
		addChild(p, "tail1", 40 ,ENGAGED);
		p = new Tail();shipManager.add(p);
		childHash["tail1"].addChild(p, "tail2", 40 ,ENGAGED);
		p = new Tail();shipManager.add(p);
		childHash["tail2"].addChild(p, "tail3", 40 ,ENGAGED);
		p = new Tail();shipManager.add(p);
		childHash["tail3"].addChild(p, "tail4", 40 ,ENGAGED);
		p = new Tail();shipManager.add(p);
		childHash["tail4"].addChild(p, "tail5", 40 ,ENGAGED);
		
		childHash["tail1"].addAnimation(new Swing(120 ,LINKZ ,1 ,0.5 ,0 ,true) ,"swing");
		childHash["tail1"].addAnimation(new Rotate(120 ,LINKX ,-0.5 ,0.0  ,true) ,"rotate");
		*/
	}
	public void setBackColor(bool sword){
		/*
		if(sword)screen.setClearColor(0.2 ,0.14 ,0.1 ,1.0);
		else screen.setClearColor(0.1 ,0.14 ,0.2 ,1.0);
		/*
		if(sword)screen.setClearColor(0.09 ,0.06 ,0.04 ,1.0);
		else screen.setClearColor(0.04 ,0.06 ,0.09 ,1.0);
		*/
	}
	public void addChild(inout Parts child,char[] name, double dist = 0.1, int childKind = NORMAL, Matrix link = null ,Matrix pose = null){
		super.addChild(child ,name ,dist ,childKind ,link ,pose);
		
	}
	public void move(){
		super.move();
		
		double speed;
		int button = key.getButtonState();
		
		
		Vector3 prepos = cast(Vector3)pos.clone();
		
		if(pos.dist(target) > 10)pos += (target - pos)/4.0f;
		else pos = cast(Vector3)target.clone();
		
		if(button & Key.Button.A){
			if(!pressing){
				if(right){
					right = false;
					target = new Vector3(LEFTX ,POSY ,-800);//cast(Vector3)VEC_LEFT.clone();
				}else{
					right = true;
					target =new Vector3(RIGHTX ,POSY ,-800);// cast(Vector3)VEC_RIGHT.clone();
				}
			}
			pressing=1;
		}else pressing = 0;
		
		
		
		speed = 5.0;
		int dir = key.getDirState();
		int aim = 5;
		//Vector aim = new Vector(0,0);
		
		if(dir & Key.Dir.RIGHT){
//			if(!(button & key.Button.A))
			pos.x += speed;
			aim -= 1;
			//aim.x += 1;
		}
		if(dir & Key.Dir.LEFT){
//			if(!(button & key.Button.A))
			pos.x -= speed;
			aim += 1;
			//aim.x -= 1;
		}
		if(dir & Key.Dir.DOWN){

			pos.y -= speed;
			aim -= 3;
			//aim.y -= 1;
		}else if(dir & Key.Dir.UP){

			pos.y += speed;
			aim += 3;
		
		}else{
			
		}
		
		double degAim;
		bool moved = true;
		switch(aim){
			case 1:degAim=135.0;		break;
				case 2:degAim=90.0;		break;
				case 3:degAim=45.0;		break;
				case 4:degAim=180.0;	break;
				case 6:degAim=0.0;		break;
				case 7:degAim=-135.0;	break;
				case 8:degAim=-90.0;	break;
				case 9:degAim=-45.0;	break;
				case 5:
				default:
				moved = false;
				break;
		}
		
		
		if(pos.y < screen.GAME_DOWN + size)pos.y = screen.GAME_DOWN + size;
		if(screen.GAME_UP - size < pos.y)pos.y = screen.GAME_UP - size;
		if(screen.GAME_RIGHT - size < pos.x)pos.x = screen.GAME_RIGHT - size;
		if(pos.x < screen.GAME_LEFT + size)pos.x = screen.GAME_LEFT + size;
		
		float dx = pos.x - prepos.x;
		
		if(1.0 < dx)poseX += dx /10.0f;
		else if(dx < -1.0)poseX -= dx /10.0f;
		else{
			if(poseX < -3.0)poseX += 3.0f;
			else if(3.0 < poseX)poseX -= 3.0f;
			else poseX = 0.0f;
		}
		
		poseX = fmax(-30.0f ,fmin(30.0f ,poseX));
		
		shot();
//		poseZ += 0.2;
//		poseX += 0.1;
		
		//rotateAll(matRotateY(1 ) );
		
		//glLineWidth(1);
		
		
		//super.draw();
		invincible --;
	}
	public void shot(){
		MouseState ms = mouse.getState();
		if((cnt % 1 == 0) &&
		((ms.button & MouseState.Button.LEFT) ||
		(ms.button & MouseState.Button.RIGHT))){
//			float ddeg;
//			float d = (cursor.rpos-rpos).size();
			/*
			if(d < 200)ddeg = rand.nextFloat((cast(Cursor)cursor).ddeg);
			else if(d < 350)ddeg = rand.nextFloat((cast(Cursor)cursor).ddeg);
			else ddeg = 0.0f;
			*/
			float ddeg = rand.nextFloat((cast(Cursor)cursor).ddeg) - (cast(Cursor)cursor).ddeg/2.0;
			Vector3 vel = vec3translate(vec3Normalize(cursor.rpos-rpos) ,matRotateZ(ddeg));
			double deg = cast(double)((cast(int)cnt * 5) % 90);// * 25;
			new Shot(rpos+vel * 70.0f ,vel * 30.0f ,deg);//deg);
		}
	}
	public void draw(){
		if((invincible > 0) && (cnt % 20 < 10))drawing = WIRE;
		else drawing = WIRE | POLYGON;
		super.draw();
	}
/*
	public void drawImpl(){
		for(int i=0;i<rpos0.length-1;i++){
			drawLocus(shape ,rpos0[i] ,rpos0[i+1] ,rpose0[i] ,rpose0[i+1] ,R*0.5 ,G ,B ,1.0);
		}
		drawLocus(shape ,rpos ,rpos0[0] ,rpose ,rpose0[0] ,R*0.5 ,G ,B ,1.0);
		
		for(int i=rpos0.length-2;0<=i;i--){
			rpos0[i+1] = cast(Vector3)rpos0[i].clone();
			rpose0[i+1] = cast(Matrix)rpose0[i].clone();
		}
		rpos0[0] = cast(Vector3)rpos.clone();
		rpose0[0] = cast(Matrix)rpose.clone();
		
	}
*/
	public void reportCollision(int kind ,Parts p){
		switch(kind){
			case CollisionManager.kind.STAR:
//			if(R <= 0.9f)R += 0.1f;
//			else R = 1.0f;
			starnum ++;
			rankpar = rankpar + 1;
			break;
			case CollisionManager.kind.SHIP:
			case CollisionManager.kind.LASER:
			if(invincible<=0){
	//			if(0.1f <= R)R -= 0.1f;
	//			else R = 1.0f;
//				starnum = 0;
				makeParticle(shape, size ,WIRE ,rpos ,new Vector3() ,rpose ,R ,G ,B ,wR,wG,wB,alpha ,10);
//				rankdown();
				Sound_PlaySe(se_kind.MISS);
				shield --;
				invincible = 60;
			}
			break;
			default:break;
		}
//		destroy();
//		
		
		
	}
	public void destroy(){
		super.destroy();
		miss = true;
		makeParticle(shape, size ,WIRE | POLYGON ,rpos ,new Vector3() ,rpose ,R ,G ,B ,wR,wG,wB,alpha);
//		makeSimpleParticle(100, size, WIRE | POLYGON ,rpos, R ,G ,B ,wR,wG,wB,alpha);
		if(shield == 0){
			makeSimpleParticle(100, size, WIRE | POLYGON ,rpos, R ,G ,B ,wR,wG,wB,alpha);
		}
//		new SmallBlast(rpos.x ,rpos.y ,1 ,1 ,1000.0 ,60 ,R ,G ,B ,0.4);
//		new SmallBlast(rpos.x ,rpos.y ,1 ,1 ,200.0 ,60 ,R ,G ,B ,0.2);
		
	}

}

public class Tail:Parts{
	
	public this(){
		drawing =  WIRE | POLYGON;
		size =  20;//20;
		collisionRange = 10;
		R = 1.0;G =0.88;B = 0.7;alpha = 1.5;
		
		
		
	    shape = Octahedron.getShape();//new SH_Pole(a ,b ,4);
	}
}

public class Warp:Parts{
	
	public this(Shape shape ,double size ,double R = 1.0,double G = 1.0 ,double B = 1.0,double alpha = 1.0 ,Vector3 pos=new Vector3()){
		drawing =  WIRE;
		this.size =  size;//20;
//		collisionRange = 10;
		this.R = R;this.G =G;this.B = B;this.alpha = alpha;
		
		this.pos = cast(Vector3)pos.clone();
		
	    this.shape = cast(Shape)shape.clone();//new SH_Pole(a ,b ,4);
		
		poseZ = rposeZ = 90.0;
	}
}