package gov.nasa.jpl.issm;

import java.nio.DoubleBuffer;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.FloatMath;
import android.view.MotionEvent;


class MyGLSurfaceView extends GLSurfaceView 
{
	private MyGLRenderer mRend;
	private DoubleBuffer db;
	private int size;
	double vmax = 0, vmin=0;
	final int firstVelocity = 9; 
	ColorMap colorMap;
	
	// pinch to zoom
	float oldDist = 100.0f;
	float newDist;
	
	int mode = 0;
    public MyGLSurfaceView(Context context, DoubleBuffer db, int size, ColorMap colorMap) 
    {
        super(context);
        // Create an OpenGL ES 2.0 context.
        setEGLContextClientVersion(2);
        this.db = db;
        this.size = size;
        this.colorMap = colorMap;
        vmin = db.get(firstVelocity);
        findMinMaxVelocity(); 
        intialize();
    }
    private void intialize()
    {
        final int MAX_VERTICES = 21;
        float f[][] = new float[size][MAX_VERTICES];
        //indexes prefer to velocity at each vertices of triangles.
        double alpha1, alpha2, alpha3;
		float  xmin,xmax,ymin,ymax;
        //final int XSCALE_FACTOR = 1;
        //final int YSCALE_FACTOR = 2;
        RGB rgb = new RGB();

		for (int i = 0; i < size; i++) {
				f[i][0] = (float)db.get(12*i+0);
				f[i][1] = (float)db.get(12*i+1);
				f[i][2] = (float)db.get(12*i+2);
				f[i][7] = (float)db.get(12*i+3);
				f[i][8] = (float)db.get(12*i+4);
				f[i][9] = (float)db.get(12*i+5);
				f[i][14] = (float)db.get(12*i+6);
				f[i][15] = (float)db.get(12*i+7);
				f[i][16] = (float)db.get(12*i+8);
				
				f[i][6] = 1.0f;
				f[i][13] = 1.0f;
				f[i][20] = 1.0f;
				
				alpha1 = getAlphaColor(db.get(12*i+9));
				alpha2 = getAlphaColor(db.get(12*i+10));
				alpha3 = getAlphaColor(db.get(12*i+11));
				
				colorMap.getRGB(alpha1, rgb);
				float r1 = rgb.getR();
				float g1 = rgb.getG();
				float b1 = rgb.getB();
				
				colorMap.getRGB(alpha2, rgb);
				float r2 = rgb.getR();
				float g2 = rgb.getG();
				float b2 = rgb.getB();
				
				colorMap.getRGB(alpha3, rgb);
				float r3 = rgb.getR();
				float g3 = rgb.getG();
				float b3 = rgb.getB();
				
				
				f[i][3] = r1;
				f[i][4] = g1;
				f[i][5] = b1;
				
				f[i][10] = r2;
				f[i][11] = g2;
				f[i][12] = b2;
				
				f[i][17] = r3;
				f[i][18] = g3;
				f[i][19] = b3;

		}

	
		xmin=0; ymin=0; xmax=0; ymax=0;

		for (int i = 0; i < size; i++) {
			if (f[i][0]<xmin) xmin=f[i][0];
			if (f[i][0]>xmax) xmax=f[i][0];

			if (f[i][1]<ymin) ymin=f[i][1];
			if (f[i][1]>ymax) ymax=f[i][1];
		}
				
		for (int i = 0; i < size; i++) {
				f[i][0] =  2*(f[i][0]-xmin)/(xmax-xmin)-1;
				f[i][1] =  2*(f[i][1]-ymin)/(ymax-ymin)-1;
				f[i][7] =  2*(f[i][7]-xmin)/(xmax-xmin)-1;
				f[i][8] =  2*(f[i][8]-ymin)/(ymax-ymin)-1;
				f[i][14] =  2*(f[i][14]-xmin)/(xmax-xmin)-1;
				f[i][15] =  2*(f[i][15]-ymin)/(ymax-ymin)-1;
		}
				
    	mRend = new MyGLRenderer(f);
    	// Set the Renderer for drawing on the GLSurfaceView
        setRenderer(mRend);

        // Render the view only when there is a change in the drawing data
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }
    private void findMinMaxVelocity()
    {
    	for(int i = 0; i < size*12; i++)
    	{
    		if(i%12==9 || i%12==10 ||i%12==11 )
    		{
    			if (db.get(i) <  vmin) vmin = db.get(i);
    			if (db.get(i) >= vmax) vmax = db.get(i);
    		}
    		else continue; 
    	}
    	
    }  
    private double getAlphaColor(double velocity)
    {
    	return (velocity-vmin)/(vmax-vmin);
    }
    
    private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
    private float mPreviousX;
    
    private float mPreviousY;
 // touch events
 	private final int NONE = 0;
 	private final int DRAG = 0;
 	private final int ZOOM = 0;
    @Override
    public boolean onTouchEvent(MotionEvent e) /* NEW STUFF*/
	{
		float x = e.getX();
		float y = e.getY();
		switch (e.getAction()) {
			case MotionEvent.ACTION_DOWN:			// one touch: drag
		      mode = DRAG;
		      //mRend.eyeX = e.getX();
		      //mRend.eyeY = e.getY;
		      break;
		      
			case MotionEvent.ACTION_POINTER_DOWN:	// two touches: zoom
				oldDist = spacing(e);
				if (oldDist > 10.0f) 
					mode = ZOOM; // zoom
				break;
				
			case MotionEvent.ACTION_UP:		// no mode
				mode = NONE;
				oldDist = 100.0f;
				break;
				
			case MotionEvent.ACTION_POINTER_UP:		// no mode
				mode = NONE;
				oldDist = 100.0f;
				break;
				
			case MotionEvent.ACTION_MOVE:						// rotation
				if (e.getPointerCount() > 1 && mode == ZOOM) 
				{
					newDist = spacing(e);
					if (newDist > 10.0f) {
						float scale = newDist/oldDist; // scale
						
						// scale in the renderer
						mRend.changeScale(scale);
						oldDist = newDist;
					}
				}
				else if (mode == DRAG)
				{
					float dx = x - mPreviousX;
					float dy = y - mPreviousY;
					
					mRend.mAngleX += dx * TOUCH_SCALE_FACTOR;
					mRend.mAngleY += dy * TOUCH_SCALE_FACTOR;

					requestRender();
				}
				break;
		}
		mPreviousX = x;
		mPreviousY = y;
		return true;
	}
	
	private float spacing(MotionEvent event) /* NEW STUFF*/
	{
		float x = event.getX(0) - event.getX(1);
		float y = event.getY(0) - event.getY(1);
		return FloatMath.sqrt(x * x + y * y);
	}
}

