package com.android.draw3d;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;

public class MainActivity extends Activity implements CvCameraViewListener2 {
	private Display display;
	//private android.graphics.Point size;
	
	private RelativeLayout relativelayout;
	
	private ModelSurfaceView mModelSurfaceView1;
	private ModelSurfaceView mModelSurfaceView2;
	//private ModelRenderer mModelRenderer1;
	//private ModelRenderer mModelRenderer2;
	//private ObjModelRenderer mObjModelRenderer1;
	//private ObjModelRenderer mObjModelRenderer2;
	private DrawModelRenderer mDrawModelRenderer1;
	private DrawModelRenderer mDrawModelRenderer2;
	
	private CameraBridgeViewBase mOpenCvCameraView;
	private Mat mRgba;
    private Mat mGray;
    private MarkerRecognizer MR;
    private DrawAboveMarker DAM;
    private List<Marker> recognizedMarkers = new ArrayList<Marker>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		
		display = getWindowManager().getDefaultDisplay();
		//display.getSize(size);
		//int width = size.x;
		//int height = size.y;
		int width = display.getWidth();
		int height = display.getHeight();
		
		relativelayout = (RelativeLayout) findViewById(R.id.relativelayout);
		
		//mModelRenderer1 = new ModelRenderer(this);
		//mModelRenderer2 = new ModelRenderer(this);
		//mObjModelRenderer1 = new ObjModelRenderer(this);
		//mObjModelRenderer2 = new ObjModelRenderer(this);
		mDrawModelRenderer1 = new DrawModelRenderer(this);
		mDrawModelRenderer2 = new DrawModelRenderer(this);
		
		mModelSurfaceView1 = new ModelSurfaceView(this);
		mModelSurfaceView1.setZOrderOnTop(true);
		mModelSurfaceView1.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
		mModelSurfaceView1.getHolder().setFormat(PixelFormat.TRANSPARENT);
		//mModelSurfaceView1.setEGLContextClientVersion(2);
		mModelSurfaceView1.setRenderer(mDrawModelRenderer1);
		LayoutParams lp1 =new LayoutParams(width/2, height);
		lp1.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
		mModelSurfaceView1.setLayoutParams(lp1);
		relativelayout.addView(mModelSurfaceView1);
		
		mModelSurfaceView2 = new ModelSurfaceView(this);
		mModelSurfaceView2.setZOrderOnTop(true);
		mModelSurfaceView2.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
		mModelSurfaceView2.getHolder().setFormat(PixelFormat.TRANSPARENT);
		//mModelSurfaceView2.setEGLContextClientVersion(2);
		mModelSurfaceView2.setRenderer(mDrawModelRenderer2);
		LayoutParams lp2 =new LayoutParams(width/2, height);
		lp2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		mModelSurfaceView2.setLayoutParams(lp2);
		relativelayout.addView(mModelSurfaceView2);
		
		
		mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.CvCameraView);
		//mOpenCvCameraView.setCameraIndex(0);
		//mOpenCvCameraView.enableFpsMeter();
		mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
	    mOpenCvCameraView.setCvCameraViewListener(this);
	}
	
	private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    mOpenCvCameraView.enableView();
                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };
	
	@Override
	protected void onResume() {
		super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_11, this, mLoaderCallback);
		//mModelSurfaceView1.onResume();
	}

	@Override
	protected void onPause() {
		super.onPause();
		//mModelSurfaceView1.onPause();
	}

	@Override
	public void onCameraViewStarted(int width, int height) {
		
	}

	@Override
	public void onCameraViewStopped() {
		
	}

	@Override
	public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
		mDrawModelRenderer1.set_has_update(false);
        mDrawModelRenderer2.set_has_update(false);
        mDrawModelRenderer1.set_markers(recognizedMarkers.size(), recognizedMarkers);
        mDrawModelRenderer2.set_markers(recognizedMarkers.size(), recognizedMarkers);
        
		mRgba = inputFrame.rgba();
        mGray = inputFrame.gray();
        
        int height = mRgba.height();
        int width = mRgba.width();
        int halfWidth = width/2;
        int startCol = width/4;
        int stopCol = startCol+halfWidth;
        
        Mat mat = new Mat(mRgba.size(),mRgba.type());
        Mat matMiddle = mRgba.submat(0,height, startCol, stopCol);
        Mat matMiddle_gray = mGray.submat(0,height, startCol, stopCol);
        Mat matLeft = mat.submat(0, height, 0, halfWidth);
        Mat matRight = mat.submat(0, height, halfWidth, width);
        
        List<Marker> detectedMarkers = new ArrayList<Marker>();
        MR = new MarkerRecognizer();
        //MR.MarkerDetect(mGray, detectedMarkers, 50, 5);
        MR.MarkerDetect(matMiddle_gray, detectedMarkers, 50, 5);
        
        //List<Marker> recognizedMarkers = new ArrayList<Marker>();
        recognizedMarkers = new ArrayList<Marker>();
        //MR.MarkerRecognize(mGray, detectedMarkers, recognizedMarkers);
        MR.MarkerRecognize(matMiddle_gray, detectedMarkers, recognizedMarkers);
        
        //MR.MarkerRefine(mGray, recognizedMarkers);
        DAM = new DrawAboveMarker();
        
        Scalar cColor= new Scalar(0, 0, 255);
        for(int i=0;i<recognizedMarkers.size();i++){
        	//if(recognizedMarkers.get(i).marker_id != 198 & recognizedMarkers.get(i).marker_id != 588){
        		Marker marker = recognizedMarkers.get(i);
        		//marker.drawToMat(mRgba, cColor, 1);
        		//DAM.drawCube(mRgba, marker, false);
        		marker.drawToMat(matMiddle, cColor, 1);
        		DAM.drawCube(matMiddle, marker, false);
        	//}
        }
        
        matMiddle.copyTo(matRight);
        matMiddle.copyTo(matLeft);
        
        mRgba.release();
        mGray.release();
        matMiddle.release();
        matMiddle_gray.release();
        matLeft.release();
        matRight.release();
        
        mDrawModelRenderer1.set_has_update(true);
        mDrawModelRenderer2.set_has_update(true);
        mDrawModelRenderer1.set_markers(recognizedMarkers.size(), recognizedMarkers);
        mDrawModelRenderer2.set_markers(recognizedMarkers.size(), recognizedMarkers);
        
        System.gc();
        
		return mat;
	}
	
	public void MarkerDetect(Mat m){
		Point p0 = new Point(100,100);
		Point p1 = new Point(100,200);
		Point p2 = new Point(200,200);
		Point p3 = new Point(200,100);
		
		Marker marker = new Marker(1,p0,p1,p2,p3);
	}
	
}
