//@STATE=嶌惉拞
//@DESCRIPTION ---------------------------------------------------------------
// EA01.cpp: EA01 僋儔僗偺僀儞僾儕儊儞僥乕僔儑儞
//	棜楌丗
// $Log: EA01.cpp,v $
// Revision 1.1  2001/10/28 21:40:35  fujiwara
// DLL偵暘妱
//
// Revision 1.5  2001/07/09 20:30:08  fujiwara
// 椺奜張棟偺慻傒崬傒
//
// Revision 1.4  2001/07/01 21:30:33  fujiwara
// 儊儌儕儕乕僋僠僃僢僋尒捈偟
//
// Revision 1.3  2001/07/01 01:03:43  fujiwara
// const 偺尒捈偟
// 攝抲僄僨傿僞偼搑拞宱夁
//
// Revision 1.2  2001/06/10 21:18:15  fujiwara
// 抧忋梡捛壛
//
// Revision 1.1  2001/06/03 09:21:49  fujiwara
// 抧忋揋僋儔僗偺捛壛
//
//@DESCRIPTION_END -----------------------------------------------------------
//@AUTHOR=S.F.
// Copyright (C) 2000 Satoshi Fujiwara. All Rights Reserved.
///////////////////////////////////////////////////////////////////////////////
#pragma warning( disable : 4786 )	//STL偺寈崘奜偟

// 儊儌儕乕儕乕僋専弌梡
#include "sfdebug.h"

// System Includes //

#include <string>
#include <vector>
#include <memory>
#include <stack>
#include <list>
#include <iostream>
#include <fstream>
#include <map>
#include "stdio.h"
#include "math.h"

// Project Includes //

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#include "exception.h"
#include "singleton.h"
#include "system.h"
#include "console.h"
#include "input.h"
#include "sound.h"

#include "Obj.h"
#include "Obj2D.h"
#include "Obj3D.h"
#include "Obj3DL.h"
#include "ObjRectangle.h"
#include "ObjQuadrangle.h"

#include "Background.h"
#include "Scene.h"
#include "main.h"

#include "character.h"
#include "Hit.h"
#include "MyShip.h"
#include "Game.h"
#include "Enemys.h"
#include "Armys.h"
#include "EnemyBullets.h"
#include "DispositionControl.h"
#include "Effects.h"
#include "Explosion.h"
#include "EA01.h"
#include "EB01.h"

using namespace sf::application;
using namespace sf::application::enemy;

sf::system::console::sprite::PSprite EA01::mspSprite[2];


const sf::system::console::sprite::Info EA01::msSpriteInfo[2] = 
{
	{"media\\ea01.png",0.0f,0.0f,64.0f,64.0f,0xff000000,console::sprite::SPRITE2D},
	{"media\\ea01foot.tga",0.0f,0.0f,64.0f,64.0f,0xff000000,console::sprite::SPRITE2D}
};

const int EA01::SCORE = 20;
const float LIGHT_OFFSET_Y = -14.0f;

// 僐儞僗僩儔僋僞 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
EA01::EA01()
{
}// EA01()

// 僨僗僩儔僋僞 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
EA01::~EA01()
{
	Armys::instance()->clear(index());
}// ~EA01()


// 弶婜壔 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void EA01::initialize()
{
	// 摉傝敾掕 
	mHitRect.offsetTop(-24.0f);
	mHitRect.offsetBottom(24.0f);
	mHitRect.offsetLeft(-24.0f);
	mHitRect.offsetRight(24.0f);

	mHitRect.isChecking(true);
	mHitRect.characterPtr(this);

	direction((float)atan2((double)(game()->player()->y() - y()),(double)(game()->player()->x() - x())));
	
	if(direction() < 0.0f)
		direction(2.0f * sf::system::PI + direction()); 
	
	speed(0.0f);
	
	mDeltaTime = sf::system::instance()->deltaTime();
	mDeltaTimeRev = 1.0f / mDeltaTime;

	if(!mspSprite[0].get())
		load();

	mObj.index(0);
	mObj.sprite(mspSprite[0].get());
	
	mObj.z(Z_OFFSET_ARMYS + index() * Z_OFFSET_INDEX);
	mObj.x(x());
	mObj.y(y());

	mObj.visibility(true);
	mObj.color(0xffffffff);
	mObj.drawMode(sf::system::console::DRAW_TRANS);
	mObj.angle(direction());

	mObjFoot.index(0);
	mObjFoot.sprite(mspSprite[1].get());
	
	mObjFoot.z(Z_OFFSET_ARMYS + index() * Z_OFFSET_INDEX + Z_OFFSET_ASSEMBLE);
	mObjFoot.x(x());
	mObjFoot.y(y());

	mObjFoot.visibility(true);
	mObjFoot.color(0xffffffff);
	mObjFoot.drawMode(sf::system::console::DRAW_TRANS);
	
	mbHit = false;
	mDirCount = (rand() & 3) + 3;
	mDirSpeed = (direction() > 0.0f) ? 0.04f * mDeltaTime : -0.04f * mDeltaTime;
	mState = MOVE;
	
	mShootTimer = (80.0f - game()->currentDifficulty() * 15.0f) * mDeltaTimeRev;
	mShootCount = game()->currentDifficulty() + 2.0f;
	
	mObjLight.x(x() + cosf(direction()) * LIGHT_OFFSET_Y );
	mObjLight.y(y() + sinf(direction()) * LIGHT_OFFSET_Y );


	mObjLight.z(z() - Z_OFFSET_ASSEMBLE);
	initLight();
}// initialize()

// 僥僋僗僠儍偺儘乕僪 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void EA01::load(void){
	using namespace sf::system::console::sprite;
	if(!mspSprite[0].get()){
		PSprite ptemp(sf::system::instance()->console()->createSprite(&msSpriteInfo[0])); 
		mspSprite[0] = ptemp;

#ifdef _BORLAND
		ptemp.reset(sf::system::instance()->console()->createSprite(&msSpriteInfo[1]));
#else
		ptemp = PSprite(sf::system::instance()->console()->createSprite(&msSpriteInfo[1]));
#endif
		mspSprite[1] = ptemp;

//		PSprite ptemp1(sf::system::instance()->console()->createSprite(&msSpriteInfo[1])); 
//		if(ptemp1.get() == NULL)
//			return false;
//		mspSprite[1] = ptemp1;

	}
	Bullets::instance()->load(Bullets::EB01);
	AbstractEnemy::loadLight();
}// load()

// 僥僋僗僠儍偺傾儞儘乕僪 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void EA01::unload(void){
	using namespace sf::system::console::sprite;
	PSprite ptmp(NULL);
	mspSprite[0] = ptmp;
	mspSprite[1] = ptmp;

}// unload()

// 揋偺摦嶌 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void EA01::move()
{
	using namespace sf::application;

	float dir,tmpx,tmpy;

	y(y() + game()->scrollSpeed());
	
	mObj.y(y());
	mObjFoot.y(y());

	switch(mState){
	case MOVE:
		// 
		dir = fabs(mDirBackup - direction());
		
		if(dir > sf::system::PI)
			dir = 2.0f * sf::system::PI - dir;
		
		if(dir > 0.08f)
		{
			direction(direction() + mDirSpeed);
			
			if(direction() < 0.0f)
				direction(2.0f * sf::system::PI + direction());
		
			if(direction() > 2.0f * sf::system::PI)
				direction(direction() - 2.0f * sf::system::PI);

			dir = direction() - mDirBackup;
			
			if(dir < 0.0f) dir = dir + 2.0f * sf::system::PI;
			
			if(dir > sf::system::PI) 
				mDirSpeed = 0.04f;
			else
				mDirSpeed = -0.04f;
	
			mObj.angle(direction());

		}

		if(!mDirCount--){
			mDirCount = 30.0f * mDeltaTimeRev;
			mDirBackup = Util::calcDirection(x(),y(),game()->player()->x(),game()->player()->y());
 			if(mDirBackup < 0.0f)
				mDirBackup = 2.0f * sf::system::PI + mDirBackup; 

			dir = direction() - mDirBackup;
			if(dir < 0.0f) dir = dir + 2.0f * sf::system::PI;
			
			if(dir > sf::system::PI) 
				mDirSpeed = -0.04f * mDeltaTime;
			else
				mDirSpeed = 0.04f * mDeltaTime;
				
		}
	
		if(mShootCount){
			if(!(mShootTimer--) ){
				mState = SHOOT;
				mShootCount--;
				mShootTimer = 80.0f * mDeltaTimeRev;
				mAnimTimer = (int)(2.0f * mDeltaTimeRev);
				mAnimSpeed = 1;
			}
		}
		
		if(mbHit)
		{
			die();
			return;
		}

		mObjLight.x(x() + cosf(direction()) * LIGHT_OFFSET_Y );
		mObjLight.y(y() + sinf(direction()) * LIGHT_OFFSET_Y );
		moveLight();

		break;

	case SHOOT:
		if(!mAnimTimer--){
			if(mAnimSpeed == 1){
				if(mObj.index() == 3)
				{
					tmpx = x() + cosf(direction()) * 6.0f;
					tmpy = y() + sinf(direction()) * 6.0f;

					EB01 *peb = (EB01 *)Bullets::instance()->create(Bullets::EB01,tmpx,tmpy,z() - 0.01f,game());
					peb->direction(direction());
					mAnimSpeed = -1;
					mAnimTimer = (int)(2.0f * mDeltaTimeRev);
				} else {
					mObj.index(mObj.index() + mAnimSpeed);
					mAnimTimer = (int)(2.0f * mDeltaTimeRev);
				}
			} else {
				if(mObj.index() == 0){
					mState = MOVE;
				} else {
					mObj.index(mObj.index() + mAnimSpeed);
					mAnimTimer = (int)(2.0f * mDeltaTimeRev);
				}
			}
		};

		mObjLight.x(x() + cosf(direction()) * LIGHT_OFFSET_Y );
		mObjLight.y(y() + sinf(direction()) * LIGHT_OFFSET_Y );
		
		moveLight();
		if(mbHit)
		{
			die();
			return;
		}

		break;
	case DEAD:
		if(!mDirCount){
			mObjLight.visibility(false);
			mObj.visibility(false);
			return;
		} else {
			mDirCount--;
		}
		
		break;
	
	}

	if( y() < -64.0f || y() > (sf::system::console::viewport::HEIGHT + 32.0f))
		delete this;
}//move()



// 抏偵偁偨偭偨偲偒偺張棟 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void EA01::hit(Character * const pDest)
{
	if(pDest->life()){
		mHitRect.isChecking(false);
		mbHit = true;
	}
};

// 揋偺惗惉 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
sf::application::Character * const EA01::create(float x,float y ,float z,sf::application::scene::Game * const pGame,int index)
{
	EA01 * ptemp = new EA01;
	ptemp->x(x);
	ptemp->y(y);
	ptemp->z(Z_OFFSET_ARMYS);
	ptemp->index(index);
	ptemp->game(pGame);
	ptemp->initialize();
	return ptemp;
;}// create

//丂巰傫偩偲偒偺張棟  亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void EA01::die(void)
{
	
	direction(3.0f * sf::system::PI / 2.0f );
	speed( - game()->scrollSpeed());

	effect::Explosion *pExp = (effect::Explosion*)effect::Effects::instance()->create(effect::Effects::EXPLOSION,x(),y(),0.5f,game(),this);
	if(pExp){
		pExp->scaling(1.0f);
	}
	mDirCount = 2;
	mState = DEAD;
	game()->score(game()->score() + SCORE);

};// die()

//  慡敋敪僀儀儞僩 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void EA01::allBomb(void)
{
	die();
}// allBomb()