package Cameus;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;

import MyMain.CameraPointingGame;


public class KameusThread extends JPanel implements Runnable{
	
    private static final long serialVersionUID = 1L;

    public static int CameraDeviceNumber;
    
    private BufferedImage mImg;
    
    Mat dst;
    Mat dst1;
    Mat dst2;
    MatOfRect objDetections;
    Size minSize;
    Size maxSize;
    java.awt.Point mouseP;
    java.awt.Point cameraP;
    CameraPointingGame cameraPointingGame;
    
    public static VideoCapture capture;
    public KameusThread(CameraPointingGame cameraPointingGame){
        System.out.println("opencv_java300");
        //System.loadLibrary("opencv_java300");
        
        this.cameraPointingGame = cameraPointingGame;
        
        this.dst = new Mat();
        this.dst1 = new Mat();
        this.dst2 = new Mat();
        objDetections = new MatOfRect();
        
        minSize = new Size(25,25);
        maxSize = new Size(60,60);
        
        mouseP = new java.awt.Point();
        cameraP = new java.awt.Point();
    }
    public void dobj(CascadeClassifier objDetector, Mat src, int width, int height, KamesMouse kames) {

        
        dst1 = src.submat(new Rect(320, 40, 640, 640));
        Imgproc.cvtColor(dst1, dst2, Imgproc.COLOR_RGB2GRAY);
        Imgproc.equalizeHist(dst2, dst);
        
        objDetector.detectMultiScale(dst, objDetections, 1.11, 2, 0, minSize,maxSize);

        if(objDetections.toArray().length<=0)
            return;

        int rectWidth = 0;
        for (Rect rect : objDetections.toArray()) {
        	
        	if (((rect.width - rect.height) > 10) || ((rect.width - rect.height) < -10))
        		continue;
        	
        	mouseP.x = rect.x + (rect.width)/2;
        	mouseP.y = rect.y + (rect.height)/2;
        	
            rectWidth = rect.width;

			cameraP.x = 640 / 2;
			cameraP.y = 640 / 2;

			int x = cameraP.x - mouseP.x;
			int y = cameraP.y - mouseP.y;

			float smallNum = 32.0f / (float) rectWidth;
			
			x = Math.round((((float) x) * smallNum) / 3.0f);
			y = Math.round((((float) y) * smallNum) / 3.0f);

			kames.GetNowCursor();
			kames.MoveMouse(new java.awt.Point(x, y));

			return;
        }
    }
    public void dobj640x480(CascadeClassifier objDetector, Mat src, int width, int height, KamesMouse kames) {

        
        dst1 = src;//.submat(new Rect(320, 40, 640, 640));
        Imgproc.cvtColor(dst1, dst2, Imgproc.COLOR_RGB2GRAY);
        Imgproc.equalizeHist(dst2, dst);
        
        objDetector.detectMultiScale(dst, objDetections, 1.11, 2, 0, minSize,maxSize);

        if(objDetections.toArray().length<=0)
            return;

        int rectWidth = 0;
        for (Rect rect : objDetections.toArray()) {
        	
        	if (((rect.width - rect.height) > 10) || ((rect.width - rect.height) < -10))
        		continue;
        	
        	mouseP.x = rect.x + (rect.width)/2;
        	mouseP.y = rect.y + (rect.height)/2;
        	
            rectWidth = rect.width;

			cameraP.x = 640 / 2;
			cameraP.y = 480 / 2;

			int x = cameraP.x - mouseP.x;
			int y = cameraP.y - mouseP.y;

			float smallNum = 32.0f / (float) rectWidth;
			
			x = Math.round((((float) x) * smallNum) / 3.0f);
			y = Math.round((((float) y) * smallNum) / 3.0f);

			kames.GetNowCursor();
			kames.MoveMouse(new java.awt.Point(x, y));

			return;
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        if(mImg != null)
            g.drawImage(mImg, 0, 0, mImg.getWidth(), mImg.getHeight(), this);
    }

    public void startThread(){
    
    	Thread thread = new Thread(this);
    	thread.start();
    }
    
    public void run(){
		try {

			KamesMouse kames = new KamesMouse(this.cameraPointingGame);

			// Create a object detector.
			CascadeClassifier objDetector = new CascadeClassifier(
					"res/cascade.xml");

			Mat capImg = new Mat();
			capture = new VideoCapture(CameraDeviceNumber);

			capture.set(4, 720);
			capture.set(3, 1280);
			capture.read(capImg);
			if ((capImg.width() == 1280) && (capImg.height() == 720)) {
				System.out.println("Camera is 1280x720");
				while (true) {
					capture.read(capImg);
					if (capImg == null)break;
					dobj(objDetector, capImg, 1280, 720, kames);
					Thread.sleep(10);
					// 終了させる
					//if (CameusLock.getIsCameus() == false)
					//	break;
				}
				// capture.release();
			} else {
				
			}
			
			capture.release();
		
		} catch (Exception e) {
			System.out.println("xxxx" + e);
		} finally {
			System.out.println("done");
		}
        
    }
}
