package com.mygdx.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.Input.Keys;
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;

public class Pacman extends ApplicationAdapter {
	SpriteBatch batch;
	Texture sprites;
	TextureRegion pacmanTxt[][]=new TextureRegion[4][3];
	TextureRegion ghostsTxt[][][]= new TextureRegion[4][4][2];
	TextureRegion characters[]=new TextureRegion[44];
	Animation pacmanAnim[] = new Animation [4];
	Animation ghostsAnim[][] = new Animation [4][4];
	float ti=0;
	public int extX=0,extY=0;
	Texture world;
	Actor pacman;
	Actor ghosts[] = new Actor[4];
	int worldDesc[][];
	public int w,h;
	
	public int getTileFromX(int x){
			return (x-extX)/8;}
	
	public int getTileFromY(int y){
			int temp=(y-extY)/8;
			return h-1-temp;}
	
	public class Actor //HERE IS THE NESTED CLASS
	{
		public static final int LEFT=0,RIGHT=2,UP=1,DOWN=3;
		public int x,y,d,s;
		Animation pose[];
		public Actor (int x,int y,int d,int s,Animation [] pose)
		{
			this.x=x;
			this.y=y;
			this.d=d;
			this.s=s;
			this.pose=pose;
		}
		public Actor (Animation[] pose)
		{
			this.x=0;
			this.y=0;
			this.d=0;
			this.s=1;
			this.pose=pose;
		}
		public Actor (int s,Animation[] pose)
		{
			this.x=0;
			this.y=0;
			this.d=0;
			this.s=s;
			this.pose=pose;
		}
		public int getX(){
			return x;}
		public int getY(){
			return y;}
		public int getRealX(){
			return x-7;}
		public int getRealY(){
			return y-7;}
		public Animation getMovingAnimation(){
			return pose[d];}
		public Animation getAnimation(int x){
			return pose[x];}
		public int getTileX(){
			return (x-extX)/8;}
		public int getTileY(){
			int temp=(y-extY)/8;
			return h-1-temp;}
		public void goLeft(){
			d=0;}
		public void goRight(){
			d=2;}
		public void goUp(){
			d=1;}
		public void goDown(){
			d=3;}
		public void walk()
		{
			switch (this.d)
			{
				case Actor.LEFT:
				{
					int valX,actX,actY,newX;
					actX=this.getTileX();
					actY=this.getTileY();
					newX=getTileFromX(this.x-this.s);
					for (valX=actX;valX>=newX;valX--)
					{
						if (!isAValidTile(valX,actY))
						{
							valX++;
							break;
						}
					}
					this.x=Math.max(this.x-this.s, valX*8+extX);
					break;
				}
				case Actor.RIGHT:
				{
					int valX,actX,actY,newX;
					actX=this.getTileX();
					actY=this.getTileY();
					newX=getTileFromX(this.x+this.s);
					for (valX=actX;valX<=newX;valX++)
					{
						if (!isAValidTile(valX,actY))
						{
							valX--;
							break;
						}
					}
					this.x=Math.min(this.x+this.s, (valX+1)*8-1+extX);
					break;
				}
			}
		}
	}
	
	public boolean isAValidTile(int x,int y)
	{
		if ((x>=0) && (y>=0) && (x<w) && (y<h))
			return worldDesc[x][y]!=1;
		return false;
	}
	public void setAnimations()
	{
		sprites = new Texture ("sprites.png");
		int corr[] = {2,0,3,1};
		int corr2[] = {2,0,1};
		int i,j,k;
		for (i=0;i<4;i++)
			for (j=0;j<3;j++)
				pacmanTxt[i][j] = new TextureRegion(sprites,16*corr2[j],16*corr[i],16,16);
		for (i=0;i<4;i++)
		{
			pacmanAnim[i]=new Animation ((float) (1.0/15.0),pacmanTxt[i]);
			pacmanAnim[i].setPlayMode(Animation.PlayMode.LOOP_PINGPONG);
		}
		pacman = new Actor (13*8+3+4,7*8+3,0,3,pacmanAnim);
		for (i=0;i<4;i++)
			for (j=0;j<4;j++)
				for (k=0;k<2;k++)
				   ghostsTxt[i][j][k]=new TextureRegion(sprites,16*2*i+16*k,16*4+16*corr[j],16,16);
		for (i=0;i<4;i++)
			for (j=0;j<4;j++)
			{
				ghostsAnim[i][j]=new Animation((float) (2.0/15.0),ghostsTxt[i][j]);
				ghostsAnim[i][j].setPlayMode(Animation.PlayMode.LOOP);
			}
		for (i=0;i<4;i++)
			ghosts[i] = new Actor (3,ghostsAnim[i]);
		j=0;
		for (i=0;i<18;i++)
		{
			characters[j]=new TextureRegion(sprites,8*16+i*8,0,8,8);
			j++;
		}
		for (i=0;i<18;i++)
		{
			characters[j]=new TextureRegion(sprites,8*16+i*8,8,8,8);
			j++;
		}
		for (i=0;i<5;i++)
		{
			characters[j]=new TextureRegion(sprites,8*16+i*8,16,8,8);
			j++;
		}
		for (i=0;i<2;i++)
		{
			characters[j]=new TextureRegion(sprites,8*16+18*8,i*8,8,8);
			j++;
		}
		characters[43]=new TextureRegion(sprites,0,0,1,1);
	}
	public void setBackground()
	{
		try
		{
			Scanner in = new Scanner (new File ("world.txt"));
			h = in.nextInt();
			w = in.nextInt();
			int i,j;
			worldDesc=new int[h][w];
			for (i=0;i<h;i++)
			{
				for (j=0;j<w;j++)
				{
					worldDesc[i][j]=in.nextInt();
				}
			}
			world = new Texture ("map.png");
		}
		catch (FileNotFoundException ex)
		{
			
		}
	}
	public void write(String cad,int x,int y)
	{
		int i,p;
		cad=cad.toUpperCase();
		for (i=0;i<cad.length();i++)
		{
			p=43;
			if ((cad.charAt(i)<='9')&&(cad.charAt(i)>='0'))
				p=(int)cad.charAt(i)-(int)'0';
			if ((cad.charAt(i)<='Z')&&(cad.charAt(i)>='A'))
				p=(int)cad.charAt(i)-(int)'A'+10;
			if (cad.charAt(i)=='.')
				p=36;
			if (cad.charAt(i)=='!')
				p=37;
			batch.draw(characters[p],x+i*8,y);
		}
		
	}
        
        
        @Override
	public void create () {
		batch = new SpriteBatch();
                setBackground();
                setAnimations();
	}

	@Override
	public void render () {
                ti+=Gdx.graphics.getDeltaTime();
                pacman.walk();
		Gdx.gl.glClearColor(0, 0, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
                
                if (Gdx.input.isKeyJustPressed(Keys.DPAD_LEFT))
                {
                    pacman.goLeft();
                    for (int i =0;i<4;i++)
                        ghosts[i].goLeft();
                }
                if (Gdx.input.isKeyJustPressed(Keys.DPAD_RIGHT))
                {
                    pacman.goRight();
                    for (int i =0;i<4;i++)
                        ghosts[i].goRight();
                }
                if (Gdx.input.isKeyJustPressed(Keys.DPAD_UP))
                {
                    pacman.goUp();
                    for (int i =0;i<4;i++)
                        ghosts[i].goUp();
                }
                if (Gdx.input.isKeyJustPressed(Keys.DPAD_DOWN))
                {
                    pacman.goDown();
                    for (int i =0;i<4;i++)
                        ghosts[i].goDown();
                }
                
                int i;
		batch.begin();
		//batch.draw(img, 0, 0);
                batch.draw(world,0,0);
                batch.draw(pacman.getMovingAnimation().getKeyFrame(ti),pacman.getRealX(),pacman.getRealY());
                for (i=0;i<4;i++)
                    batch.draw(ghosts[i].getMovingAnimation().getKeyFrame(ti),120+i*20,100);
                write("alto: " + h,300,300+8);
                write("tile actual: "+pacman.getTileX()+ " , " + pacman.getTileY(),300,300);
                write("coordenada actual: "+pacman.x+ " , " + pacman.y,300,300-8);
		batch.end();
                
	}
}
