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.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
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.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import other.DynamicCmdSelector;
import other.MsgBox;
import other.PathHelp;

/**
 * TabItemObsDef Klasse 
 * Dient zum Erzeugen, Bearbeiten und Löschen von Hindernisdefinitionen
 * (Graustufenbitmaps). Die Bitmaps können lokal oder via FTP geladen und 
 * gespeichert werden
 */
public class TabItemObsDef extends Composite implements DynamicCmdSelector {

	// Attribute
	private Display dDisplay = null;
	private Canvas cCanvas = null;
	private Canvas cColor = null;
	private GC gContext = null;
	private Image img = null;
	private Obstacle oObstacle = null;	
	private Group gColor = null;
	private Group gPics = null;
	private Group gCanvas = null;
	private Group gDrawInfo = null;
	private Text tColor = null;
	private Label statLbl = null;
	private Button bLoadFTP = null;
	private Button bSaveFTP = null;
	private Button bDelete = null;
	private Button bUsePic = null;
	private Button bDrawRect = null;
	private Button bDrawCircle = null;
	private Table tTable = null;
	private Composite cBtnComp = null;
	private MainShell mainShell = null;
	private NetworkHandler netHandler = null;
	
	private boolean bStart;
	private boolean bChangeColor = true ;
	private boolean bDraw = true ;
	private boolean bRect;
	private boolean bCircle;
	private boolean bClick;
	private String sPath = "";
	private int iColor = 0;
	boolean bIsDynCmdSelect = false;
	boolean bConnected = false;
	boolean bLoadBitmapSelect = false;
	String sDynCmdSelect = "";
	
	/**
	 * Konstruktor
	 * @param mainSh Referenz auf die MainShell
	 * @param display das erzeugte Display
	 * @param parent das Parent Composite
	 * @param style der SWT Style
	 * @param netH das vorherrschende NetworkHandler Objekt
	 */
	public TabItemObsDef(MainShell mainSh, Display display,Composite parent, int style, NetworkHandler netH) {
		super(parent, style);
		mainShell=mainSh;
		dDisplay=display;
		// Für die FTP Verbindung
		netHandler = netH;
		// Damit die Canvas schwarz gezeichnet wird
		bStart=true;
		initialize();
		// Image zur Zwischenspeicherung der Arbeitsfläche
        img = new Image(display,PathHelp.specFileObsImg());
        oObstacle = new Obstacle();
        // Rechteckswerkzeug auswählen
        setRect();
        // noch keine Verbindung
        setGroupBoxState(false);
	}
	
	/* ##########################################################################
	 * 						VISUAL EDITOR
	 * ##########################################################################*/

	/**
	 * Initialisiert den ObstacleDefiner und erwirkt das Erzeugen und
	 * Anordnen aller Komponeten
	 */
	private void initialize() {
		createCanvasGroup();
        createColorGroup();
        createDrawInfoGroup();
        createPicsGroup();
        // für Groupbox Resize
		this.addControlListener(new org.eclipse.swt.events.ControlAdapter() {
			public void controlResized(org.eclipse.swt.events.ControlEvent e) {
				adjustGroupBoxSize();
			}
		});
	}

	/**
	 * Initialisiert die Groupbox, welche den Zeichenbereich
	 * (das große Canvas) enthält
	 */    
	private void createCanvasGroup() {
		// Groupbox
		gCanvas = new Group(this, SWT.NONE);		   
		gCanvas.setText("Arbeitsraum");
		// Canvas
        cCanvas = new Canvas(gCanvas, SWT.NONE);
        cCanvas.setSize(512,512);
        cCanvas.setLocation(15,20);
        cCanvas.setCursor(new Cursor(dDisplay,SWT.CURSOR_CROSS));
	    gContext = new GC(cCanvas);

        cCanvas.addPaintListener(new PaintListener(){
		public void paintControl(PaintEvent e) {
			//schwarzen Hintergrund in img zeichnen
			if(bStart){ 
				gContext.setBackground(dDisplay.getSystemColor(SWT.COLOR_BLACK));
				gContext.fillRectangle(0,0,512,512);
				gContext.copyArea(img,0,0);
				bStart=false;
            //zwischengespeichertes Bild wieder anzeigen
			}else{
				gContext.drawImage(img,0,0);
			}
		}
        });
        cCanvas.addMouseListener(new MouseListener(){
			public void mouseDoubleClick(MouseEvent e) { }
			//Mause wurde geklickt
			public void mouseDown(MouseEvent e) {
				// Dyn. Auswahl: MovePos oder Offset
				if(bIsDynCmdSelect&&!bRect&&!bCircle){
					// nix
				}else{
					oObstacle.setParam(0,e.x);
					oObstacle.setParam(1,e.y);	
					bClick=true;
					bDraw = true;
				}
			}
			//Maus wurde losgelassen
			public void mouseUp(MouseEvent e) {
				// Dynamische Auswahl
				if(bIsDynCmdSelect){
					if(bRect){
						// Werte holen
						int x1 = 2*e.x-512;
						int y1 = 512-2*e.y;
						int x2 = 2*oObstacle.getParam(0)-512;
						int y2 = 512-2*oObstacle.getParam(1);
						// Richtung sicherstellen
						int x, y;
						if(x1<x2) x=x1; else x=x2;
						if(y1>y2) y=y1; else y=y2;
						int l=Math.abs(x1-x2);
						int b=Math.abs(y1-y2);
						// Command ersetzen
						stopDynamicCmdSelect(x+","+y+","+tColor.getText()+",ka,"+l+","+b);
					}else if(bCircle){
						int x = 2*oObstacle.getParam(0)-512;
						int y = 512-2*oObstacle.getParam(1);
						double dX2 = Math.pow(Double.parseDouble(Integer.toString(e.x))-Double.parseDouble(Integer.toString(oObstacle.getParam(0))),2);
						double dY2 = Math.pow(Double.parseDouble(Integer.toString(e.y))-Double.parseDouble(Integer.toString(oObstacle.getParam(1))),2);	
						long r = Math.round(Math.sqrt(dX2+dY2));
						stopDynamicCmdSelect(x+","+y+","+tColor.getText()+",ka,"+r);
					}else{
						stopDynamicCmdSelect(Integer.toString(2*e.x-512)+","+
								Integer.toString(512-2*e.y)+","+tColor.getText()+",ka");
					}
					bClick=false;
				}else{
					oObstacle.setParam(2,e.x);
					oObstacle.setParam(3,e.y);
					if(bRect)
						oObstacle.setType('R');
					else if(bCircle)
						oObstacle.setType('C');
					//Objekt zeichnen
					bClick=false;
					drawObstacle();
				}
			}
        
        });
        cCanvas.addMouseMoveListener(new MouseMoveListener(){
        	//Maus wurde bewegt
			public void mouseMove(MouseEvent e) {
				String sPos;
				if(bClick && bCircle){
					//Radius zum Anzeigen berechnen	
					double dX2 = Math.pow(Double.parseDouble(Integer.toString(e.x))-Double.parseDouble(Integer.toString(oObstacle.getParam(0))),2);
					double dY2 = Math.pow(Double.parseDouble(Integer.toString(e.y))-Double.parseDouble(Integer.toString(oObstacle.getParam(1))),2);	
					Double dRadius = new Double(Math.sqrt(dX2+dY2));
					sPos="Radius: "+Integer.toString(dRadius.intValue());
				}else{
					sPos="X: "+Integer.toString(2*e.x-512)+", Y: "+Integer.toString(512-2*e.y); 
				}
				statLbl.setText(sPos);
			}	
        });
        gCanvas.setBounds(new org.eclipse.swt.graphics.Rectangle(160,10,542,548));
	}
	
	/**
	 * Initialisiert die Groupbox, auf der das Werkzeug ausgewählt werden kann
	 */    
	private void createDrawInfoGroup() {
		// Groupbox
		gDrawInfo = new Group(this, SWT.NONE);		   
		gDrawInfo.setText("Werkzeugwahl");
		// Label
		// Werkzeugauswahl
        bDrawRect = new Button(gDrawInfo, SWT.NONE);
        bDrawRect.setBounds(new org.eclipse.swt.graphics.Rectangle(10,50,114,25));
        bDrawRect.setText("Rechteck");
        bDrawRect.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { 
        	public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {    
        		setRect();
        	}
        });
        bDrawCircle = new Button(gDrawInfo, SWT.NONE);
        bDrawCircle.setBounds(new org.eclipse.swt.graphics.Rectangle(10,90,114,25));
        bDrawCircle.setText("Kreis");
        bDrawCircle.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { 
        	public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {    
        		setCircle();
        	}
        });
        // Fertig
        gDrawInfo.setBounds(new org.eclipse.swt.graphics.Rectangle(10,370,134,188));
	}
	
	/**
	 * Initialisiert die Groupbox, auf der die Farbauswahl zu finden ist	
	 */    
	private void createColorGroup() {
		// Groupbox
		gColor = new Group(this, SWT.NONE);		   
		gColor.setText("Farbe");
		// Textbox für Farbe
		tColor = new Text(gColor, SWT.NONE | SWT.BORDER);
		tColor.setBounds(new org.eclipse.swt.graphics.Rectangle(35,296,62,19));
		tColor.setText("0");
		tColor.setEditable(false);
        // Color Canvas
        cColor = new Canvas(gColor, SWT.NONE);
        cColor.setSize(100,256);
        cColor.setLocation(16,32);
        cColor.setBackground(dDisplay.getSystemColor(SWT.COLOR_BLACK));
        cColor.setCursor(new Cursor(dDisplay,SWT.CURSOR_CROSS));
        cColor.addPaintListener(new PaintListener(){
			public void paintControl(PaintEvent e) {
		        GC gc = new GC(cColor);
		        //Farblehre anzeigen
				for(int i=0;i<256;i++){
					gc.setForeground(new Color(dDisplay,i,i,i));
					gc.drawLine(0,255-i,100,255-i);
				}
				// Rahmen zeichen
				gc.setForeground(new Color(dDisplay,0,0,0));
				gc.drawRectangle(0, 0, 99, 256);
			}
        });
        cColor.addMouseListener(new MouseListener(){
			public void mouseDoubleClick(MouseEvent e) { }
			public void mouseDown(MouseEvent e) {
				// Mause wurde geklickt
				iColor = 255-e.y;
				bChangeColor = false;
			}
			public void mouseUp(MouseEvent e) { }
        });
        cColor.addMouseMoveListener(new MouseMoveListener(){
			public void mouseMove(MouseEvent e) {	
				// Maus wurde bewegt => Flag, dass Color geändert werden soll
				if(bChangeColor) tColor.setText(Integer.toString(2*(255-e.y)));
			}
        });
        cColor.addMouseTrackListener(new org.eclipse.swt.events.MouseTrackAdapter() {
        	public void mouseEnter(org.eclipse.swt.events.MouseEvent e) {    
        		// Canvas wurde "betreten"
        		bChangeColor = true; //der Farbwert wird enabled
        	}
        	public void mouseExit(org.eclipse.swt.events.MouseEvent e) {    
        		// Canvas wurde "Verlassen"        		
        		tColor.setText(Integer.toString(2*iColor)); //der Farbwert wird enabled
        	}
        });
		gColor.setBounds(new org.eclipse.swt.graphics.Rectangle(10,10,134,350));
	}
	
	/**
	 * Initialisiert die Groupbox auf der die Bilder aufgelistet sind
	 * (Inhalt ist eine einspaltige Tabelle die alle Bilder auflistet)	
	 */    
	private void createPicsGroup() {
		// Groupbox
		gPics = new Group(this, SWT.NONE);
		gPics.setText("Roboterspeicher");
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 2;
		gPics.setLayout(gridLayout);
		// Composite, das die Buttons enthält
		FillLayout fillLayout = new FillLayout();
		fillLayout.type = org.eclipse.swt.SWT.VERTICAL;
		fillLayout.spacing = 8;
		GridData gridData1 = new GridData();
		gridData1.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
		gridData1.verticalAlignment = org.eclipse.swt.layout.GridData.CENTER;
		cBtnComp = new Composite(gPics, SWT.NONE);
		cBtnComp.setLayoutData(gridData1);
		cBtnComp.setLayout(fillLayout);
		// Buttons
		bLoadFTP = new Button(cBtnComp, SWT.NONE);
        bLoadFTP.setText("<");
        bLoadFTP.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { 
        	public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {    
        		loadFTP();
        	}
        });
        bSaveFTP = new Button(cBtnComp, SWT.NONE);
        bSaveFTP.setText(">");
        bSaveFTP.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { 
        	public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {    
        		saveFTP();
        	}
        });
        Label lFiller = new Label(cBtnComp, SWT.NONE);
        lFiller.setText("");
        bDelete = new Button(cBtnComp, SWT.NONE);
        bDelete.setText("Löschen");
        bDelete.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { 
        	public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {    
        		clickBDelete();
        	}
        });
        Label lFiller2 = new Label(cBtnComp, SWT.NONE);
        lFiller2.setText("");
        bUsePic = new Button(cBtnComp, SWT.NONE);
        bUsePic.setText("Verwenden");
        bUsePic.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { 
        	public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {    
        		clickUsePic();
        	}
        });
        // Tabelle und fertig
        createTable();
		gPics.setBounds(new org.eclipse.swt.graphics.Rectangle(717,10,220,548));
	}
	
	/**
	 * Diese Methode initialisiert die Tabelle die alle Bilder auflistet
	 */    
	private void createTable() {
		// Griddata fürs Layout
		GridData gridData = new GridData();
		gridData.grabExcessHorizontalSpace = true;
		gridData.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
		gridData.verticalAlignment = org.eclipse.swt.layout.GridData.FILL;
		gridData.grabExcessVerticalSpace = true;
		tTable = new Table(gPics, SWT.FULL_SELECTION);
		tTable.setHeaderVisible(true);
		tTable.setLinesVisible(true);
        tTable.setFont(new org.eclipse.swt.graphics.Font(org.eclipse.swt.widgets.Display.getDefault(), "Tahoma", 10, org.eclipse.swt.SWT.NORMAL));
		tTable.setLayoutData(gridData);
		TableColumn tcPic = new TableColumn(tTable,SWT.NONE);
		tcPic.setText("Bildname");
		tcPic.setWidth(120+200);
		tcPic.setResizable(false);
		tTable.setSortColumn(tcPic);
		tTable.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { 
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				if(bIsDynCmdSelect){
					String s = tTable.getItem(tTable.getSelectionIndex()).getText(0);
					if(bLoadBitmapSelect)
						stopDynamicCmdSelect(s+",true");
					else
						stopDynamicCmdSelect(s);
				}
			}
		});
		refreshTable();
	}

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

	/* ##########################################################################
	 * 						ÖFFENTLICHE METHODEN
	 * ##########################################################################*/	
	
	/**
	 * Gibt dem TabItem das Label in der Statusbar bekannt
	 * @param stat Label in der Statusbar
	 */
	public void setStatusbarLabel(Label stat){
		statLbl = stat;
	}	
	
	/**
	 * Ein neues Bild beginnen
	 */
	public void newPicture(){
		gContext.setBackground(dDisplay.getSystemColor(SWT.COLOR_BLACK));
		gContext.fillRectangle(0,0,512,512);
		sPath="";
	}
	
	/**
	 * Lädt ein Graustufenbitmap aus einem lokalen Verzeichnis
	 */
	public void loadLocal(){
		// Öffnen-Dialog anzeigen
		bDraw = false;
		FileDialog fileDialog = new FileDialog(new Shell(), SWT.OPEN);
		fileDialog.setText("Bild laden");
		fileDialog.setFilterExtensions(new String[]{"*.bmp","*.*"});
		String path = fileDialog.open();
		if(path==null) return;
		
		//Bild anzeigen
		img = new Image(dDisplay, path);
		gContext.drawImage(img,0,0);
		sPath = path;
	}
	
	/**
	 * Speichert in ein lokales Verzeichnis, wenn bereits davor 
	 * gespeichert wurde (ein Verzeichnis wurde bereits zuvor ausgewählt)
	 */
	public void saveLocal(){
		if(sPath.length()<=1)
			saveLocalAs();
		else
			savePictureLocal(sPath);
	}
	
	/**
	 * In ein locales Verzeichnis speichern mit Auswahl des 
	 * gewünschten Verzeichnisses
	 */
	public void saveLocalAs(){
		//Öffnen-Dialog anzeigen
		FileDialog fileDialog = new FileDialog(new Shell(), SWT.SAVE);
		fileDialog.setText("Bild speichern");
		fileDialog.setFilterExtensions(new String[]{"*.bmp","*.*"});
		String path = fileDialog.open();
		if(path!=null){
			sPath = path;
			savePictureLocal(sPath);
		}
	}
	
	/**
	 * Lädt ein Bild vom FTP Server in die Zeichenfläche
	 * gegebenenfalls zuerst downloaden und dann lokal öffnen
	 */
	public void loadFTP(){
		if(tTable.getSelectionIndex()<0) return; //wenn kein Eintrag gewählt wurde
		// ausgewähltes Bild holen
		String sPic = tTable.getItem(tTable.getSelectionIndex()).getText() + ".bmp";
		String sPath = PathHelp.specDirImageSep() + sPic;
		// Kontrolle ob File bereits downgeloadet wurde
		if(!(new File(sPath).exists()))
			netHandler.getFTPModule().receiveFile(sPic,PathHelp.specDirImageSep());
		// Bild anzeigen
		try{
		  img = new Image(dDisplay, sPath);
		  gContext.drawImage(img,0,0);
		}catch(Exception e){
			MsgBox.showError("Dieses Bild kann nicht angezeigt werden!");
		}
	}

	/**
	 * Speichert ein Bild zuerst in einem lokalen Hilfsverzeichnis ab
	 * und lädt es anschließend mit der entsprechenden Funktion auf den 
	 * FTP Server hoch
	 */
	public void saveFTP(){
		InputDialog dlg = new InputDialog(this.getShell());
		dlg.setText("Bitte Dateinamen eingeben:");
		String sName = dlg.open();
		// Auf Abbrechen geklickt
		if(sName.length()<2) return;
		//Das Bild unter dem Pfad speichern
		String sPath = PathHelp.specDirImageSep() + sName + ".bmp";
		savePictureLocal(sPath);
		netHandler.getFTPModule().uploadFile(sPath); //Uploaden
		refreshTable(); //Tabelle neu laden
	}
	

	
	/**
	 * Wählt das Rechteckswerkzeug aus
	 */
	public void setRect(){
		bRect=true;
		bCircle=false;
	}

	/**
	 * Wählt das Kreiswerkzeug aus
	 */
	public void setCircle(){
		bCircle=true;
		bRect=false;
	}

	/**
	 * Überprüft, ob Bitmaps in der Tabelle stehen
	 * @return true wenn Bilder in der Tabelle vorhanden sind, sonst false
	 */
	public boolean isBitmapSelectionPossible(){
		return (tTable.getItemCount()>0);
	}
	
	/**
	 * Bricht die dynamische Auswahl von Commands ab
	 */
	public void cancelDynamicCmdSelect() {
		bIsDynCmdSelect=false;
		setRect();
		// Widgets wieder einschalten
		setToolButtonsState(true);
		setGroupBoxState(bConnected);
	}

	/**
	 * Startet die dynamische Auswahl von Commands
	 * @param cmd String der zu dynamisch auszuwählendes Kommando enthält
	 */
	public void startDynamicCmdSelect(String cmd) {
		bIsDynCmdSelect=true;
		// Auswählen, was verwendet werden soll
		boolean canvas = false;
		if(cmd.equals("moveposition")){
			sDynCmdSelect="MovePosition";
			bCircle=false;
			bRect=false;
			canvas=true;
		}else if(cmd.equals("offset")){
			sDynCmdSelect="Offset";
			bCircle=false;
			bRect=false;
			canvas=true;
		}else if(cmd.equals("defineobstaclecircle")){
			sDynCmdSelect="DefineObstacleCircle";
			setCircle();
			canvas=true;
		}else if(cmd.equals("defineobstaclerect")){
			sDynCmdSelect="DefineObstacleRect";
			setRect();
			canvas=true;
		}else if(cmd.equals("loadbitmap")){
			sDynCmdSelect="LoadBitmap";
			bLoadBitmapSelect=true;
		}else if(cmd.equals("savebitmap")){
			sDynCmdSelect="SaveBitmap";
			bLoadBitmapSelect=false;
		}
		// Werkzeugauswahl ausschalten
		setToolButtonsState(false);
		// Controls disablen:
		setGroupBoxState(false);
		if(!canvas) tTable.setEnabled(true);
	}

	/**
	 * Lädt die Tabelle nach Veränderungen neu
	 */
	public void refreshTable(){
		
		boolean bSel = false;
		String selName = "";
		
		//aktuelle Selektion holen
		try{
		 selName = tTable.getItem(tTable.getSelectionIndex()).toString();
		 bSel = true;
		}catch(Exception e){ }
		
		// Tabelle leeren
		tTable.removeAll();
		// Files adden
		String sFiles[] = netHandler.getFTPModule().listFiles();
		try{
			for(int i=0;i<sFiles.length;i++){
				if(sFiles[i].endsWith(".bmp")){
					TableItem ti = new TableItem(tTable,SWT.NONE);
					ti.setText(sFiles[i].substring(0,sFiles[i].lastIndexOf(".")));
				}
			}
		}catch(Exception e){ }
		// Selektion wieder setzen
		int n=0;
		while(n<tTable.getItemCount() && bSel){
		 if((tTable.getItem(n).toString()).equals(selName)){
		  tTable.setSelection(n);
		  break;
		 }
		 n++;
		}
	}	
	
	/* ##########################################################################
	 * 						HILFSMETHODEN
	 * ##########################################################################*/	
	
	/**
	 * Stoppt die dynamische Auswahl von Commands
	 * @param cmd dynamisch ausgewähltes Kommando mit gesetzten Parametern als String
	 */
	private void stopDynamicCmdSelect(String sel){
		cancelDynamicCmdSelect();
		mainShell.stopDynamicCommandSelect(sDynCmdSelect+"("+sel+")");
	}

	/**
	 * Löschen-Button wurde geklickt
	 * Veranlasst, dass das ausgewählte Bild vom FTP Server
	 * gelöscht wird
	 */
	private void clickBDelete(){
		if(tTable.getSelectionIndex()<0) return; //wenn kein Eintrag gewählt wurde
		if(MsgBox.showYesNoQuestion("Wollen Sie dieses Bild wirklich löschen?")){
			String sPic = tTable.getItem(tTable.getSelectionIndex()).getText();
			netHandler.getFTPModule().deleteFile(sPic+".bmp");
			tTable.remove(tTable.getSelectionIndex());
		}
	}

	/**
	 * Verwenden Button wurde geklickt
	 * Veranlasst, dass das ausgewählte Bild in den Roboterspeicher
	 * geladen wird
	 */
	private void clickUsePic(){
		if(tTable.getSelectionIndex()<0) return; //wenn kein Eintrag gewählt wurde
		String sPic = tTable.getItem(tTable.getSelectionIndex()).getText();
		netHandler.getComQueue().enqueue(new Command(NetPack.LOAD_BITMAP,0,sPic));
	}	
	
	/**
	 * Zeichnet ein Hindernis, dessen Parameter im Objekt oObstacle
	 * zuvor durch Benutzerinteraktionen (Farbwahl + Zeichnen) zwischengespeichert
	 * wurden
	 */
	private void drawObstacle(){

		if(!bDraw) return;
		int iCValue=0;
		
		//Höhenwert = Farbwert ermitteln
		try{
		 iCValue=Integer.parseInt(tColor.getText())/2;
		}catch(NumberFormatException e){
		 MsgBox.showError("Kein gültiger Höhenwert!");
		 return;
		}
		
		if(iCValue<0){ 
		 iCValue=iColor=0;
		 tColor.setText("0");
		}
		if(iCValue>255){
		 iCValue=iColor=255;
		 tColor.setText("512");
		}
		
		//Farbe erzeugen u. setzen
        Color cColor = new Color(dDisplay,iCValue,iCValue, iCValue);
        gContext.setBackground(cColor);

        //Rechteck zeichnen
        if(oObstacle.getType()=='R'){
         gContext.fillRectangle(oObstacle.getParam(0),oObstacle.getParam(1),
        					    oObstacle.getParam(2)-oObstacle.getParam(0),
							    oObstacle.getParam(3)-oObstacle.getParam(1));
        }
        //Kreis zeichnen
        else if(oObstacle.getType()=='C'){
        	
          //Radius berechnen	
		  double dX2 = Math.pow(Double.parseDouble(Integer.toString(oObstacle.getParam(2)))-Double.parseDouble(Integer.toString(oObstacle.getParam(0))),2);
		  double dY2 = Math.pow(Double.parseDouble(Integer.toString(oObstacle.getParam(3)))-Double.parseDouble(Integer.toString(oObstacle.getParam(1))),2);	
		  Double dRadius = new Double(Math.sqrt(dX2+dY2));
		  
		 //Kreis zeichen
          gContext.fillOval(oObstacle.getParam(0)-dRadius.intValue(),oObstacle.getParam(1)-dRadius.intValue(),
					   	    2*dRadius.intValue(),
					   	    2*dRadius.intValue());	
        }
		
        gContext.copyArea(img,0,0);

	}
	
	/**
	 * Sichert das in der Variable img gespeicherte Bild lokal
	 * @param path der Pfad für die Sicherung
	 */
	private void savePictureLocal(String path){
		ImageLoader iLoader = new ImageLoader();
		iLoader.data = new ImageData[] { img.getImageData() };
		iLoader.save(path,SWT.IMAGE_BMP);	
	}
	
	/**
	 * Schaltet die Elemente der FTP-GroupBox ein oder aus
	 * @param enabled gibt an, ob die Elemente enabled sein sollen (true), oder nicht (false)
	 */
	private void setGroupBoxState(boolean enabled){
		bLoadFTP.setEnabled(enabled);
		bSaveFTP.setEnabled(enabled);
		bDelete.setEnabled(enabled);
		bUsePic.setEnabled(enabled);
		tTable.setEnabled(enabled);
	}

	/**
	 * Schaltet die Buttons für die Werkzeugwahl ein oder aus
	 * @param enabled gibt an, ob die Buttons enabled sein sollen (true), oder nicht (false)
	 */
	private void setToolButtonsState(boolean enabled){
		bDrawRect.setEnabled(enabled);
		bDrawCircle.setEnabled(enabled);
	}
	
	/**
	 * Passt die Größe der Groupbox mit der Tabelle an die
	 * Größe des Fensters an
	 */
	private void adjustGroupBoxSize(){
		int a = this.getSize().x - 732;
		if(a>0) gPics.setSize(a, gPics.getSize().y);
	}
	
	/* ##########################################################################
	 * 						INNERE KLASSE
	 * ##########################################################################*/
	
	/** Obstacle Klasse
	 * Dient zum Zwischenspeichern der vom Benutzer gewählten Werte
	 * zum späteren Zeichnen von Hindernissen
	 */
	private class Obstacle{
		
		// Attribute
		char cType;
		int iParam[] = new int[4];
		
		//Get- u. Set-Methode
		public char getType(){ return cType; }
		public int getParam(int iIndex){ return iParam[iIndex]; }
		public void setType(char pType){ cType=pType; }
		public void setParam(int iIndex,int iValue){ iParam[iIndex]=iValue; }
	}
}
