package com.gameproject.harbordefender;



import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;



import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaPlayer;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


public class GameView extends SurfaceView implements
		SurfaceHolder.Callback {

	//Obiekty sprajtów 
	private SpriteObject[] pier;
	private SpriteObject[] cannon;
	private SpriteObject ground;
	private SpriteObject castle;
	private SpriteObject[] boat;
	private SpriteObject[] bullets;
	
	private SpriteObject trash;
	private SpriteObject dock;
	private SpriteObject marker;
	private SpriteObject cannonrightsmall;
	private SpriteObject cannonleftsmall;
	private SpriteObject cannonupsmall;
	private SpriteObject cannondownsmall;
	
	private int TRASH = 1;
	private int CANNON_LEFT = 2;
	private int CANNON_RIGHT = 3;
	private int CANNON_UP = 4;
	private int CANNON_DOWN = 5;
	private int user_choice;
	
	
	private GameLogic mGameLogic;
	private ArrayBlockingQueue<InputObject> inputObjectPool;
	private int game_width;
	private int game_height;
	
	//Zmienne
	private Resources res;
	private int[] x_coords;
	private int[] y_coords;
	private int shooting_counter = 0;
	private int boat_count = 0;
	private int pier_count;
	private int cannon_count = 10;
	private int cursor_x;
	private int cursor_y;
	
	private boolean selection_changed;
	private boolean addboat;
	private int[] available_bullet;
	
	private Context context;

	private MediaPlayer mp;
	
	
	public GameView(Context con) {
		super(con);
		context = con;
		res = getResources();
		getHolder().addCallback(this);
		
		ground = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.ground), 480, 500);
		trash = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.trash), 50, 650);
		dock = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.dock), 0, 650);
		marker = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.marker), 50, 650);
		castle = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.castle), 890, 500);
		
		

		
		
		Bitmap bcannonupsmall = BitmapFactory.decodeResource(getResources(), R.drawable.cannonupsmall);
		int w = bcannonupsmall.getWidth();
		int h = bcannonupsmall.getHeight();
		Matrix mtx = new Matrix();
		mtx.postRotate(90);
		Bitmap bcannonrightsmall = Bitmap.createBitmap(bcannonupsmall, 0, 0, h, w, mtx, true);
		Bitmap bcannondownsmall = Bitmap.createBitmap(bcannonrightsmall, 0, 0, w, h, mtx, true);
		Bitmap bcannonleftsmall = Bitmap.createBitmap(bcannondownsmall, 0, 0 , h, w, mtx, true);
		cannonrightsmall = new SpriteObject(bcannonrightsmall, 110, 650);
		cannonleftsmall = new SpriteObject(bcannonleftsmall, 180, 650);
		cannondownsmall = new SpriteObject(bcannondownsmall, 240, 650);
		cannonupsmall = new SpriteObject(bcannonupsmall, 300, 650);
		
		
		
		available_bullet = new int[50];
		for(int i = 0; i < 50; i++){
			available_bullet[i] = i;
		}
		

		
		
		
		bullets = new SpriteObject[50];
		for(int i = 0; i < 50; i++){
			bullets[i] = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.bullet), 10, 10);
			bullets[i].setState(bullets[i].DEAD);
			available_bullet[i] = i;
		}
		
		

		
		mGameLogic = new GameLogic(getHolder(), this);
		createInputObjectPool();
			
		

		//sprajty falochronu 
		pier_count = res.getInteger(R.integer.blocknumber);	
		x_coords = res.getIntArray(R.array.x);
		y_coords = res.getIntArray(R.array.y);
		pier = new SpriteObject[pier_count];
		for(int i = 0; i < pier_count; i++){
			pier[i] = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.pier), x_coords[i], y_coords[i]);
		}
		
		//sprajty łodzi 
		boat = new SpriteObject[12];
		
		//sprajty dział 
		cannon = new SpriteObject[10];

		

		
		mp = MediaPlayer.create(context, R.raw.bounce);
		
		setFocusable(true);
	}

	private void createInputObjectPool() {
		inputObjectPool = new ArrayBlockingQueue<InputObject>(20);
		for (int i = 0; i < 20; i++) {
			inputObjectPool.add(new InputObject(inputObjectPool));
		}
	}

	

		@Override
		public boolean onTouchEvent(MotionEvent event) {
			try {
				int hist = event.getHistorySize();
				if (hist > 0) {
					for (int i = 0; i < hist; i++) {
						InputObject input = inputObjectPool.take();
						input.useEventHistory(event, i);
						mGameLogic.feedInput(input);
					}
				}
				InputObject input = inputObjectPool.take();
				input.useEvent(event);
				mGameLogic.feedInput(input);
			} catch (InterruptedException e) {
			}
			try {
				Thread.sleep(16);
			} catch (InterruptedException e) {
			}
			return true;
		}
		
		
		
		
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		mGameLogic.start();

	}
	
	
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		mp.release();
	}
	
	
	
	@Override
	public void onDraw(Canvas canvas) {
		Log.d("ONDRAW","SUPER");
		canvas.drawColor(Color.BLUE);
		ground.draw(canvas);
		
		//sterowanie użytkownika 
		dock.draw(canvas);
		marker.draw(canvas);
		trash.draw(canvas);
		cannonleftsmall.draw(canvas);
		cannonrightsmall.draw(canvas);
		cannondownsmall.draw(canvas);
		cannonupsmall.draw(canvas);
		
		
		
		for(int i = 0; i < pier_count; i++){
			pier[i].draw(canvas);
		}
		for(int i = 0; i < boat_count; i++){
			boat[i].draw(canvas);
		}
		for(int i = 0; i < cannon_count; i++){
			cannon[i].draw(canvas);
		}
		for(int i = 0; i < 50; i++){
			bullets[i].draw(canvas);
		}
		castle.draw(canvas);

	}
	
	
	
	

	public void update(int adj_mov) {

		for(int i = 0; i < boat_count; i++){
			if((int)boat[i].getX() > 950){
				boat[i].setMoveX(0);
				boat[i].setMoveY(3);
				boat[i].setBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.boatdown));
			}
		}
		
		Random random_boat = new Random();
		int check_boat = random_boat.nextInt(100);

		if(check_boat > 97 && boat_count < 12){
			int previous_boat = boat_count - 1;
			if(boat_count == 0 || boat[previous_boat].getX() > 150){
				boat[boat_count] = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.boat), 100, 150);
				boat[boat_count].setMoveX(3);
				boat_count++;
			}
		}
		
		for(int i = 0; i < boat_count; i++){
			if(boat[i].collide(castle)){
				reset();
			}
		}
		
		
		
		
		if(selection_changed){
			selection_changed = false;
			if(trash.cursor_selection(cursor_x, cursor_y)){
				user_choice = TRASH;
				marker.setX(50);
				addboat = false;
			}
			if(cannonrightsmall.cursor_selection(cursor_x, cursor_y)){
				user_choice = CANNON_RIGHT;
				marker.setX(110);
				addboat = true;
			}
			if(cannonleftsmall.cursor_selection(cursor_x, cursor_y)){
				user_choice = CANNON_LEFT;
				marker.setX(180);
				addboat = true;
			}
			if(cannondownsmall.cursor_selection(cursor_x, cursor_y)){
				user_choice = CANNON_DOWN;
				marker.setX(240);
				addboat = true;
			}
			if(cannonupsmall.cursor_selection(cursor_x, cursor_y)){
				user_choice = CANNON_UP;
				marker.setX(300);
				addboat = true;
			}
			else if(addboat){
				if(cannon_count < 10){
					for(int i = 0; i < pier_count; i++){
						if(pier[i].cursor_selection(cursor_x, cursor_y)){
							if(pier[i].getStacked() == false){
								switch(user_choice){
								case 2:
									cannon[cannon_count] = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.cannonleft), (int)pier[i].getX(), (int)pier[i].getY());
									cannon[cannon_count].setOrientation(cannon[cannon_count].LEFT);
									break;
								case 3:
									cannon[cannon_count] = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.cannonright), (int)pier[i].getX(), (int)pier[i].getY());
									cannon[cannon_count].setOrientation(cannon[cannon_count].RIGHT);
									break;
								case 4:
									cannon[cannon_count] = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.cannonup), (int)pier[i].getX(), (int)pier[i].getY());
									cannon[cannon_count].setOrientation(cannon[cannon_count].UP);
									break;
								case 5:
									cannon[cannon_count] = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.cannondown), (int)pier[i].getX(), (int)pier[i].getY());
									cannon[cannon_count].setOrientation(cannon[cannon_count].DOWN);
									break;
								}
								
								cannon_count++;
								pier[i].setStacked(true);
							}
							else if(pier[i].getStacked() == true){
								if(user_choice == 1){
									for(int u = 0; u < cannon_count; u++){
										if(cannon[u].getX() == pier[i].getX() && cannon[u].getY() == pier[i].getY()){
											cannon[u].setState(cannon[u].DEAD);
										}
									}
								}
							}

						}
					}
				}

			}
		}
		for(int f = 0; f < 50; f++){
			available_bullet[f] = 0;
		}
		int g = 0;
		for(int i = 0; i < 50; i++){
			if(bullets[i].getY() > 800 || bullets[i].getX() > 1280 || bullets[i].getY() < 0 || bullets[i].getX() < 0){
				bullets[i].setState(bullets[i].DEAD);


			}

			for(int b = 0; b < boat_count; b++){
				if(bullets[i].collide(boat[b])){
					boat[b].diminishHealth(1);
					bullets[i].setState(bullets[i].DEAD);
				}
			}
			bullets[i].update(adj_mov);
			if(bullets[i].getState() == bullets[i].DEAD){
				available_bullet[g] = i;
				g++;
			}
			
		}
		
		shooting_counter++;
		if(shooting_counter >= 50){
			shooting_counter = 0;
			int round = 0;
			for(int i = 0; i < cannon_count; i++){
				if(cannon[i].getOrientation() == cannon[i].LEFT){
					int x = (int)(cannon[i].getX());
					int y = (int)(cannon[i].getY() + cannon[i].getBitmap().getHeight()/2);
					createBullet(x,y,cannon[i].LEFT, round);
					round++;
				}
				if(cannon[i].getOrientation() == cannon[i].RIGHT){
					int x = (int)(cannon[i].getX() + cannon[i].getBitmap().getWidth());
					int y = (int)(cannon[i].getY() + cannon[i].getBitmap().getHeight()/2);
					createBullet(x,y,cannon[i].RIGHT, round);
					round++;
				}
				if(cannon[i].getOrientation() == cannon[i].UP){
					int x = (int)(cannon[i].getX() + cannon[i].getBitmap().getWidth()/2);
					int y = (int)(cannon[i].getY());
					createBullet(x,y,cannon[i].UP, round);
					round++;
				}
				if(cannon[i].getOrientation() == cannon[i].DOWN){
					int x = (int)(cannon[i].getX() + cannon[i].getBitmap().getWidth()/2);
					int y = (int)(cannon[i].getY() + cannon[i].getBitmap().getHeight());
					createBullet(x,y,cannon[i].DOWN, round);
					round++;
				}
			}
		}
		

		
		castle.update(adj_mov);
		ground.update(adj_mov);
		for(int i = 0; i < boat_count; i++){
			boat[i].update(adj_mov);
		}
		
		

	}
	
	
	



	public void processMotionEvent(InputObject input){
		selection_changed = true;
		cursor_x = input.x;
		cursor_y = input.y;

	}
	
	public void processKeyEvent(InputObject input){

	}

	public void processOrientationEvent(float orientation[]){
		
		float roll = orientation[2];
		if (roll < -40) {
			//sprite.setMoveX(2);
		} else if (roll > 40) {
			//sprite.setMoveX(-2);
		}
		
	}


	private void reset(){
		for(int i = 0; i < boat_count; i++){
			boat[i].setState(boat[i].DEAD);
		}
		boat_count = 0;
		
	}
	private void createBullet(int x, int y, int direction, int r){
		if(r >= 0){
			int index = available_bullet[r];
			if(direction == bullets[available_bullet[r]].RIGHT){
				bullets[index].setMoveX(10);
				bullets[index].setMoveY(0);
				bullets[index].setX(x);
				bullets[index].setY(y);
				bullets[index].setState(bullets[index].ALIVE);
			}
			if(direction == bullets[available_bullet[r]].LEFT){
				bullets[index].setMoveX(-10);
				bullets[index].setMoveY(0);
				bullets[index].setX(x);
				bullets[index].setY(y);
				bullets[index].setState(bullets[index].ALIVE);
			}
			if(direction == bullets[available_bullet[r]].UP){
				bullets[index].setMoveY(-10);
				bullets[index].setMoveX(0);
				bullets[index].setX(x);
				bullets[index].setY(y);
				bullets[index].setState(bullets[index].ALIVE);
			}
			if(direction == bullets[available_bullet[r]].DOWN){
				bullets[index].setMoveY(10);
				bullets[index].setMoveX(0);
				bullets[index].setX(x);
				bullets[index].setY(y);
				bullets[index].setState(bullets[index].ALIVE);
			}
		}

		
	}
	

	
}
