module br.stage;

private import std.math;
private import SDL_mixer;
private import opengl;
private import br.gamemanager;
private import br.enemy;
private import br.enemyImpl;
private import br.blast;
private import br.sound;
private import util.ring;
private import util.vector;
private import util.ring;
private import util.ascii;
private import br.bomb;

struct enemySet {
	int time;
	char[] name;
	bool made;
	bool target;
	double x,y,z,aim;
	Object[] o;
	bool boss;
}
public abstract class Stage:Caller{
	private:
	
	int cnt;
	int nowLevelCnt;
	int totalCnt;
	int level;
	bool _exists;
	bool _cleared;
	bool boss;
	protected:
	enemySet[][] eSets;
	Enemy[] target;
	int tIdx;
	public:
	static const MAXSTAGE = 8;
	public this(){
		cnt = 0;
		nowLevelCnt = 0;
		totalCnt = 0;
		level = 0;
		_exists = true;
		_cleared = false;
		eSets.length = 0;
		
		nextMusic = -1;
					
		foreach(enemySet[] es;eSets){
			es.length = 0;
		}
		target.length = 1;
		tIdx=0;
		boss = false;
	}
	public void run(){
		char[] name;
		bool made=true;
		if(eSets.length <= level){
			_cleared = true;
			_exists = false;
		}else{
			foreach(inout enemySet es;eSets[level]){
				name = null;
				if(es.made)continue;
				if(es.target)made=false;
				if(count == es.time){
					name =es.name.dup;
	//				es.made = true;
				}
				if(name !is null){
					int span;
					if(es.boss){
						Sound_PlaySe(se_kind.WARNING);
	//					Mix_PlayChannel(-1, chunk_warning, 0);
						new SmallBlast(0 ,0 ,10 ,10 ,200.0 ,210 ,1.0 ,0.4 ,0.4 ,0.35);
						span = 90;
						boss = true;
					}else span = 45;
					EnemyRing er = new EnemyRing(this,&es, es.target ,new Vector3(es.x,es.y,es.z-800) ,es.aim,es.o,es.name,span ,45);
					
	//				er.es.made = true;
					//makeEnemy(es.name ,es.x ,es.y ,es.z ,es.aim);
				}
			}
			if(made){
				bool eTarget = false;
				
				foreach(Enemy t;target){
					if(t !is null && t.exists){
						eTarget = true;
					}
				}
				
				if(!eTarget){
					cnt = -1;
					enemyManager.allDestroy();
					
					bulletManager.allDestroy();
					ringManager.clear();
					
					foreach(inout enemySet[] es;eSets){
						foreach(inout enemySet ess;es){
							ess.made=false;
						}
					}
					target.length = 0;
					target.length = 1;
					tIdx = 0;
					level ++;
					nowLevelCnt = 0;
				}
			}

			runImpl();
			cnt++;
			nowLevelCnt++;
			totalCnt++;
		}
		
	}
	public void draw(){
		drawImpl();
	}
	public bool cleared(){
		return _cleared;
	}
	public void runImpl();
	
	public void drawImpl(){}
	public int count(){
		return cnt;
	}
	public bool exists(){
		return _exists;
	}
	public void reportRing(Ring ring){
		EnemyRing er =cast(EnemyRing)ring;
		Enemy e= makeEnemy(er.name ,er.x ,er.y ,er.z ,er.aim,er.o);
		er.es.made = true;
		if(er.target)addTarget(e);
	}
	protected void add(int level ,int time,char[] name,bool target,double x,double y,double z,double aim,Object[] o=null ,bool boss = false){
		if(eSets.length <= level)eSets.length=level+1;
		eSets[level].length =eSets[level].length + 1;
		eSets[level][eSets[level].length-1].made = false;
		eSets[level][eSets[level].length-1].time = time;
		eSets[level][eSets[level].length-1].name = name.dup;
		eSets[level][eSets[level].length-1].target = target;
		eSets[level][eSets[level].length-1].x=x;
		eSets[level][eSets[level].length-1].y=y;
		eSets[level][eSets[level].length-1].z=z;
		eSets[level][eSets[level].length-1].aim=aim;
		eSets[level][eSets[level].length-1].boss=boss;
	}
	protected void addTarget(Enemy enemy){
		enemy.setTarget();
		target[tIdx] = enemy;
		tIdx ++;
		if(tIdx < target.length)return;
		else{
			target.length = target.length * 2;
		}
	}
	public int music();
	public void goback(){
		cnt = -1;
		nowLevelCnt = -1;
		nextMusic = -1;
		
		enemyManager.clear();
		bulletManager.clear();
		ringManager.clear();
		foreach(inout enemySet[] es;eSets){
			foreach(inout enemySet ess;es){
				ess.made=false;
			}
		}
		target.length = 0;
		target.length = 1;
		tIdx = 0;
	}
}

public class EnemyRing:Ring{
	public enemySet *es;
	public bool target;
	public double x,y,z,aim;
	public Object[] o;
	public this(Caller caller ,enemySet *es,bool target ,Vector3 pos ,double aim,Object[] o,char[] name ,int span ,double R=0.4 ,double G=0.2,double B=1.0,double alpha=1.0 ,double deg = 0.0){
		if(target){
			R = 1.0; G = 0.3 ;B = 0.5; alpha = 1.0;
		}else{
			R = 0.4; G = 0.6 ;B = 2.0; alpha = 1.0;
		}
		super(caller,pos,name,span,R,G,B,alpha ,deg);
		this.es = es;
		this.target = target;
		this.x=pos.x;
		this.y=pos.y;
		this.z=pos.z;
		this.aim=aim;
		this.o = o;
	}
}

public class Stage1:Stage{
	
	public this(){
		 
		
		add(0,30 ,"stillEnemy" 	,true,200 ,0 ,0 ,PI);
		add(1,0 ,"stillEnemy" 	,true,180 ,100 ,0 ,PI);
		add(2,0 ,"stillEnemy" 	,true,-150 ,-150 ,0 ,PI);
		add(2,0 ,"stillEnemy" 	,true,-250 ,20 ,0 ,PI);
		
		add(3,10 ,"stillEnemy" 	,false,100 ,150 ,0 ,PI);
		add(3,15 ,"stillEnemy" 	,false,200 ,0 ,0 ,PI);
		add(3,20 ,"stillEnemy" 	,false,100 ,-150 ,0 ,PI);
		add(3,10 ,"stillEnemy" 	,true,-100 ,-150 ,0 ,PI);
		add(3,15 ,"stillEnemy" 	,true,-200 ,0 ,0 ,PI);
		add(3,20 ,"stillEnemy" 	,true,-100 ,150 ,0 ,PI);
		
		
//		add(4,10 ,"wideSlowEnemy" ,true ,340 ,0 ,0 ,PI);
		add(5,0  ,"boss1"				,true ,300 ,0 , -200 ,PI ,null,true); 
		/*
		add(6,60 ,"wideSlowEnemy" ,true ,340 ,0 ,0 ,PI);
		add(6,90 ,"wideSlowEnemy" ,true ,0 ,240 ,0 ,-PI /2.0);
		add(6,120 ,"wideSlowEnemy" ,true ,-340 ,0 ,0 ,0.0);
		add(6,150 ,"wideSlowEnemy" ,true ,0 ,-240 ,0 ,PI /2.0);
		*/
	}
	public override void runImpl(){
		
	}
	public override int music(){
		return music_kind.MUSIC1;
	}
}

public class Stage2:Stage{
	
	public this(){
		
		
		add(0,0 ,"stillEnemy" 	,true,200 ,-150 ,0 ,PI);
		add(0,0 ,"stillEnemy" 	,false,250 ,-200 ,0 ,PI);
		add(0,0 ,"stillEnemy" 	,true,300 ,-150 ,0 ,PI);
		add(0,0 ,"stillEnemy" ,false,250 ,-100 ,0 ,PI);
		add(0,30 ,"stillEnemy" 	,true,-100 ,150 ,0 ,PI);
		add(0,30 ,"stillEnemy" 	,false,-150 ,100 ,0 ,PI);
		add(0,30 ,"stillEnemy" 	,true,-100 ,50 ,0 ,PI);
		add(0,30 ,"stillEnemy" ,false,-50 ,100 ,0 ,PI);
		
		add(0,60 ,"stillEnemy" 	,true,-300 ,-150 ,0 ,PI);
		add(0,60 ,"stillEnemy" 	,false,-250 ,-200 ,0 ,PI);
		add(0,60 ,"stillEnemy" 	,true,-200 ,-150 ,0 ,PI);
		add(0,60 ,"stillEnemy" ,false,-250 ,-100 ,0 ,PI);
		
		add(3,0 ,"stillEnemy" 	,true,300 ,0 ,0 ,PI);
		add(3,0 ,"stillEnemy" 	,false,280 ,30 ,0 ,PI);
		add(3,0 ,"stillEnemy" 	,true,250 ,50 ,0 ,PI);
		add(3,0 ,"stillEnemy" 	,false,220 ,30 ,0 ,PI);
		add(3,0 ,"stillEnemy" 	,true,200 ,0 ,0 ,PI);
		add(3,0 ,"stillEnemy" 	,false,220 ,-30 ,0 ,PI);
		add(3,0 ,"stillEnemy" ,true,250 ,-50 ,0 ,PI);
		add(3,0 ,"stillEnemy" 	,false,280 ,-30 ,0 ,PI);
		add(4,0 ,"wideSlowEnemy" 	,true,-380 ,0 ,0 ,0);
		add(4,60 ,"wideSlowEnemy" 	,true,-380 ,200 ,0 ,0);
		add(4,120 ,"wideSlowEnemy" 	,true,-380 ,-200 ,0 ,0);
		add(5,0  ,"boss2"				,true ,300 ,0 , 440 ,PI/2 ,null,true);
	}
	public override void runImpl(){
		
	}
	public override int music(){
		return music_kind.MUSIC1;
	}
}

public class Stage3:Stage{
	
	public this(){
		
		
		add(0,0 ,"wideSlowEnemy" 	,false,380 ,0 ,0 ,PI);
		add(0,60 ,"wideSlowEnemy" 	,false,0 ,280 ,0 ,-PI/2.0);
		add(0,120 ,"wideSlowEnemy" 	,false,-380 ,0 ,0 ,0);
		add(0,180 ,"wideSlowEnemy" 	,true,0 ,-280 ,0 ,PI/2.0);
		add(1,240 ,"middleEnemy1" 	,true,400 ,0 ,0 ,PI);
		add(1,0 ,"wideSlowEnemy" 	,false,0 ,-280 ,0 ,PI/2.0);
		add(1,120 ,"wideSlowEnemy" 	,false,100 ,280 ,0 ,-PI/2.0);
		add(1,240 ,"wideSlowEnemy" 	,false,-300 ,-280 ,0 ,PI/2.0);
		add(1,400 ,"wideSlowEnemy" 	,false,200 ,280 ,0 ,-PI/2.0);
		add(1,560 ,"wideSlowEnemy" 	,false,0 ,-280 ,0 ,PI/2.0);
		add(1,720 ,"wideSlowEnemy" 	,true,-300 ,280 ,0 ,-PI/2.0);
		add(2,0  ,"boss3"				,true ,200 ,0 , -200 ,0.0 ,null,true);
//		add(1,240 ,"wideSlowEnemy" 	,false,100 ,-280 ,0 ,PI/2.0);
	}
	public override void runImpl(){
		
	}
	public override int music(){
		return music_kind.MUSIC3;
	}
}
public class Stage4:Stage{
	
	public this(){
		add(0,0 ,"zab" 	,false,380 ,0 ,0 ,PI);
		add(0,10 ,"zab" 	,false,200 ,150 ,0 ,PI);
		add(0,20 ,"zab" 	,false,300 ,-60 ,0 ,PI);
		add(0,30 ,"zab" 	,false,150 ,-120 ,0 ,PI);
		add(0,40 ,"zab" 	,false,50 ,200 ,0 ,PI);
		add(0,50 ,"zab" 	,false,-300 ,-240 ,0 ,PI);
		add(0,60 ,"zab" 	,false,-200 ,-60 ,0 ,PI);
		add(0,70 ,"zab" 	,false,-50 ,230 ,0 ,PI);
		add(0,80 ,"zab" 	,false,100 ,30 ,0 ,PI);
		add(0,90 ,"zab" 	,false,0 ,0 ,0 ,PI);
		add(0,100 ,"zab" 	,false,-80 ,-60 ,0 ,PI);
		add(0,110 ,"zab" 	,false,-300 ,-250 ,0 ,PI);
		add(0,120 ,"zab" 	,false,200 ,-210 ,0 ,PI);
		add(0,130 ,"zab" 	,false,20 ,250 ,0 ,PI);
		add(0,140 ,"zab" 	,false,-120 ,20 ,0 ,PI);
		add(0,150 ,"zab" 	,false,340 ,10 ,0 ,PI);
		add(0,160 ,"zab" 	,false,-100 ,150 ,0 ,PI);
		add(0,170 ,"zab" 	,false,170 ,-230 ,0 ,PI);
		add(0,200 ,"stillEnemy" 	,true,-300 ,0 ,0 ,PI);
		add(1,0 ,"upLaserEnemy" 	,false,400 ,-280 ,0 ,PI);
		add(1,120 ,"downLaserEnemy" 	,false,400 ,280 ,0 ,PI);
		add(1,240 ,"upLaserEnemy" 	,false,400 ,-280 ,0 ,PI);
		add(1,360 ,"downLaserEnemy" 	,false,400 ,280 ,0 ,PI);
		add(1,480 ,"upLaserEnemy" 	,false,400 ,-280 ,0 ,PI);
		add(1,600 ,"downLaserEnemy" 	,false,400 ,280 ,0 ,PI);
		add(1,240 ,"stillEnemy" 	,true,-300 ,200 ,0 ,PI);
		add(1,360 ,"stillEnemy" 	,true,50 ,250 ,0 ,PI);
		add(1,480 ,"stillEnemy" 	,true,-150 ,-150 ,0 ,PI);
		add(1,600 ,"stillEnemy" 	,true,200 ,170 ,0 ,PI);
		add(1,660 ,"stillEnemy" 	,true,350 ,0 ,0 ,PI);
		add(2,0   ,"boss4"			,true,50 ,180 ,-400 ,PI ,null ,true);
	}
	public override void runImpl(){
		
	}
	public override int music(){
		return music_kind.MUSIC3;
	}
}

public class Stage5:Stage{
	
	public this(){
		add(0,0 ,"homingEnemy" 	,false,380 ,0 ,-100 ,PI);
		add(0,45 ,"homingEnemy" ,false,240 ,180 ,-100 ,-PI/3);
		add(0,90 ,"homingEnemy" ,false,-140 ,-250 ,-100 ,PI/3);
		add(0,135 ,"homingEnemy" ,false,-360 ,-50 ,-100 ,0);
		add(0,240 ,"stillEnemy" ,true,50 ,0 ,0 ,0);
		add(1,0 ,"turretEnemy" 	,false,380 ,0 ,0 ,PI);
		add(1,30 ,"turretEnemy" 	,false,140 ,230 ,0 ,PI);
		add(1,30 ,"turretEnemy" 	,false,140 ,-230 ,0 ,PI);
		add(1,90 ,"homingEnemy" 	,false,200 ,100 ,-100 ,PI);
		add(1,90 ,"homingEnemy" 	,false,200 ,-100 ,-100 ,PI);
		add(1,360 ,"stillEnemy" ,true,-300 ,0 ,0 ,0);
		add(2,0 ,"turretEnemy" 	,false,300 ,0 ,0 ,PI);
		add(2,0 ,"turretEnemy" 	,false,100 ,200 ,0 ,-PI*2/3);
		add(2,0 ,"turretEnemy" 	,false,-100 ,200 ,0 ,-PI/3);
		add(2,0 ,"turretEnemy" 	,false,-300 ,0 ,0 ,0);
		add(2,0 ,"turretEnemy" 	,false,100 ,-200 ,0 ,PI*2/3);
		add(2,0 ,"turretEnemy" 	,false,-100 ,-200 ,0 ,PI/3);
		add(2,300 ,"stillEnemy" ,true,0 ,0 ,0 ,0);
		add(3,0   ,"boss5"			,true,-380 ,0 ,-200 ,0 ,null ,true);
	}
	public override void runImpl(){
		
	}
	public override int music(){
		return music_kind.MUSIC4;
	}
}

public class Stage6:Stage{
	
	public this(){
		int interval= 30;
		for(int t=0;t<=150;t+=interval*2){
			add(0,t ,"boundEnemy" 	,false,rand.nextFloat(500)-120 ,280 ,0 ,PI);
			add(0,t+interval ,"boundEnemy" 	,false,rand.nextFloat(500)-380 ,280 ,0 ,0);
		}
		/*
		add(0,0 ,"boundEnemy" 	,false,200 ,280 ,0 ,PI);
		add(0,30 ,"boundEnemy" 	,false,-100 ,280 ,0 ,0);
		add(0,60 ,"boundEnemy" 	,false,50 ,280 ,0 ,PI);
		add(0,90 ,"boundEnemy" 	,false,100 ,280 ,0 ,0);
		add(0,120 ,"boundEnemy" 	,false,350 ,280 ,0 ,PI);
		add(0,150 ,"boundEnemy" 	,false,-300 ,280 ,0 ,0);
		*/
		/*
		add(0,15 ,"boundEnemy" 	,false,250 ,280 ,0 ,PI);
		add(0,45 ,"boundEnemy" 	,false,200 ,280 ,0 ,PI);
		add(0,75 ,"boundEnemy" 	,false,10 ,280 ,0 ,0);
		add(0,105 ,"boundEnemy" 	,false,-50 ,280 ,0 ,PI);
		add(0,135 ,"boundEnemy" 	,false,90 ,280 ,0 ,0);
		*/
		
		add(0,20 ,"sidewayEnemy" 	,true,380 ,50 ,0 ,PI * 8.0/9.0 );
		add(0,80 ,"sidewayEnemy" 	,true,-380 ,120 ,0 ,PI/9.0 );
		add(0,140 ,"sidewayEnemy" 	,true,380 ,280 ,0 ,PI * 8.0/9.0 );
		
		interval= 23;
		for(int t=0;t<=350;t+=interval*2){
			add(1,t ,"boundEnemy" 	,false,rand.nextFloat(500)-120 ,280 ,0 ,PI);
			add(1,t+interval ,"boundEnemy" 	,false,rand.nextFloat(500)-380 ,280 ,0 ,0);
		}
		/*
		add(1,0 ,"boundEnemy" 	,false,50 ,280 ,0 ,PI);
		add(1,20 ,"boundEnemy" 	,false,-250 ,280 ,0 ,0);
		add(1,40 ,"boundEnemy" 	,false,300 ,280 ,0 ,PI);
		add(1,60 ,"boundEnemy" 	,false,-50 ,280 ,0 ,0);
		add(1,80 ,"boundEnemy" 	,false,-150 ,280 ,0 ,PI);
		add(1,100 ,"boundEnemy" 	,false,120 ,280 ,0 ,0);
		add(1,120 ,"boundEnemy" 	,false,250 ,280 ,0 ,PI);
		add(1,140 ,"boundEnemy" 	,false,-100 ,280 ,0 ,0);
		add(1,160 ,"boundEnemy" 	,false,-20 ,280 ,0 ,PI);
		add(1,180 ,"boundEnemy" 	,false,60 ,280 ,0 ,0);
		add(1,200 ,"boundEnemy" 	,false,180 ,280 ,0 ,PI);
		add(1,220 ,"boundEnemy" 	,false,-320 ,280 ,0 ,0);
		add(1,240 ,"boundEnemy" 	,false,0 ,280 ,0 ,PI);
		add(1,260 ,"boundEnemy" 	,false,-140 ,280 ,0 ,0);
		*/
//		add(1,280 ,"boundEnemy" 	,true,-30 ,280 ,0 ,PI);
		
		/*
		add(1,10 ,"boundEnemy" 	,false,50 ,280 ,0 ,PI);
		add(1,30 ,"boundEnemy" 	,false,-250 ,280 ,0 ,0);
		add(1,50 ,"boundEnemy" 	,false,300 ,280 ,0 ,PI);
		add(1,70 ,"boundEnemy" 	,false,-50 ,280 ,0 ,0);
		add(1,90 ,"boundEnemy" 	,false,-150 ,280 ,0 ,PI);
		add(1,110 ,"boundEnemy" 	,false,-120 ,280 ,0 ,PI);
		add(1,130 ,"boundEnemy" 	,false,120 ,280 ,0 ,0);
		add(1,150 ,"boundEnemy" 	,false,-300 ,280 ,0 ,0);
		add(1,170 ,"boundEnemy" 	,false,160 ,280 ,0 ,PI);
		add(1,190 ,"boundEnemy" 	,false,260 ,280 ,0 ,0);
		add(1,210 ,"boundEnemy" 	,false,-80 ,280 ,0 ,0);
		add(1,230 ,"boundEnemy" 	,false,200 ,280 ,0 ,PI);
		add(1,250 ,"boundEnemy" 	,false,-100 ,280 ,0 ,PI);
		add(1,270 ,"boundEnemy" 	,false,140 ,280 ,0 ,PI);
		add(1,290 ,"boundEnemy" 	,false,120 ,280 ,0 ,PI);
		*/
		
		add(1,0 ,"fourwayEnemy" 	,true,380 ,-120 ,0 ,PI );
		add(1,160 ,"fourwayEnemy" 	,true,-380 ,110 ,0 ,0 );
		add(2,0 ,"boss6" 	,true,0 ,-480 ,0 ,0 ,null ,true);
	}
	public override void runImpl(){
		
	}
	public override int music(){
		return music_kind.MUSIC4;
	}
}
public class Stage7:Stage{
	
public this(){
		int interval= 12;
		for(int t=0;t<300;t+=interval*2){
			float y = rand.nextFloat(300) - 300;
			add(1,t ,"thrustEnemy" 	,false,380 ,y ,0 ,PI );
			y = rand.nextFloat(300);
			add(1,t+interval ,"thrustEnemy" 	,false,380 ,y ,0 ,PI );
		}
		float y = rand.nextFloat(600) - 300;
		add(1,312 ,"thrustEnemy" 	,true,380 ,y ,0 ,PI );
		
		
		double rad1 = PI*2.0/3.0;
		double rad2 = -PI*2.0/3.0;
		double x1 ,y1 ,x2 ,y2;
		x1 = x2 = 300;
		y1 = y2 = 0;
		interval = 100;
		
		add(2,0 ,"turretEnemy" 	,false,300 ,0 ,0 ,PI);
		for(int t=interval;t<200;t+=interval){
			x1 += 200.0*cos(rad1);
			y1 += 200.0*sin(rad1);
			x2 += 200.0*cos(rad2);
			y2 += 200.0*sin(rad2);
			add(2,t ,"turretEnemy" 	,false,x1 ,y1 ,0 ,rad1+PI/2.0);
			add(2,t ,"turretEnemy" 	,false,x2 ,y2 ,0 ,rad2-PI/2.0);
			rad1 += PI /3.0;//rand.nextFloat(PI / 8.0) - PI / 16.0;
			rad2 -= PI /3.0;//rand.nextFloat(PI / 8.0) - PI / 16.0;
		}
		x1 += 120.0*cos(rad1);
		y1 += 120.0*sin(rad1);
		x2 += 120.0*cos(rad2);
		y2 += 120.0*sin(rad2);
		add(2,250 ,"turretEnemy" 	,true,x1 ,y1 ,0 ,rad1+PI/2.0);
		add(2,250 ,"turretEnemy" 	,true,x2 ,y2 ,0 ,rad2-PI/2.0);
		
		interval = 45;
		for(int t=0;t<700;t+=interval*2){
			y = rand.nextFloat(300) - 300;
			add(2,t ,"thrustEnemy" 	,false,380 ,y ,0 ,PI );
			y = rand.nextFloat(300);
			add(2,t+interval ,"thrustEnemy" 	,false,380 ,y ,0 ,PI );
		}
		for(int t=0;t<800;t+=200){
			for(y=-300;y<=300;y+=60){
				add(3,t ,"wall" 	,false,380 ,y ,0 ,PI );
			}
		}
		for(y=-300;y<=300;y+=60){
			add(3,800 ,"wall" 	,true,380 ,y ,0 ,PI );
		}
		for(int t=0;t<1200;t+=180){
			y=rand.nextFloat(400.0)-200.0;
			add(3,t ,"chaseEnemy" ,false,-380 ,y ,0 ,0 );
		}
		
		add(4,0 ,"boss7" 	,true,-700 ,-70 ,-300 ,0 ,null ,true);
	}
	public override void runImpl(){
//		background.setAxis(0.5 ,0.5 ,0.0);
//		background.theta += 0.1;
	}
	public override int music(){
		return music_kind.MUSIC5;
	}
}


public class Stage8:Stage{
	
	public this(){
		for(double rad = -PI;rad < PI;rad += PI / 16.0){
			add(1,0 ,"foldEnemy" 	,false,250 * cos(rad) ,250*sin(rad) ,0 ,PI);
		}
		for(double rad = -PI;rad < PI;rad += PI / 16.0){
			add(1,90 ,"foldEnemy" 	,false,250 * cos(rad) ,250*sin(rad) ,0 ,PI);
		}
		for(double rad = -PI;rad < PI;rad += PI / 16.0){
			add(1,180 ,"foldEnemy" 	,true,250 * cos(rad) ,250*sin(rad) ,0 ,PI);
		}
		for(int i=0;i<128;i+=3){
			add(2,i,"zab" ,false ,rand.nextFloat(780)-390,rand.nextFloat(580)-290 ,0 ,0);
		}
		add(2,128,"zab" ,true ,rand.nextFloat(780)-390,rand.nextFloat(580)-290 ,0 ,0);
		
		for(int t=0;t<600;t+=250){
			add(3,t,"upLaserEnemy" ,false ,380 ,-280 ,0,PI);
			add(3,t,"upLaserEnemy" ,false ,-380 ,280 ,0,0);
			add(3,t,"upLaserEnemy" ,false ,380 ,280 ,0,-PI/2);
			add(3,t,"upLaserEnemy" ,false ,-380 ,-280 ,0 ,PI/2);
		}
		add(3,700,"stillEnemy" ,true ,0 ,0 ,0 ,0);
		add(4,0 ,"stillEnemy" ,true ,800 ,0 ,0 ,0);
		add(5,0 ,"boss8" 	,true,0 ,0 ,-800 ,0 ,null ,true);
	}
	public override void runImpl(){
		switch(level){
			case 0:
			if(nowLevelCnt == 0){
				Sound_HaltMusic();
			}
			
			if(nowLevelCnt >= 150){
				if(nowLevelCnt == 150){
					if(Sound_PlayingMusic()==-1)Sound_PlayMusic(music_kind.MUSIC7);
				}
				if(0 <= nextMusic && Sound_PlayingMusic()==-1)Sound_PlayMusic(nextMusic);
			}
			
			break;
			case 4:
			if(nowLevelCnt == 0){
				Sound_FadeOutMusic(0);
				background.setAxis(1.0 ,0.6 ,1.0);
			}
			
			if(-330<background.theta)background.theta -= 1.0;
			break;
			case 5:
			/*
			if(nowLevelCnt == 0){
				Sound_HaltMusic();
			}
			*/
			if(nowLevelCnt >= 150){
				if(nowLevelCnt == 150){
					if(Sound_PlayingMusic()==-1)Sound_PlayMusic(music_kind.MUSIC7);
				}
				if(0 <= nextMusic && Sound_PlayingMusic()==-1)Sound_PlayMusic(nextMusic);
			}
			
			break;
			default:break;
		}
	}
	public override int music(){
		return music_kind.MUSIC6;
	}
}



private int nextMusic = -1;
public void setNextMusic(int music){
	nextMusic = music;
}

public class Ending:Stage{
	
	public this(){
		add(0,0 ,"boss8imitate" 	,true,400 ,100 ,-700 ,-15 ,null ,true);
		add(0,90 ,"boss8imitate" 	,true,-100 ,50 ,400 ,-10 ,null ,true);
		add(0,180 ,"boss8imitate" 	,true,50 ,-200 ,-500 ,-5 ,null ,true);
		add(0,270 ,"boss8imitate" 	,true,0 ,0 ,-200 ,0 ,null ,true);
		add(0,1000 ,"stillEnemy" 	,true,800 ,0 ,0 ,0);
	}
	public override void runImpl(){
		if(totalCnt == 850){
//			new Bomb();
			new Blast2(0.0 ,0.0 ,0.01 ,0.006 ,350 ,1.0 ,1.0 ,1.0 ,1.0);
		}
		if(totalCnt == 1080){
			shipManager.allDestroy();
			enemyManager.allDestroy();
			background.drawing = false;
		}
	}
	public override void drawImpl(){
		
		asciiR = 1.0;asciiG = 1.0;asciiB = 1.0;asciiAlpha = 1.0;
		if(totalCnt > 400 && totalCnt < 600){
			drawString("ready to destroy" ,-300 ,-100 ,0 ,(totalCnt - 400) / 5);
			drawString(" the warp hole" ,-120 ,-160 ,0 ,(totalCnt - 500) / 5);
		}
		if(totalCnt > 630 && totalCnt < 800){
			drawString("start destroying" ,-240 ,-130 ,0 ,(totalCnt - 630) / 5);
		}
		
		if(totalCnt > 830 && totalCnt < 1000){
			drawString("we are proud of you" ,-270 ,-130 ,0 ,(totalCnt - 830) / 5);
		}
		if(totalCnt > 1020 && totalCnt < 1100){
			drawString("thank you" ,-120 ,-130 ,0 ,(totalCnt - 1030) / 2);
		}
		
	}
	public override int music(){
		return -1;
	}
	
}