package ar.nmorales.tesis.gui;

import java.awt.Graphics;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;

import ar.nmorales.tesis.model.Blob;
import ar.nmorales.tesis.video.GraphicProcessor;

public  class MatchedBlobsPanel extends JPanel{  
    private static final long serialVersionUID = 1L;
    
    private BufferedImage image;
	
    public MatchedBlobsPanel(){  
         super(true);
    }  
    
    /*  
     * Converts/writes a Mat into a BufferedImage.  
     *   
     * @param matrix Mat of type CV_8UC3 or CV_8UC1  
     * @return BufferedImage of type TYPE_3BYTE_BGR or TYPE_BYTE_GRAY  
     */
    
    public boolean project(ArrayList<Blob> previousBlobs,ArrayList<Blob> currentBlobs) {  
    	
    	Mat matrix = new Mat(new Size(200,500), CvType.CV_8UC3, new Scalar(0,0,0));
    	GraphicProcessor.setColor(255,0,0);
		GraphicProcessor.text(matrix, new Point (5,10), "Previous");
		GraphicProcessor.setColor(0,255,0);
		GraphicProcessor.text(matrix, new Point (110,10), "Current");
		
		int xl = 30;
		int xr = 130;
		
		GraphicProcessor.setFilled();
		GraphicProcessor.setColor(255,255,255);
		
		/* Draw blocks for previous blobs */
		for (int i = 1; i<= previousBlobs.size() ; i++){	
			GraphicProcessor.drawRectangle(matrix, xl, i * 35, 25, 25);
		//	System.out.println(previousBlobs.get(i-1).getRectangle());
		}
		
		/* Draw blocks for current blobs */
		for (int i = 1; i<= currentBlobs.size() ; i++){	
			GraphicProcessor.drawRectangle(matrix, xr, i * 35, 25, 25);
		}
		
		/* Draw connection lines between dots*/
		int i = 1;
		int yl,yr;
		for (Blob blobPrev : previousBlobs){
			if (blobPrev.getMatchedBlobs().size() > 1){
			//	System.out.println("Prev Blob: " + blobPrev.getRectangle() + " Matches: ");
				for (Blob b : blobPrev.getMatchedBlobs()){
				//	System.out.println(" - " + b.getRectangle() + " POS: " + (currentBlobs.indexOf(b)+1));
				}
			}
			for (Blob blobCurr : blobPrev.getMatchedBlobs()){
				yl = i * 35 + 12;
				yr = (currentBlobs.indexOf(blobCurr) + 1 ) * 35 + 12;
				GraphicProcessor.drawLine(matrix, xl + 25, yl, xr, yr);
			}
			i++;
		}

		GraphicProcessor.setNotFilled();
    	
         MatOfByte mb=new MatOfByte();  
         
         
         Imgcodecs.imencode(".jpg", matrix, mb);  
         try {  
              this.image = ImageIO.read(new ByteArrayInputStream(mb.toArray()));  
         } catch (IOException e) {  
              e.printStackTrace();  
              return false; // Error  
         }  
         repaint(); // Update panel image
      return true; // Successful  
    }
    
 
	public boolean MatToBufferedImage(Mat matBGR){  
        long startTime = System.nanoTime();  
        int width = matBGR.width(), height = matBGR.height(), channels = matBGR.channels() ;  
        byte[] sourcePixels = new byte[width * height * channels];  
        matBGR.get(0, 0, sourcePixels);  
        // create new image and get reference to backing data  
        image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);  
        final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();  
        System.arraycopy(sourcePixels, 0, targetPixels, 0, sourcePixels.length);  
        long endTime = System.nanoTime();  
        System.out.println(String.format("Elapsed time: %.2f ms", (float)(endTime - startTime)/1000000));  
        return true;  
   }  
    
    public void paintComponent(Graphics g){  

        if (this.image==null) return;   
        super.paintComponent(g);   
         float imageRatio = (float)this.image.getWidth()/(float)this.image.getHeight();
         float frameRatio = (float)this.getWidth()/(float)this.getHeight();
         
         if ( frameRatio > imageRatio ){
        	 g.drawImage(this.image,(this.getWidth() - (int)(this.getHeight()*imageRatio))/2,0,(int)(this.getHeight()*imageRatio),this.getHeight(), null);
         }else {
        	 g.drawImage(this.image,0,(int)(this.getHeight() - (int)(this.getWidth()/imageRatio))/2,this.getWidth(),(int)(this.getWidth()/imageRatio), null);
         }
          
    }

}  