package MyCanvas.GameCanvas;


import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.media.j3d.Appearance;
import javax.media.j3d.Background;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.GeometryArray;
import javax.media.j3d.ImageComponent2D;
import javax.media.j3d.Material;
import javax.media.j3d.Node;
import javax.media.j3d.PolygonAttributes;
import javax.media.j3d.QuadArray;
import javax.media.j3d.Shape3D;
import javax.media.j3d.TextureAttributes;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.TexCoord2f;

import MyCanvas.ClearCanvas.ClearCanvas;
import MyCanvas.EndingCanvas.EndingCanvas;
import MyCanvas.KaisetsuCanvas.KaisetsuCanvas;
import MyCanvas.StartCanvas.StartCanvas;
import MyMain.CameraPointingGame;

import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.picking.PickCanvas;
import com.sun.j3d.utils.picking.PickResult;
import com.sun.j3d.utils.picking.PickTool;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class GameCanvas{

	private SimpleUniverse simpleU;
	private BoundingSphere bounds = new BoundingSphere(new Point3d(), 10.0);
	public Canvas3D canvas;
	public PickCanvas cnvs = null;
	// public Canvas canvasClearGame;

	public ClearCanvas canvasClearGame;
	public StartCanvas canvasStartView;
	public EndingCanvas canvasEndingView;
	public KaisetsuCanvas canvasKaisetsuView;

	public static GameTimer gametimer;

	BranchGroup branchG0;
	public EnemyData enemy1, enemy2, enemy3;

	public CameraPointingGame cameraPointingGame;
	
	public MyCanvas.GameCanvas.MySound myGameCanvasSound = new MyCanvas.GameCanvas.MySound();

	public GameCanvas(CameraPointingGame cameraPointingGame) {
    	this.cameraPointingGame = cameraPointingGame;
    	
        canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
        canvas.setBounds(0,0,1024,768);
        //シーングラフの生成
        simpleU = new SimpleUniverse(canvas);
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(createSceneGraph());
	}

	private void createPolygon(BranchGroup branch, EnemyData enemy,
			String name, float point) {

		//enemy.tfd = new Transform3D();
		//enemy.tg = new TransformGroup(enemy.tfd);

		enemy.tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		enemy.tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		// tg.setCapability(TransformGroup.ALLOW_PICKABLE_READ);
		// tg.setCapability(TransformGroup.ALLOW_PICKABLE_WRITE);
		enemy.tg.setCapability(TransformGroup.ENABLE_PICK_REPORTING);

		enemy.tg.setUserData(name);

		branch.addChild(enemy.tg);

		Appearance ap = new Appearance();
		PolygonAttributes pa = new PolygonAttributes();
		pa.setCullFace(PolygonAttributes.CULL_NONE);
		pa.setBackFaceNormalFlip(true);
		ap.setPolygonAttributes(pa);
		ColoringAttributes ca = new ColoringAttributes();
		ca.setColor(new Color3f(0.0f, 0.0f, 0.1f));
		ap.setColoringAttributes(ca);
		Material ma = new Material();
		ap.setMaterial(ma);

		Point3f[] vertex = new Point3f[4];
		vertex[0] = new Point3f(point, 0.6f, 0.0f);
		vertex[1] = new Point3f(point - 0.4f, 0.6f, 0.0f);
		vertex[2] = new Point3f(point - 0.4f, -0.6f, 0.0f);
		vertex[3] = new Point3f(point, -0.6f, 0.0f);

		QuadArray quadA = new QuadArray(vertex.length,
				GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2);

		TexCoord2f[] texCoord = new TexCoord2f[4];
		texCoord[0] = new TexCoord2f(1.0f, 1.0f);
		texCoord[1] = new TexCoord2f(0.0f, 1.0f);
		texCoord[2] = new TexCoord2f(0.0f, 0.0f);
		texCoord[3] = new TexCoord2f(1.0f, 0.0f);

		quadA.setTextureCoordinates(0, 0, texCoord);

		quadA.setCoordinates(0, vertex);

		// テクスチャー
		// アプリケーションの場合
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		Image image = toolkit.getImage("res/1.png");
		TextureLoader loader = new TextureLoader(image, null);
		ap.setTexture(loader.getTexture());

		// /System.out.println(path);
		TextureAttributes texAttr = new TextureAttributes();
		texAttr.setTextureMode(TextureAttributes.REPLACE);
		ap.setTextureAttributes(texAttr);
		ap.setCapability(Appearance.ALLOW_TEXTURE_READ);
		ap.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
		enemy.shape3D = new Shape3D(quadA, ap);

		enemy.tg.addChild(enemy.shape3D);
	}

	private BranchGroup createSceneGraph() {

		branchG0 = new BranchGroup();

		BufferedImage someImage = null;
		try {
			someImage = ImageIO.read(new File("res/gameback_bokashi.png"));
		} catch (IOException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
    	ImageComponent2D image=new ImageComponent2D(
    			ImageComponent2D.FORMAT_RGB,someImage);
    	Background background=new Background(image);
    	
		//Background background = new Background(new Color3f(0.8f, 0.9f, 1.0f));
		
    	background.setApplicationBounds(bounds);
		branchG0.addChild(background);

		Transform3D tfd = new Transform3D();
		TransformGroup tg = new TransformGroup(tfd);
		enemy1 = new EnemyData("polygon1", tfd, tg);
		createPolygon(branchG0, enemy1, "polygon1", 0.7f);

		tfd = new Transform3D();
		tg = new TransformGroup(tfd);
		enemy2 = new EnemyData("polygon2", tfd, tg);
		createPolygon(branchG0, enemy2, "polygon2", 0.2f);

		tfd = new Transform3D();
		tg = new TransformGroup(tfd);
		enemy3 = new EnemyData("polygon3", tfd, tg);
		createPolygon(branchG0, enemy3, "polygon3", -0.3f);

		GameCanvasBehavior myBehavior3 = new GameCanvasBehavior();
		myBehavior3.setSchedulingBounds(bounds);
		branchG0.addChild(myBehavior3);

		// テキスト表示
		EnemyData.prepareText(branchG0);

		MyMouseAdapter adapter = new MyMouseAdapter();
		canvas.addMouseListener(adapter);

		cnvs = new PickCanvas(canvas, branchG0);
		cnvs.setMode(PickTool.GEOMETRY);

        enemy1.startAutoTurnEnemy();
        enemy2.startAutoTurnEnemy();
        enemy3.startAutoTurnEnemy();
        
		branchG0.compile();

		return branchG0;
	}
    public void destroy(){

        simpleU.cleanup();
    }

	class MyMouseAdapter extends MouseAdapter {

		public void mouseClicked(MouseEvent evnt) {
			String sensorID = createID(evnt.getX(), evnt.getY());
			if (sensorID == null) {
				return;
			}
			clickMethod(sensorID);
		}
	}

	private String createID(int x, int y) {

		cnvs.setShapeLocation(x, y);
		PickResult result = cnvs.pickClosest();
		if (result != null) {
			Node node = null;

			node = result.getNode(PickResult.PRIMITIVE);
			if (node == null)
				node = result.getNode(PickResult.TRANSFORM_GROUP);

			String sensorID = (node.getUserData()).toString();
			return sensorID;
		}
		return null;
	}

	private void clickMethod(String name) {
		// クリアー後にhit()メソッドを実行させないために
		if (FiveRoundData.enemyCount > 0) {

			if (name.equals("polygon1") == true) {
				enemy1.hit();
			} else if (name.equals("polygon2") == true) {
				enemy2.hit();
			} else if (name.equals("polygon3") == true) {
				enemy3.hit();
			}
		}
		// ゼロになったらクリアー画面にする
		if (FiveRoundData.enemyCount == 0) {
			EnemyData.gametimer.timerStop();
			int round = FiveRoundData.upRound();

			if (4 > round) {
				this.cameraPointingGame.changeClearCanvas();
			} else if (4 == round) {
				// ゲーム全面クリア
				this.cameraPointingGame.changeEndingCanvas();
				FiveRoundData.setRoundOne();
			}
		}
	}

	public abstract class MyOwnCode {
		public abstract void processSensor(String sensorID);
	}
}