package gui;

import java.io.File;
import network.Command;
import network.NetPack;
import network.NetworkHandler;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import other.DynamicCmdSelector;
import other.PathHelp;

/**
 * TabItemCam Klasse 
 * Dient zum Anzeigen des WebCam Bildes  von der WebCam
 * Die Arbeiten des Roboters können kontrolliert und der
 * Bereich der Kameraprüfung ausgewählt werden
 */
public class TabItemCam extends Composite implements DynamicCmdSelector {

	// Attribute
	private Display dDisplay = null;
	private Canvas cCanvas = null;
	private Button bRefresh = null;
	private Label lFiller1 = null;
	private Label lFiller2 = null;
	private Label statLbl = null;
    private Image img = null;
	private NetworkHandler netHandler = null;
	private GC gContext = null;
	private Composite cComp = null;
	private Point pClick = null;
	private MainShell mainShell = null;
	boolean bConnected = false;
	boolean bIsDynCmdSelect = false;

	/**
	 * Konstruktor
	 * @param display das erzeugte Display
	 * @param parent das Parent Composite
	 * @param style der SWT Style
	 * @param netH das vorherrschende NetworkHandler Objekt
	 */
	public TabItemCam(MainShell mainSh, Display display,Composite parent, int style, NetworkHandler netH) {
		super(parent, style);
		mainShell=mainSh;
		dDisplay=display;
		// Image erzeugen
        img = new Image(display,PathHelp.specFileStdCam());
		// Für die FTP Verbindung
		netHandler = netH;
		initialize();
	}
	
	/* ##########################################################################
	 * 						VISUAL EDITOR
	 * ##########################################################################*/

	/**
	 * Initialisiert das Tab. Erzeugt die Komponeten und ordent diese an
	 */
	private void initialize() {
		// Layout
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 3;
		this.setLayout(gridLayout);
		
		// Fülllabel 1
		lFiller1 = new Label(this, SWT.NONE);
		GridData gridDataF = new GridData();
		gridDataF.grabExcessHorizontalSpace = true;
		gridDataF.grabExcessVerticalSpace = true;
		gridDataF.verticalSpan = 2;
		lFiller1.setLayoutData(gridDataF);
		
		// Canvas
        cCanvas = new Canvas(this, SWT.NONE);
        cCanvas.setSize(640,480);
        cCanvas.setCursor(new Cursor(dDisplay,SWT.CURSOR_CROSS));
        gContext = new GC(cCanvas);
        // Layout
		GridData gridData1 = new GridData();
		gridData1.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
		gridData1.verticalAlignment = org.eclipse.swt.layout.GridData.FILL;
		gridData1.widthHint = 640;
		gridData1.heightHint= 480;
		cCanvas.setLayoutData(gridData1);
		// Listener
        cCanvas.addPaintListener(new PaintListener(){
		public void paintControl(PaintEvent e) {
			// Bild refreshen
			gContext.drawImage(img,0,0);
		}
        });
        cCanvas.addMouseListener(new MouseListener(){
			public void mouseDoubleClick(MouseEvent e) { }
			//Mause wurde geklickt
			public void mouseDown(MouseEvent e) {
				// Mausposition speichern
				if(bIsDynCmdSelect) pClick=new Point(e.x,e.y);
			}
			//Maus wurde losgelassen
			public void mouseUp(MouseEvent e) {
				if(bIsDynCmdSelect){
					int x = (e.x+pClick.x)/2;
					int y = (e.y+pClick.y)/2;
					int s = (Math.abs(e.x-pClick.x)+Math.abs(e.y-pClick.y))/2;
					int m = getColor(x,y);
					statLbl.setText("");
					String str = "" + x + "," + y + "," + s + ",";
					if(m>50)
						str += "100,20";
					else
						str += "0,20";
					stopDynamicCmdSelect(str);
				}
			}
        
        });
        cCanvas.addMouseMoveListener(new MouseMoveListener(){
        	//Maus wurde bewegt
			public void mouseMove(MouseEvent e) {
				//Zeigt die Farbe in der Statusbar
				if(bIsDynCmdSelect&&pClick!=null){
					int s = (Math.abs(e.x-pClick.x)+Math.abs(e.y-pClick.y))/2;
					showStatusText(e.x,e.y,getColor(e.x,e.y),s);
				}else{
					showStatusText(e.x,e.y,getColor(e.x,e.y),0);
				}
				
			}	
        });
        
		// Fülllabel 2
		lFiller2 = new Label(this, SWT.NONE);
		lFiller2.setLayoutData(gridDataF);
        
		// Button-Composite
		cComp = new Composite(this, SWT.NONE);
		// Layout
		FillLayout fillLayout = new FillLayout();
		fillLayout.type = org.eclipse.swt.SWT.VERTICAL;
		fillLayout.spacing = 8;
		GridData gridData2 = new GridData();
		gridData2.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER;
		gridData2.verticalAlignment = org.eclipse.swt.layout.GridData.BEGINNING;
		cComp.setLayoutData(gridData2);
		cComp.setLayout(fillLayout);
		
        // Button
		bRefresh = new Button(cComp, SWT.NONE);
		bRefresh.setText("   Aktualisieren   ");
		bRefresh.setFont(new org.eclipse.swt.graphics.Font(org.eclipse.swt.widgets.Display.getDefault(), "Tahoma", 12, org.eclipse.swt.SWT.NORMAL));
		// Listener
		bRefresh.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { 
        	public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {    
        		sendImageRequest();
        	}
        });
	}
	

	/* ##########################################################################
	 * 						EREIGNISSE
	 * ##########################################################################*/
	
	
	/**
	 * Wird vom Hauptfenster aufgerufen, wenn gerade
	 * eine Verbindung aufgebaut wurde.
	 */
	public void connectionEstablished(){
		bConnected=true;
		bRefresh.setEnabled(true);
	}
	
	/**
	 * Wird vom Hauptfenster aufgerufen, wenn die Verbindung
	 * gerade unterbrochen wurde.
	 */
	public void connectionDisrupted(){
		bConnected=false;
		bRefresh.setEnabled(false);
	}

	/* ##########################################################################
	 * 						ÖFFENTLICHE METHODEN
	 * ##########################################################################*/
	
	/**
	 * Liefert den Graustufefarbewert an der Position(x,y)
	 * @param x X-Koordinate
	 * @param y Y-Koordinate
	 */
	public int getColor(int x,int y){
		try{
			// Pixel holen
			int p = img.getImageData().getPixel(x, y);
			// in R, G, B umwandeln
			int r = p & 0xFF;
			int g = (p>>8) & 0xFF;
			int b = (p>>16) & 0xFF;
			// Mittelwert errechnen
			int m = (int)((r+g+b)/3.0/2.55);
			return m;
		}catch(Exception e){
			return 0;
		}
    }
	
	
	/**
	 * Gibt dem TabItem das Label in der Statusbar bekannt
	 * @param stat Label in der Statusbar
	 */
	public void setStatusbarLabel(Label stat){
		statLbl = stat;
	}	
	
	/**
	 * Schickt ein ImageRequest-Command an den Server
	 */
	public void sendImageRequest(){
		netHandler.getComQueue().enqueueFirst(new Command(NetPack.IMAGEREQUEST));
	}
	
	/**
	 * Vom FTP-Server Bild laden
	 */
	public void refreshCamPic(){
		// ausgewähltes Bild holen
		String sPic = "cam.jpg";
		String sPath = PathHelp.specDirImageSep() + sPic;
		// Kontrolle ob File bereits downgeloadet wurde
		File f = new File(sPath);
		if(f.exists()) f.delete();
		// Download
		netHandler.getFTPModule().receiveFile(sPic,PathHelp.specDirImageSep());
		// Bild anzeigen
		try{
			img = new Image(dDisplay, sPath);
			gContext.drawImage(img,0,0);
		}catch(Exception e){
			System.out.println("Fehlerhaftes Cam-Bild");
		}
	}

	/**
	 * Bricht die dynamische Auswahl ab
	 */
	public void cancelDynamicCmdSelect() {
		bIsDynCmdSelect=false;
		bRefresh.setEnabled(bConnected);
	}

	/**
	 * Startet die dynamische Auswahl
	 * @param cmd Commando für die dynamische Auswahl
	 */
	public void startDynamicCmdSelect(String cmd) {
		bIsDynCmdSelect=true;
		bRefresh.setEnabled(false);
	}

	/* ##########################################################################
	 * 						HILFSMETHODEN
	 * ##########################################################################*/
	
	/**
	 * Stoppt die dynamische Auswahl von Commands
	 * @param sel String der das Kommando nach dynamischer Auswahl repräsentiert
	 */
	private void stopDynamicCmdSelect(String sel){
		cancelDynamicCmdSelect();
		mainShell.stopDynamicCommandSelect("CamIf("+sel+")");
	}

	/**
	 * Zeigt Informationen in der Statusbar an
	 * @param x X-Koordinate
	 * @param y Y-Koordinate
	 * @param c Farbwert
	 * @param s Scattering, weil bei 0 ignoriert
	 */
	private void showStatusText(int x, int y, int c, int s){
		// in Statusbar anzeigen
		String str = "X: " + x + ", Y: " + y + ", F: " + c;
		if(s>0) str += ", S: " + s;
		statLbl.setText(str);
	}	
	
}
