package com.roxiga.aquamotion3d;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.opengl.Matrix;

public class BoneModel3D extends Model3D
{
    public BoneModel3D()
    {
    }
    
    protected void init()
    {
    	short i,i2,i3;
   
    	super.init();

        ByteBuffer bbb = ByteBuffer.allocateDirect(
        		_indices.size()*FLOAT_SIZE_BYTES);
        bbb.order(ByteOrder.nativeOrder());
        _boneBuffer = bbb.asFloatBuffer();
        for ( i = 0; i < _indices.size(); i++)
        {
 			_boneBuffer.put(_bones.get(_indices.get(i)));
		}
		_boneBuffer.position(0);

		int size = _animations.size();
		_motions = new float[size][][];
		for ( i = 0; i < size; i++ )
		{
			ArrayList<ArrayList<Float>> anim = _animations.get(i);
			int size2 = anim.size();
			_motions[i] = new float[size2][];
			for ( i2 = 0; i2 < size2; i2++ )
			{
				ArrayList<Float> anim2 = anim.get(i2);
				int size3 = anim2.size();
				_motions[i][i2] = new float[size3];
				for ( i3 = 0; i3 < size3; i3++ )
				{
					_motions[i][i2][i3] = anim2.get(i3);
				}
			}
		}
		
		_currentAnimation = 0;
        _time = 0;
    }

    protected void addB(double x,double y,double z,double bone)
    {
    	_vertices.add(new Vector3D((float)x,(float)y,(float)z));
    	_bones.add((float)bone);
    }

	protected void addA3()
	{
		_animations.add(new ArrayList<ArrayList<Float>>());
		_currentAnimation = _animations.size() - 1;
	}

	protected void addA2()
	{
		ArrayList<ArrayList<Float>> anim = _animations.get(_currentAnimation);
		anim.add(new ArrayList<Float>());
		_time = anim.size() - 1;
	}

	protected void addA(
			double m0,double m1,double m2,double m3,
			double m4,double m5,double m6,double m7,
			double m8,double m9,double m10,double m11,
			double m12,double m13,double m14,double m15)
	{
		ArrayList<ArrayList<Float>> anim = _animations.get(_currentAnimation);
		ArrayList<Float> anim2 = anim.get(_time);
		anim2.add((float)m0);
		anim2.add((float)m1);
		anim2.add((float)m2);
		anim2.add((float)m3);
		anim2.add((float)m4);
		anim2.add((float)m5);
		anim2.add((float)m6);
		anim2.add((float)m7);
		anim2.add((float)m8);
		anim2.add((float)m9);
		anim2.add((float)m10);
		anim2.add((float)m11);
		anim2.add((float)m12);
		anim2.add((float)m13);
		anim2.add((float)m14);
		anim2.add((float)m15);
	}
    
    public void draw(Scene3D scene)
    {        
    	if ( !_visible )
    	{
    		return;
    	}
    	GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, _textureID);

        GLES20.glUniform1i(scene._uUseBoneHandle, 1);

        setTransform();
        Matrix.multiplyMM(_mvpMatrix, 0, scene._vMatrix, 0, _mMatrix, 0);
        Matrix.multiplyMM(_mvpMatrix, 0, scene._projMatrix, 0, _mvpMatrix, 0);
        GLES20.glUniformMatrix4fv(scene._uMVPMatrixHandle, 1, false, _mvpMatrix, 0);
	
		GLES20.glUniformMatrix4fv(scene._uBoneMatrixHandle,
				_motions[_currentAnimation][_time].length/16,
				false, _motions[_currentAnimation][_time], 0);

        GLES20.glEnableVertexAttribArray(scene._aPositionHandle);
		_vertexBuffer.position(0);
        GLES20.glVertexAttribPointer(scene._aPositionHandle, 3, GLES20.GL_FLOAT,
        		false,VERTICES_DATA_STRIDE_BYTES, _vertexBuffer);

        GLES20.glEnableVertexAttribArray(scene._aBoneHandle);
        _boneBuffer.position(0);
        GLES20.glVertexAttribPointer(scene._aBoneHandle, 1, GLES20.GL_FLOAT,
        		false,BONE_DATA_STRIDE_BYTES, _boneBuffer);
 
        GLES20.glEnableVertexAttribArray(scene._aTextureHandle);
        _textureBuffer.position(0);
         GLES20.glVertexAttribPointer(scene._aTextureHandle, 2, GLES20.GL_FLOAT,
        		false,UV_DATA_STRIDE_BYTES, _textureBuffer);

         GLES20.glDrawElements(GL10.GL_TRIANGLES, _indices.size(),
        		GLES20.GL_UNSIGNED_SHORT, _indexBuffer);

         if ( !_stopAnimation )
         {
        	 _time++;
        	 if ( _time >= _motions[_currentAnimation].length )
        	 {
        		 if ( _loopAnimation )
        		 {
        			 _time = 0;
        		 }
        		 else if ( _animationLast )
        		 {
        			 _time = _motions[_currentAnimation].length - 1;
        			 _stopAnimation = true;
        		 }
        		 else
        		 {
        			 _time = 0;
        			 _stopAnimation = true;
        		 }
        	 }
        }
    }
}
