#define  COMMON_FLY_H aaa
//----------------------------------------------------------------------------
//  @brief
//        новый геймплей тут будет реализовываться
//        

//  @ingroup
    
//  2006Oct02 created. Zmanovsky Peter.
//  (C) 2006    Sigma-Team
//-----------------------------------------------------------------------------

#ifndef COMMON_STATISTICS_H
    #include "maps\common_statistics.lgc"
#endif

#ifndef COMMON_MAP_H
	#include "maps\common_map.lgc"
#endif

#ifndef UTIL_CRYSTALS_H
    #include "maps\util_crystals.lgc"
#endif

static bool bMapWin = false;	//флаг что карта уже пройдена

//------------------------------------------------------------------------------------------
abs(int x)
{
	if(x >= 0)
		return x;
	else
		return -x;
}


//------------------------------------------------------------------------------------------
NearDistance(int d1, int d2)
{
	d1 = abs(d1);
	d2 = abs(d2);
	if(d1 > d2)
		return (d1 + d2/2);
	else
		return (d2 + d1/2);
}


//------------------------------------------------------------------------------------------
FineDistance(int d1, int d2)
{
	return NearDistance(d1, d2);
	//return SendCommand(1, d1*d1 + d2*d2);
}


//------------------------------------------------------------------------------------------
ChangePlayerVehiAnim()
{
    static int last_change_animation = -1000;
    static int last_stop_move = -1000;
	//
	if(!PlayerVehi || IsDying(PlayerVehi))
		return;
	//
    int link;
    link = Action(PlayerVehi, ACT_GET_LINK);
    //
    if ( GetInputX() < GetX(PlayerVehi) )
    {
        last_stop_move = -1000;
        Action(PlayerVehi, ACT_CHANGE_DIRECTION, 64);
        Action(link, ACT_CHANGE_DIRECTION, 64);
        if ( last_change_animation >= 0 && GetAnimation(PlayerVehi) != ANI_START_MOVE )
            ChangeVehiAnimation(ANI_GO);
        else
            ChangeVehiAnimation(ANI_START_MOVE);
        last_change_animation = GetTime();
    }
    else if ( GetInputX() > GetX(PlayerVehi) )
    {
        last_stop_move = -1000;
        Action(PlayerVehi, ACT_CHANGE_DIRECTION, 192);
        Action(link, ACT_CHANGE_DIRECTION, 192);
        if ( last_change_animation >= 0 && GetAnimation(PlayerVehi) != ANI_START_MOVE )
            ChangeVehiAnimation(ANI_GO);
        else
            ChangeVehiAnimation(ANI_START_MOVE);
        last_change_animation = GetTime();
    }
    else if ( (GetTime() - last_change_animation) > 70 )
    {
        last_change_animation = -1000;
        if ( last_stop_move >= 0 && GetAnimation(PlayerVehi) != ANI_STOP_MOVE )
            ChangeVehiAnimation(ANI_STAND);
        else
            ChangeVehiAnimation(ANI_STOP_MOVE);//STAND);
        last_stop_move = GetTime();
    }
    else
    {
        if ( GetAnimation(PlayerVehi) == ANI_STAND )
            ChangeVehiAnimation(ANI_GO);
        if ( GetAnimation(link) == ANI_STAND )
            Action(link, ANI_GO);
    }
}


//------------------------------------------------------------------------------------------
static int giSpeedX = 0;
static int giSpeedY = 0;

//------------------------------------------------------------------------------------------
MoveVehiTo(int x, int y, int limleft, int limtop, int limright, int limbtm)
{
	int xx, yy, ax, ay, alen, dt, vlen, MaxSpeed, MustBeMaxSpeed;
	//
	static int PrevTime = 0;
	iff(1)
		PrevTime = GetTime();
	dt = GetTime()-PrevTime;
	//
	if(!PlayerVehi)
		return;

	//экранные координаты самолета
	xx = ToScreenX(GetX(PlayerVehi));
	yy = ToScreenY(GetY(PlayerVehi), GetZ(PlayerVehi));
	//
	MaxSpeed = MAX_VEHI_SPEED;
	MustBeMaxSpeed = 0;
	ax = (x-xx);
	ay = (y-yy);
	alen = SizeTo(PlayerVehi, x, -ToScreenY(0)+y);  //теперешняя длина вектора a
	//alen = FineDistance(ax,ay);
	if(alen)
	{
		//нормализуем до нужной длины, если надо
		ax = ax * VEH_MAX_ACCELERATION / alen;
		ay = ay * VEH_MAX_ACCELERATION / alen;
		//
		//Log("alen="+itoa(alen));
		//устанавливаем MaxSpeed в зависимости от того, насколько сильно двигали мышку
		if(alen < MOUSE_PIXELS_MIN)
			alen = MOUSE_PIXELS_MIN;
		if(alen < MOUSE_PIXELS_MAX && USE_SLOW_MOUSE_MODE)
			MustBeMaxSpeed = MaxSpeed * alen / MOUSE_PIXELS_MAX;
		//Log("MustBeMaxSpeed="+itoa(MustBeMaxSpeed));
	}
	else
	{
		//врубаем торможение
		ax = -giSpeedX;
		ay = -giSpeedY;
		alen = FineDistance(ax, ay);
		if(alen)
		{
			ax = ax * VEH_STOP_ACCELERATION / alen;
			ay = ay * VEH_STOP_ACCELERATION / alen;
		}
	}
	//
	int PrevSpeedX, PrevSpeedY;
	PrevSpeedX = giSpeedX;
	PrevSpeedY = giSpeedY;
	//
	if(GAME_MODE==3 || GAME_MODE==2 && DISABLE_ACCELERATION)
	{
		giSpeedX = ax;
		giSpeedY = ay;
	}
	else
	{
		giSpeedX += ax * dt / 1000;
		giSpeedY += ay * dt / 1000;
	}
	//
	vlen = FineDistance(giSpeedX, giSpeedY);	//теперешняя длина вектора скорости
	if(MustBeMaxSpeed && GAME_MODE == 2 && !DISABLE_ACCELERATION)
	{
		int PrevSpeed; PrevSpeed = FineDistance(PrevSpeedX, PrevSpeedY);
		//обрубание производим только если новая MaxSpeed больше PrevSpeed
		//Log("MustBeMaxSpeed = " + itoa(MustBeMaxSpeed) + ". PrevSpeed = " + itoa(PrevSpeed));
		if(MustBeMaxSpeed >= PrevSpeed)
		{
			MaxSpeed = MustBeMaxSpeed;
			//Log("use MustBeMaxSpeed");
		}
	}

	//нормализуем до длины MaxSpeed
	if(vlen > MaxSpeed || vlen && (GAME_MODE == 3  || GAME_MODE==2 && DISABLE_ACCELERATION))
	{
		//производим обрубание
		giSpeedX = giSpeedX * MaxSpeed / vlen;
		giSpeedY = giSpeedY * MaxSpeed / vlen;
		//Log("cut off speed");
		//Log("speed = " + itoa(FineDistance(giSpeedX, giSpeedY)));
	}
	//
	int PrevXX, PrevYY; PrevXX = xx; PrevYY = yy;
	xx += giSpeedX * dt / 1000;
	yy += giSpeedY * dt / 1000;
	if(GAME_MODE==3 || GAME_MODE==2 && DISABLE_ACCELERATION)	//приехали
	{
		if( (x-xx)*(x-PrevXX) < 0 || (y-yy)*(y-PrevYY) < 0)
		{
			xx = x;
			yy = y;
		}
	}
	//
	if(GAME_MODE==3 || GAME_MODE==2 && DISABLE_ACCELERATION)
	{
		giSpeedX = 0; giSpeedY = 0;
	}

	//
	if(xx < limleft) xx = limleft;
	if(xx > limright) xx = limright;
	if(yy < limtop) yy = limtop;
	if(yy > limbtm) yy = limbtm;
	//
	Action(PlayerVehi, ACT_CHANGE_COOR, xx, -ToScreenY(0)+yy, GetZ(PlayerVehi));
	if(GAME_MODE==2)
		SetCursorPosition(xx, yy);
	//
	PrevTime = GetTime();
}


//------------------------------------------------------------------------------------------
ChangePlayerVehiPosition2()
{
	if(!PlayerVehi)
		return;
	ChangePlayerVehiAnim();
	//
	int link; link = Action(PlayerVehi, ACT_GET_LINK);
	//
    int x; x = GetInputX();
    int size_x; size_x = GetVidData(GetUnitVid(link), VID_SIZE_X)/2;
	//
    int y; y = ToScreenY(GetInputY());
    int size_y; size_y = GetVidData(GetUnitVid(link), VID_SIZE_Y)/2;
    int limleft, limtop, limright, limbtm;
    limleft = SCREEN_FIELD_LEFT - SCREEN_FIELD_VEHI_LIMIT + size_x;
    limright = SCREEN_FIELD_RIGHT + SCREEN_FIELD_VEHI_LIMIT - size_x;
    limtop = SCREEN_FIELD_VEHI_LIM_TOP + size_y;
    limbtm = ScreenY() - SCREEN_FIELD_VEHI_LIM_BTM - size_y;
	//
    if(x < limleft) x = limleft;
    if(x > limright) x = limright;
    if(y < limtop) y = limtop;
    if(y > limbtm) y = limbtm;
	//
	if(!bMapWin)
	{
		if(GAME_MODE==1)
			Action(PlayerVehi, ACT_CHANGE_COOR, x, -ToScreenY(0)+y, GetZ(PlayerVehi));
		else
			MoveVehiTo(x, y, limleft, limtop, limright, limbtm);
	}
}


//------------------------------------------------------------------------------------------
ChangeMapPosition(bool bGamePaused)
{
	static int y;	//y-координата карты * 1000
	iff(1)
		y = (MapSizeY() - ScreenY()/2) * 1000;
	//
	static bool bWasPaused = false;
	static int bWasPausedTime = 0;
	if(bGamePaused)
	{
		bWasPaused = true;
		return;
	}
	if(bWasPaused)	//первый такт, когда уже не пауза - запоминаем время
	{
		bWasPausedTime = GetTime();
		bWasPaused = false;
	}
	//
	static int speed = 0;
	int LevArrNum; LevArrNum = GetLevArrNum();
	//
	if(MAP_INIT_ACCELERATION_TIME && GetTime() <= MAP_INIT_ACCELERATION_TIME )
	{
		speed = bMapMinSpeed[LevArrNum] * GetTime() / MAP_INIT_ACCELERATION_TIME;
	}
	else
	if(bMapAccTime[LevArrNum] && GetTime() <= bMapAccTime[LevArrNum] + MAP_INIT_ACCELERATION_TIME)
	{
		speed = bMapMinSpeed[LevArrNum] +
		 (bMapMaxSpeed[LevArrNum]-bMapMinSpeed[LevArrNum]) * (GetTime()-MAP_INIT_ACCELERATION_TIME) / bMapAccTime[LevArrNum];
	}
	else
		speed = bMapMaxSpeed[LevArrNum];
	//
	if(MAP_ACCEL_TIME_AFTER_PAUSE && bWasPausedTime && GetTime()-bWasPausedTime < MAP_ACCEL_TIME_AFTER_PAUSE)
	{
		//разгон после паузы - уже посчитанную speed обрубаем
		speed = speed * (GetTime()-bWasPausedTime) / MAP_ACCEL_TIME_AFTER_PAUSE;
	}
	if(bCheatFly)
		speed = 1000;
	//
	static int PrevTime = 0;
	iff(1)
		PrevTime = GetTime();
	int iMapDY;
	iMapDY = - (GetTime()-PrevTime) * speed;
	y = y + iMapDY;
	//Log("dt = " + itoa(GetTime()-PrevTime) + ". iMapDY = " + itoa(iMapDY) + ". speed = " + itoa(speed) +
	//			". y = " + itoa(y/1000));
	//
	PrevTime = GetTime();
    //Log("y = " + itoa(y));
    static int PrevY = 0;
    int NewY; NewY = y/1000;
	SetPosition(ScreenX()/2, NewY);
	//
	if(NewY <= ScreenY()/2 || bCheatWin)
		bMapWin = true;
	//
	if(PlayerVehi)
	{
		if(PrevY!=0/* && !bMapWin*/)//2-е усл. - чтобы не прилипнуть в конце карты к верхней стенке
			Action(PlayerVehi, ACT_CHANGE_COOR, GetX(PlayerVehi), GetY(PlayerVehi)+(NewY-PrevY), GetZ(PlayerVehi));
	}
	PrevY = NewY;
	//
	if(bMapWin && (!PlayerVehi || GetY(PlayerVehi) <= -50) || bCheatWin)
	{
		iff(!giStatShown)
			ShowStatistics(STAT_TYPE_FLY);
		else
			ProcessStatistics();
		//
		iff(!giStatShown)
		{
			SaveCurData();
			gbMapImmediateExit = true;
			ShowMap(false);
		}
		return;
	}
	//
	int unit;
	if(PlayerVehi)
	{
		for( unit = FirstInBox(GetFIB_X1(), GetFIB_Y1(), GetFIB_X2(), GetFIB_Y2()); unit; unit = NextInBox() )
		{
			int vid = GetUnitVid(unit);
			if( vid == 881 && IntersectWithVehi(unit, true, true) )	//кристаллы
			{
				Action(unit, ANI_DEATH);
				gScoreTot += SCORES_FOR_CRYSTALL_FLY*10;
			}
			else
			if( (vid == 1222 || vid == 1230) && IntersectWithVehi(unit, true, true) )	//клетки
			{
				DeathOfFlower(unit, true);
				gScoreTot += SCORES_FOR_CRYSTALL_FLY*10;
			}
		}
	}
}


//------------------------------------------------------------------------------------------
FlyVehiTact()
{
	static int speed = 0;
	static int time = 0;
	iff(PlayerVehi)
	{
		Action(Action(PlayerVehi, ACT_GET_LINK), ACT_CHANGE_VID, 39);
		Action(Action(PlayerVehi, ACT_GET_LINK), ANI_HIT);
		ChangeVehiAnimation(ANI_STAND);
		speed = 0;
		time = GetTime();
		gbVehiFlying = true;
	}
	//
	int dt = GetTime() - time;
	time = GetTime();
	speed += dt * 400 / 1000;
	//
	Action(PlayerVehi, ACT_CHANGE_COOR, GetX(PlayerVehi), GetY(PlayerVehi)-dt*speed/1000, GetZ(PlayerVehi));
	if(GetY(PlayerVehi) - GetZ(PlayerVehi) < 0)
		return 0;
	//
	return 1;
}

