package com.aerodroidrace.Game;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.audio.music.Music;
import org.anddev.andengine.audio.music.MusicFactory;
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.handler.timer.ITimerCallback;
import org.anddev.andengine.engine.handler.timer.TimerHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.FillResolutionPolicy;
import org.anddev.andengine.entity.modifier.MoveYModifier;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.menu.MenuScene;
import org.anddev.andengine.entity.scene.menu.MenuScene.IOnMenuItemClickListener;
import org.anddev.andengine.entity.scene.menu.item.IMenuItem;
import org.anddev.andengine.entity.scene.menu.item.TextMenuItem;
import org.anddev.andengine.entity.scene.menu.item.decorator.ColorMenuItemDecorator;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.text.ChangeableText;
import org.anddev.andengine.entity.text.Text;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.font.Font;
import org.anddev.andengine.opengl.font.FontFactory;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.Debug;

import com.aerodroidrace.FinDeJuego;
import com.aerodroidrace.Menu;
import com.aerodroidrace.Sprites.Avion;
import com.aerodroidrace.Sprites.Cono;
import com.aerodroidrace.Sprites.SpritePuntos;

import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.KeyEvent;
import android.view.MotionEvent;


public class PantallaJuego extends BaseGameActivity implements SensorEventListener, IOnMenuItemClickListener{

	//Ancho y alto de la pantalla donde va a aparecer nuestro juego
	private static final float CAMERA_WIDTH = 1024;
	private static final float CAMERA_HEIGHT = 512;
	
	private Camera mCamera1;
	private BitmapTextureAtlas mBitmapTextureAtlas1, mBitmapTextureAtlas2, mBitmapTextureAtlas3, mBitmapTextureAtlas4,  texturaFuente;
	private TextureRegion mFaceTextureRegion1, mFaceTextureRegion2, barra, con; 
	public static Music musica1;
    private Sprite picture1;
    private Avion av;
    private LinkedList<Cono> conosañadidos;
	private LinkedList<Cono> conos;
	private LinkedList<SpritePuntos> lsprites;
	private LinkedList<SpritePuntos> lspritesadd;
    private MenuScene menuEscena;
    private Font fuente;
    private Scene scene;
    private ScrollBackground Scroll;
    private int puntuacionN;
    private ChangeableText puntuacion;
    
    private SharedPreferences Puntuacion1;
    private SharedPreferences Puntuacion2;
    private SharedPreferences Puntuacion3;
    private SharedPreferences Puntuacion4;
    private SharedPreferences Puntuacion5;
    private SharedPreferences estadosonido;
    
    protected static final int MENU_REINICIAR = 0;
	protected static final int MENU_SALIR = MENU_REINICIAR + 1;
	protected static final int MENU_CONTINUAR = MENU_SALIR + 1;
	protected static final int MENU_SOUND = MENU_CONTINUAR + 1;
    
    private SensorManager sensorManager; 
    private float accellerometerSpeedX;
    private float accellerometerSpeedY;
    private float sX, sY;
    private Boolean b = true;
    private Boolean swf = false;
    private Boolean music;
    
    

    public void onLoadComplete() {
		
	}
    
   
    //LLamado cuando el motor del juego es cargado en nuestra actividad
	public Engine onLoadEngine() {
		
		//Aquí inicializamos la cámara
		this.mCamera1 = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		
		//Aquí es donde creamos el motor a devolver
		final EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE,
				new FillResolutionPolicy(), this.mCamera1).setNeedsMusic(true);
		
        engineOptions.getTouchOptions().setRunOnUpdateThread(true);
        
        final Engine engine = new Engine(engineOptions);
        
        return engine;
        
	}

	public void onLoadResources() {
		
		this.mBitmapTextureAtlas1 = new BitmapTextureAtlas(1024, 1024, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mBitmapTextureAtlas2 = new BitmapTextureAtlas(128, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mBitmapTextureAtlas3 = new BitmapTextureAtlas(128, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mBitmapTextureAtlas4 = new BitmapTextureAtlas(256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		
		
		
		
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("graficos/");
		
		this.mFaceTextureRegion1 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas1, this, "fondoagua.png", 0, 0);
		this.mFaceTextureRegion2 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas2, this, "plane.png", 0, 0);
		this.con = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas3, this, "Cono.png", 0, 0);
		this.barra = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas4, this, "spritepuntos.png", 0, 0);
		
		
		
		
		this.texturaFuente = new BitmapTextureAtlas(256, 256,
				TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		
		FontFactory.setAssetBasePath("fuente/");
		this.fuente = FontFactory.createFromAsset(this.texturaFuente, this,
				"Droid.ttf", 40, true, Color.WHITE);
		
		this.mEngine.getFontManager().loadFont(this.fuente);
		
		
		
		//Aquí cargamos la música
		MusicFactory.setAssetBasePath("sonidos/");
		try{

			musica1 = MusicFactory.createMusicFromAsset(this.mEngine.getMusicManager(), this, "sonidoavioneta.mp3");
			musica1.setLooping(true);
			
		} catch (final IOException e){
			
			Debug.e(e);
		}
		
		
		
		this.mEngine.getTextureManager().loadTextures(this.mBitmapTextureAtlas1, this.mBitmapTextureAtlas2, 
				this.mBitmapTextureAtlas4, this.mBitmapTextureAtlas3, this.texturaFuente);
		
	}

	public Scene onLoadScene() {
		
		sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), sensorManager.SENSOR_DELAY_GAME);
		
		this.mEngine.registerUpdateHandler(new FPSLogger());
		this.menuEscena = this.createMenuScene();
		final Scene scene = new Scene();
		
		puntuacionN = 0;
		Text score= new Text(3,3,this.fuente,"Puntos:");
		this.mEngine.registerUpdateHandler(new IUpdateHandler() {
            public void onUpdate(float pSecondsElapsed) {
                updateSpritePosition();
            }
 
            public void reset() {
                // TODO Auto-generated method stub
            }
        });
		
		scene.attachChild(score);
		puntuacion = new ChangeableText(150,3,this.fuente,String.valueOf(puntuacionN),9);
		scene.attachChild(puntuacion);
		
		
		estadosonido = getSharedPreferences("sonido", MODE_PRIVATE);
		SharedPreferences.Editor admin = estadosonido.edit();
		music = estadosonido.getBoolean("sonido", true);
		if(! music){
 		  musica1.stop();
 	    }else{
 	      musica1.play();	
 	    }
	
		
		conosañadidos = new LinkedList<Cono>();
		conos = new LinkedList<Cono>();
		lsprites = new LinkedList<SpritePuntos>(); 
		lspritesadd = new LinkedList<SpritePuntos>();
		
        av = new Avion(512, 440, this.mFaceTextureRegion2);
        
        picture1 = new Sprite(0, 0, this.mFaceTextureRegion1){
        	
        	public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
					final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
				if (pSceneTouchEvent.getAction() == MotionEvent.ACTION_DOWN) {
					
				} else if (pSceneTouchEvent.getAction() == MotionEvent.ACTION_UP) {
					
					musica1.pause();
					
					PantallaJuego.this.accellerometerSpeedX = 0;
					PantallaJuego.this.accellerometerSpeedY = 0;
					
					PantallaJuego.this.unregister();
					
					scene.setChildScene(menuEscena, false, true, true);
					
					return true;
					
					}
				return true;
			} 
        };
        
       Scroll = new ScrollBackground(picture1, 150);
		
		
		scene.setBackground(Scroll);
		
		scene.registerTouchArea(picture1);
		
		scene.registerUpdateHandler(new IUpdateHandler() {
			

			
			public void reset() {
			}
 
			
			public void onUpdate(float pSecondsElapsed) {
				
				if(!swf){
					conos.addAll(conosañadidos);
					lsprites.addAll(lspritesadd);
					Iterator<Cono> targets = conos.iterator();
					Iterator<SpritePuntos> targets1 = lsprites.iterator();
					Cono _target;
					SpritePuntos _target1;
					boolean chocar=false;
					
					while (targets.hasNext() && !chocar) {
						_target = targets.next();
						
						if (_target.collidesWith(av)) {
							
							
							
							chocar=true;
							musica1.stop();
						
							Puntuacion5 = getSharedPreferences("puntuacion5",MODE_PRIVATE);
						
											
							SharedPreferences.Editor admin = Puntuacion5.edit();
							int pts;
							pts=Puntuacion5.getInt("puntos", 0);
						
							if(pts<puntuacionN){

								actualizaPuntuaciones(puntuacionN);
							
							}						
						
						
							swf=true;			
							mEngine.stop();
							PantallaJuego.this.runOnUiThread(new Runnable() {
								
								public void run() {
									
									Intent a = new Intent(PantallaJuego.this, FinDeJuego.class);
									PantallaJuego.this.finish();
									PantallaJuego.this.startActivity(a);
									
								}
							});
					
						
						
						
						}
						while (targets1.hasNext()){
							_target1 = targets1.next();
							
							if((av.collidesWith(_target1)) && !chocar){
								puntuacionN = puntuacionN + 5;
								puntuacion.setText(String.valueOf(puntuacionN));
								removeSpriteBarra(_target1, targets1);
								scene.detachChild(_target1);	
						
						
							}
						}
						}
					
						conos.addAll(conosañadidos);
						conosañadidos.clear();
						lsprites.addAll(lspritesadd);
						lspritesadd.clear();
					}}});
        
        scene.registerUpdateHandler(new TimerHandler(3f,
				new ITimerCallback() {
			
			public void onTimePassed(final TimerHandler pTimerHandler) {
				pTimerHandler.reset();
				Random rand = new Random();
	
				int minX = 5;
				int x = rand.nextInt(807) + minX;
				
				Cono target=null;
				Cono target2=null;
				SpritePuntos sp = null;
				
				int ancho = x + 170;
				int anchosprite = x + 39;
				
				target = new Cono(x, 0, PantallaJuego.this.con.deepCopy());
				target2 = new Cono(ancho, 0, PantallaJuego.this.con.deepCopy());
				sp = new SpritePuntos(anchosprite, 0, PantallaJuego.this.barra.deepCopy());
				
				scene.attachChild(target);
				scene.attachChild(target2);
				scene.attachChild(sp);
				
				int Duration = 8;
				MoveYModifier mod = new MoveYModifier(Duration, -target.getHeight(), 760);
				MoveYModifier mod2 = new MoveYModifier(Duration, -target2.getHeight(), 760);
				MoveYModifier mod3 = new MoveYModifier(Duration, sp.getHeight(), 760);
                
				target.registerEntityModifier(mod.deepCopy());
				conosañadidos.add(target);
				target2.registerEntityModifier(mod2.deepCopy());
				conosañadidos.add(target2);
				sp.registerEntityModifier(mod3.deepCopy());
				lspritesadd.add(sp);
				
				}
			}
		));
        
        
		scene.attachChild(av);
		
		return scene;
		
	}
	
	public void unregister() {
		
		      sensorManager.unregisterListener(this);
	   }
	
	public void register() {
		
		sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), sensorManager.SENSOR_DELAY_GAME);
 }

	

	public void onAccuracyChanged(Sensor arg0, int arg1) {
		
	}
	
	

	public void onSensorChanged(SensorEvent event) {
		
		synchronized (this) {
            switch (event.sensor.getType()) {
                case Sensor.TYPE_ACCELEROMETER:
                    accellerometerSpeedX = (int)event.values[1];
                    accellerometerSpeedY = (int)event.values[0];
                	
                    break;
            }
        }
		
	}
	
	private void updateSpritePosition() {
        if ((accellerometerSpeedX != 0) || (accellerometerSpeedY != 0)) {
           
            int tL = 0;
            int lL = 0;
            float rL = CAMERA_WIDTH - av.getWidth();
            float bL = CAMERA_HEIGHT - av.getHeight();
            
            
            while (sX == 0 && sY == 0 && b){
            sX = 512;
            sY = 440;
            b = false;
            }
            
            if (sX >= lL) sX += accellerometerSpeedX; else sX = lL;
            if (sX <= rL) sX += accellerometerSpeedX; else sX = rL;
            if (sY >= tL) sY += accellerometerSpeedY; else sY = tL;
            if (sY <= bL) sY += accellerometerSpeedY; else sY = bL;
 
            
            if (sX < lL)      sX = lL;
            else if (sX > rL) sX = rL;
            if (sY < tL)      sY = tL;
            else if (sY > bL) sY = bL;
 
            av.setPosition(sX, sY);
        }
    }
	
	public void removeSpriteBarra(final SpritePuntos _sprite, Iterator<SpritePuntos> it) {
		runOnUpdateThread(new Runnable() {

			
			public void run() {
				
			}
		});
		it.remove();
	}
	
	public void removeSpriteCono(final Cono _sprite, Iterator<Cono> it) {
		runOnUpdateThread(new Runnable() {

			
			public void run() {
				
			}
		});
		it.remove();
	}
	
	private void actualizaPuntuaciones(int puntuacion){
		
		Puntuacion1 = getSharedPreferences("puntuacion1",MODE_PRIVATE);
		Puntuacion2 = getSharedPreferences("puntuacion2",MODE_PRIVATE);
		Puntuacion3 = getSharedPreferences("puntuacion3",MODE_PRIVATE);
		Puntuacion4 = getSharedPreferences("puntuacion4",MODE_PRIVATE);
		Puntuacion5 = getSharedPreferences("puntuacion5",MODE_PRIVATE);
		SharedPreferences.Editor admin1 = Puntuacion1.edit();
		SharedPreferences.Editor admin2 = Puntuacion2.edit();
		SharedPreferences.Editor admin3 = Puntuacion3.edit();
		SharedPreferences.Editor admin4 = Puntuacion4.edit();
		SharedPreferences.Editor admin5 = Puntuacion5.edit();
		int pt1 = Puntuacion1.getInt("puntos", 0);
		String nm1 = Puntuacion1.getString("nombre", null);
		int pt2 = Puntuacion2.getInt("puntos", 0);
		String nm2 = Puntuacion2.getString("nombre", null);
		int pt3 = Puntuacion3.getInt("puntos", 0);
		String nm3 = Puntuacion3.getString("nombre", null);
		int pt4 = Puntuacion4.getInt("puntos", 0);
		String nm4 = Puntuacion4.getString("nombre", null);
		int pt5 = Puntuacion5.getInt("puntos", 0);
		String nm5 = Puntuacion5.getString("nombre", null);
		
		int[] aux = {pt1, pt2, pt3, pt4, pt5};
		
		for (int i = 0; i < 5; i++){
			
			if(aux[i] < puntuacion){
				
				for(int j = 4; j > i; j--)
					aux[j]=aux[j-1];
				
				aux[i]=puntuacion;
				break;	
			}		
		}
		
		admin1.putInt("puntos", aux[0]);
		admin1.commit();
		admin2.putInt("puntos", aux[1]);
		admin2.commit();
		admin3.putInt("puntos", aux[2]);
		admin3.commit();
		admin4.putInt("puntos", aux[3]);
		admin4.commit();
		admin5.putInt("puntos", aux[4]);
		admin5.commit();
				
	}
	
	
	
	public boolean onKeyDown(final int pKeyCode, final KeyEvent pEvent) {
		if(pKeyCode == KeyEvent.KEYCODE_MENU && pEvent.getAction() == KeyEvent.ACTION_DOWN) {
		
			return true;
		}
		if(pKeyCode == KeyEvent.KEYCODE_BACK && pEvent.getAction() == KeyEvent.ACTION_DOWN){
			
			return true;
		}
		if(pKeyCode == KeyEvent.KEYCODE_SEARCH && pEvent.getAction() == KeyEvent.ACTION_DOWN){
			
			return true;
		}
		else {
			return super.onKeyDown(pKeyCode, pEvent);
		}
	}
	
	public void onPauseGame(){
		
		musica1.stop();
		this.finish();
		super.onPause();
			
	}
	
	public boolean onMenuItemClicked(final MenuScene pMenuScene, final IMenuItem pMenuItem, final float pMenuItemLocalX, final float pMenuItemLocalY) {
		switch(pMenuItem.getID()) {
			case MENU_REINICIAR:
				
				Intent it = new Intent(PantallaJuego.this,PantallaJuego.class);
				PantallaJuego.this.finish();
				PantallaJuego.this.startActivity(it);
				
				return true;
			case MENU_SALIR:
				
				Puntuacion5 = getSharedPreferences("puntuacion5",MODE_PRIVATE);
				SharedPreferences.Editor admin = Puntuacion5.edit();
				int pts;
				pts=Puntuacion5.getInt("puntos", 0);
			
				if(pts<puntuacionN){

					actualizaPuntuaciones(puntuacionN);
				
				}	
				Intent b = new Intent(PantallaJuego.this,Menu.class);
				PantallaJuego.this.finish();
				PantallaJuego.this.startActivity(b);
				
				return true;
				
			case MENU_CONTINUAR:
				
				this.register();
				this.menuEscena.back();
				musica1.play();
				return true;
				
			
				
				
			default:
				return false;
		}
	}
	
	protected MenuScene createMenuScene() {
		
		
		final MenuScene menuScene = new MenuScene(this.mCamera1);
		
		final IMenuItem continueMenuItem = new ColorMenuItemDecorator(new TextMenuItem(MENU_CONTINUAR, this.fuente, "Continuar"), 1.0f,0.0f,0.0f, 1.0f,1.0f,1.0f);
		continueMenuItem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		menuScene.addMenuItem(continueMenuItem);
		
		final IMenuItem resetMenuItem = new ColorMenuItemDecorator(new TextMenuItem(MENU_REINICIAR, this.fuente, "Reiniciar"), 1.0f,0.0f,0.0f, 1.0f,1.0f,1.0f);
		resetMenuItem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		menuScene.addMenuItem(resetMenuItem);

		final IMenuItem quitMenuItem = new ColorMenuItemDecorator(new TextMenuItem(MENU_SALIR, this.fuente, "Salir"), 1.0f,0.0f,0.0f, 1.0f,1.0f,1.0f);
		quitMenuItem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		menuScene.addMenuItem(quitMenuItem);
		
		menuScene.buildAnimations();

		menuScene.setBackgroundEnabled(false);

		menuScene.setOnMenuItemClickListener(this);
		return menuScene;
	}
	

}

