package com.darkdimension.ritle_run;

import android.graphics.Canvas;
import android.graphics.Paint;

public class Character extends DiPoint
{
    private enum State
    {
        RUNNING,
        FALLING,
        JUMPING
    }

    //Animation
    private DiAnimation animation = new DiAnimation(24);
    private int aJump = 15;

	//AirJump
	private DiPoint pAirJump = new DiPoint(40);
    private DiAnimation aAirJump = new DiAnimation(15);
	private Paint invisJump = new Paint();
	private boolean canAirJump = true;

    //Character State
    private State state = State.FALLING;

    //Frame
    private int stateFrame = 6;
    private int currentFrame = 0;

    //Shield & land
    private boolean isShielded = false;
    private boolean justLanded = false;
	public int walkingOn = 0;

	//Magic Circle
    private int circleSize = 0, visualCircleSize = 0;
    private Paint circlePaint = new Paint();

    public Character()
    {
        super(28);

		pAirJump.setRight(0);

		if (DiPoint.firstChar) circlePaint.setARGB(50, 10, 10, 10);
		else circlePaint.setARGB(75, 113, 40, 167);
        circlePaint.setAntiAlias(true);

        animation.start();
    }

    public boolean update(int groundLevel, int jumpHeight)
    {
        if (justLanded)
            justLanded = false;

        //Update state
        switch (state)
        {
            case RUNNING:
                //If running off edge, fall down
                if (y +image[frame].getHeight() != groundLevel)
                {
                    state = State.FALLING;
                    stateFrame = 8;
                    currentFrame = 0;
                }
                break;
            case FALLING:
                //Apply gravity
                y += jumpHeight /12;

                //If fell on ground
                if (y +image[frame].getHeight() >= groundLevel
                &&  y +image[frame].getHeight() <  groundLevel +jumpHeight /12)
                {
                    //Set character on top of ground
                    y = groundLevel -image[frame].getHeight();

                    //Start Walking
                    state = State.RUNNING;
                    stateFrame = 0;
                    currentFrame = 0;

                    justLanded = true;
                    canAirJump = true;
                }
                break;
            case JUMPING:
                //Keep jumping
                y -= jumpHeight /15;

                //If animation reaches end
                if (aJump > 15)
                {
                    //Start Falling
                    state = State.FALLING;
                    stateFrame = 8;
                    currentFrame = 0;
                }

                //Advance animation
                aJump++;
                break;
        }

        //Animation
        if (animation.update())
            if (animation.getCounter() %4 == 0)
            {
                currentFrame++;
                if (currentFrame >= 8
                || (stateFrame != 0 && currentFrame >= 1)) currentFrame = 0;

                if (animation.isAtEnd())
                    animation.startFromBeginning();

                if ((currentFrame == 1 ||  currentFrame == 5)
                &&  stateFrame == 0)
                    GameSurface.playSound(0);
            }

        if (visualCircleSize > circleSize) visualCircleSize -= 4 *GameSurface.density;
        else
        if (visualCircleSize < circleSize) visualCircleSize += 4 *GameSurface.density;

		if (aAirJump.update())
			invisJump.setAlpha(aAirJump.getDistance(255));

		pAirJump.changeX(-(int)(4 *GameSurface.density));

        return true;
    }

    @Override
    public void draw(Canvas canvas, Paint paint)
    {
		pAirJump.draw(canvas, invisJump);

        canvas.drawCircle(this.getCenterX(), this.getCenterY(), visualCircleSize, circlePaint);

		if (isShielded)
			canvas.drawBitmap(image[39], x, y, paint);

        canvas.drawBitmap(image[frame +stateFrame +currentFrame], x, y, paint);

        if (isShielded)
			canvas.drawBitmap(image[38], x, y, paint);
    }

	public void drawSimple(Canvas canvas, Paint paint) {canvas.drawBitmap(image[frame +currentFrame], x, y, paint);}

    //Actions
    public void jump()
    {
        if (aJump > 5)
            if (canAirJump || circleSize > 0)
            {
                //Use Mana
                if (!canAirJump) circleSize -= 36 *GameSurface.density;
                else
                    //Waste Air Jump
                    if (state == State.FALLING || state == State.JUMPING)
					{
						canAirJump = false;
						pAirJump.setCenterY(getBottom());
						pAirJump.setCenterX(getCenterX());
						aAirJump.startFromEnd();
					}

                //Jump Animation
                state = State.JUMPING;
                stateFrame = 9;
                currentFrame = 0;
                aJump = 0;

                //Sound
                GameSurface.playSound(1);
            }
    }

	public boolean animate()
	{
		//Animation
		if (animation.update())
		if (animation.getCounter() %4 == 0)
		{
			currentFrame++;
			if (currentFrame >= 8) currentFrame = 0;

			if (animation.isAtEnd())
				animation.startFromBeginning();

			return true;
		}

		return false;
	}

    public void giveShield() {isShielded = true;}
    public void loseShield() {isShielded = false;}
    public boolean hasShield() {return isShielded;}

    public void addManaLevel()
	{
		//If circleSize smaller than max size
		if (circleSize <  108 *GameSurface.density)
		{
			//Make circle bigger
			circleSize += 36 *GameSurface.density;
			GameSurface.playSound(3);
		}
		//circleSize greater or equal to max size
		else
		{
			//Remove circle
			circleSize = 0;
			GameSurface.playSound(4);
		}
	}


    public void loseMana() {circleSize = 0;}
    public boolean hasMana() {return circleSize > 0;}

    public boolean justLanded() {return justLanded;}

	public int[] getSquare()
	{
		int[] returner = new int[4];

		returner[0] = x +image[frame].getWidth () *3/6;
		returner[1] = y +image[frame].getHeight() *3/6;
		returner[2] = x +image[frame].getWidth () *4/6;
		returner[3] = y +image[frame].getHeight() *4/6;

		return returner;
	}
}