package org.concord.energy3d.model;

import org.concord.energy3d.scene.Scene;
import org.concord.energy3d.scene.Scene.TextureMode;
import org.concord.energy3d.util.SelectUtil;

import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.BlendState;
import com.ardor3d.renderer.state.BlendState.TestFunction;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.Spatial;
import com.ardor3d.scenegraph.extension.BillboardNode;
import com.ardor3d.scenegraph.extension.BillboardNode.BillboardAlignment;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.PickingHint;
import com.ardor3d.scenegraph.shape.Quad;

public class Human extends HousePart {

	private static final long serialVersionUID = 1L;
	public static final int JANE = 0;
	public static final int JENNY = 1;
	public static final int JACK = 2;
	public static final int JOHN = 3;
	private transient BillboardNode billboard;
	private transient Node collisionRoot;
	private final int humanType;

	public Human(final int humanType) {
		super(1, 1, 1);
		this.humanType = humanType;
		init();
	}

	@Override
	protected void init() {
		super.init();

		final double height;
		final double width;
		switch (humanType) {
		case JANE:
			width = 2.5;
			height = 8;
			break;
		case JENNY:
			width = 3;
			height = 9;
			break;
		case JACK:
			width = 2.8;
			height = 9;
			break;
		case JOHN:
			width = 4;
			height = 10;
			break;
		default:
			width = 2.5;
			height = 8;
		}
		mesh = new Quad("Human Quad", width, height);
		mesh.setModelBound(new BoundingBox());
		mesh.updateModelBound();
		mesh.setRotation(new Matrix3().fromAngles(Math.PI / 2, 0, 0));
		mesh.setTranslation(0, width / 2, height / 2 + 1); // foundation height = 1
		mesh.getSceneHints().setPickingHint(PickingHint.Pickable, false);

		final BlendState bs = new BlendState();
		bs.setEnabled(true);
		bs.setBlendEnabled(false);
		bs.setTestEnabled(true);
		bs.setTestFunction(TestFunction.GreaterThan);
		bs.setReference(0.7f);
		mesh.setRenderState(bs);
		mesh.getSceneHints().setRenderBucketType(RenderBucketType.Transparent);

		billboard = new BillboardNode("Billboard");
		billboard.setAlignment(BillboardAlignment.AxialZ);
		billboard.attachChild(mesh);
		root.attachChild(billboard);

		collisionRoot = new Node("Tree Collision Root");
		if (points.size() > 0)
			collisionRoot.setTranslation(getAbsPoint(0));
		collisionRoot.updateWorldBound(true);
		collisionRoot.getSceneHints().setCullHint(CullHint.Always);
		root.attachChild(collisionRoot);

		updateTextureAndColor();

	}

	@Override
	public void setPreviewPoint(final int x, final int y) {
		final int index = 0;
		final PickedHousePart pick = SelectUtil.pickPart(x, y, new Class<?>[] { Foundation.class, null });
		if (pick != null) {
			final Vector3 p = pick.getPoint();
			snapToGrid(p, getAbsPoint(index), getGridSize());
			points.get(index).set(toRelative(p));
		}
		draw();
		setEditPointsVisible(true);
	}

	@Override
	public double getGridSize() {
		return 5.0;
	}

	@Override
	protected boolean mustHaveContainer() {
		return false;
	}

	@Override
	public boolean isPrintable() {
		return false;
	}

	@Override
	public boolean isDrawable() {
		return true;
	}

	@Override
	protected void drawMesh() {
		billboard.setTranslation(getAbsPoint(0));
		collisionRoot.setTranslation(getAbsPoint(0));
		final double scale = 1 / (Scene.getInstance().getAnnotationScale() / 0.2);
		billboard.setScale(scale);
		collisionRoot.setScale(scale);
	}

	@Override
	protected String getTextureFileName() {
		switch (humanType) {
		case JANE:
			return "jane.png";
		case JENNY:
			return "jenny.png";
		case JACK:
			return "jack.png";
		case JOHN:
			return "john.png";
		default:
			return "jane.png";
		}
	}

	@Override
	public void updateTextureAndColor() {
		updateTextureAndColor(mesh, Scene.getInstance().getWallColor(), TextureMode.Full);
	}

	@Override
	public Spatial getCollisionSpatial() {
		collisionRoot.updateWorldBound(true);
		return collisionRoot;
	}

	public int getHumanType() {
		return humanType;
	}

	public String getHumanName() {
		switch (humanType) {
		case JANE:
			return "Jane";
		case JENNY:
			return "Jenny";
		case JACK:
			return "Jack";
		case JOHN:
			return "John";
		default:
			return "Unknown";
		}
	}

}

@@ -438,83 +438,8 @@
 on;%0A
-import com.ardor3d.scenegraph.Node;%0Aimport com.ardor3d.scenegraph.Spatial;%0A
 impo
@@ -567,101 +567,8 @@
 nt;%0A
-import com.ardor3d.scenegraph.hint.CullHint;%0Aimport com.ardor3d.scenegraph.hint.PickingHint;%0A
 impo
@@ -645,17 +645,16 @@
 ePart %7B%0A
-%0A
 %09private
@@ -884,47 +884,8 @@
 rd;%0A
-%09private transient Node collisionRoot;%0A
 %09pri
@@ -1661,66 +1661,47 @@
 esh.
-getSceneHints().setPickingHint(PickingHint.Pickable, false
+setUserData(new UserData(this, 0, true)
 );%0A%0A
@@ -2162,271 +2162,8 @@
 );%0A%0A
-%09%09collisionRoot = new Node(%22Tree Collision Root%22);%0A%09%09if (points.size() %3E 0)%0A%09%09%09collisionRoot.setTranslation(getAbsPoint(0));%0A%09%09collisionRoot.updateWorldBound(true);%0A%09%09collisionRoot.getSceneHints().setCullHint(CullHint.Always);%0A%09%09root.attachChild(collisionRoot);%0A%0A
 %09%09up
@@ -2185,17 +2185,16 @@
 olor();%0A
-%0A
 %09%7D%0A%0A%09@Ov
@@ -2927,56 +2927,8 @@
 ));%0A
-%09%09collisionRoot.setTranslation(getAbsPoint(0));%0A
 %09%09fi
@@ -3033,41 +3033,8 @@
 e);%0A
-%09%09collisionRoot.setScale(scale);%0A
 %09%7D%0A%0A
@@ -3434,127 +3434,8 @@
 %09%7D%0A%0A
-%09@Override%0A%09public Spatial getCollisionSpatial() %7B%0A%09%09collisionRoot.updateWorldBound(true);%0A%09%09return collisionRoot;%0A%09%7D%0A%0A
 %09pub

Fix problem with not being able to pick the human