package gui;
 
import network.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CBanner;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
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 org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import other.*;
import other.ConnectionNotifier;
import other.DynamicCmdSelector;
    
/**
 * MainShell Klasse
 * Diese Klasse stellt das Hauptfenster dar und implementiert
 * das ConnectionNotifier Interface zur Kommunikation mit 
 * untergeordneten Composites
 */
public class MainShell implements ConnectionNotifier {
      
	// Attribute
	private Shell sShell = null;  
	private Menu menuBar = null;
	private Menu submenu = null;
	private Menu submenu1 = null;
	private CBanner cBanner = null;
	private ToolBar toolBar = null;
	private TabFolder tabFolder = null;
	private Composite composite = null;
	private Label label = null;
	private Label label1 = null;
	private Label label2 = null;
	private NetworkHandler netHandler = null;
	private Canvas canvas = null;
	private Menu submenu2 = null;
	private Menu submenu3 = null;
	private Menu submenu4 = null;
	private TabItemProgram tabItemProgram = null;
	private TabItemObsDef tabItemObsDef = null;
	private TabItemTransObj tabItemTransObj = null;
	private TabItemManual tabItemManual = null;
	private TabItemCam tabItemCam = null;
	private Menu submenu5 = null;
	private SettingsHandler setHandler = null;
	private boolean bConnectionCmd = true;
	private boolean bConnectionSql = false;
	private boolean bConnectionFtp = false;
	private int dynCmdSelectLine;
	private DynamicCmdSelector dynCmdSelect = null;
	
	// TabItem Indizes
	final int TAB_PRG = 0;
	final int TAB_TRANSOBJ = 1;
	final int TAB_OBSDEF = 2;
	final int TAB_MAN = 3;
	final int TAB_CAM = 4;
	
	/**
	 * Konstruktor. Erzeugt die Shell
	 */
	public MainShell(){
		// Einstellungen lesen
		setHandler = new SettingsHandler();
		// NetHandler erzeugen
		netHandler = new NetworkHandler(this, setHandler.getData());
		// Shell erzeugen
		createSShell();
		// Evtl. maximieren
		if(setHandler.getData().startMaximized) sShell.setMaximized(true);
	}

	/* ##########################################################################
	 * 						VISUAL EDITOR
	 * ##########################################################################*/	
	
	/**
	 * Erzeugt die Shell und ordnet alle Elemente auf dieser an
	 */
	private void createSShell() {
		GridLayout gridLayout = new GridLayout();
		gridLayout.horizontalSpacing = 1;
		gridLayout.marginWidth = 1;
		gridLayout.verticalSpacing = 5;
		gridLayout.numColumns = 1;
		gridLayout.marginHeight = 1;
		sShell = new Shell();
		sShell.setText("Robotix Client");
		sShell.setMaximized(false);
		sShell.setLayout(gridLayout);
		createCBanner();
		createTabFolder();
		createComposite();
		sShell.setBounds(new org.eclipse.swt.graphics.Rectangle(22,29,970,700));
		menuBar = new Menu(getShell(), SWT.BAR);
		MenuItem submenuItem = new MenuItem(menuBar, SWT.CASCADE);
		submenuItem.setText("Datei");
		MenuItem submenuItem2 = new MenuItem(menuBar, SWT.CASCADE);
		submenuItem2.setText("Verbindung");
		MenuItem submenuItem5 = new MenuItem(menuBar, SWT.CASCADE);
		submenuItem5.setText("Programm");
		submenu5 = new Menu(submenuItem5);
		MenuItem push15 = new MenuItem(submenu5, SWT.PUSH);
		push15.setText("Starten");
		push15.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Right1.png")));
		MenuItem push18 = new MenuItem(submenu5, SWT.PUSH);
		push15.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				startEvent();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		MenuItem push16 = new MenuItem(submenu5, SWT.PUSH);
		push16.setText("Parsen");
		push16.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Forward.png")));
		push16.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				 tabItemProgram.parseProgramOnly();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		MenuItem separator3 = new MenuItem(submenu5, SWT.SEPARATOR);
		MenuItem push17 = new MenuItem(submenu5, SWT.PUSH);
		push17.setText("Sofortiger Halt");
		push17.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Error.png")));
		push18.setText("Starten (Endlosschleife)");
		push18.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Right1b.png")));
		push18.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				tabItemProgram.parseProgramAndRun(1000,setHandler.getData().cmdPassw);
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		push17.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				tabItemProgram.immediateHalt();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
		});
		submenuItem5.setMenu(submenu5);
		submenu2 = new Menu(submenuItem2);
		submenuItem2.setMenu(submenu2);
		MenuItem submenuItem3 = new MenuItem(submenu2, SWT.CASCADE);
		submenuItem3.setText("Verbinden");
		MenuItem submenuItem4 = new MenuItem(submenu2, SWT.CASCADE);
		submenuItem4.setText("Trennen");
		MenuItem separator1 = new MenuItem(submenu2, SWT.SEPARATOR);
		MenuItem push12 = new MenuItem(submenu2, SWT.PUSH);
		push12.setText("Alle verbinden");
		push12.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Check.png")));
		push12.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				netHandler.startTimer();
				label.setText("Verbinden...");
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		MenuItem push13 = new MenuItem(submenu2, SWT.PUSH);
		push13.setText("Alle trennen");
		push13.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Block.png")));
		push13.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				netHandler.stopTimer();
				label.setText("Nicht verbunden");
				netHandler.disconnect();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		MenuItem separator2 = new MenuItem(submenu2, SWT.SEPARATOR);
		MenuItem push14 = new MenuItem(submenu2, SWT.PUSH);
		push14.setText("Einstellungen...");
		push14.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				// Verbindung beenden
				netHandler.stopTimer();
				label.setText("Nicht verbunden");
				netHandler.disconnect();
				// Dialog öffnen
				SettingsDialog dlg = new SettingsDialog(sShell, setHandler);
				dlg.open();
				netHandler.updateSettings(setHandler.getData());
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		submenu4 = new Menu(submenuItem4);
		MenuItem push9 = new MenuItem(submenu4, SWT.PUSH);
		push9.setText("Command");
		push9.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				 netHandler.disconnectCmd();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		MenuItem push10 = new MenuItem(submenu4, SWT.PUSH);
		push10.setText("SQL");
		push10.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				netHandler.disconnectSql();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		MenuItem push11 = new MenuItem(submenu4, SWT.PUSH);
		push11.setText("FTP");
		push11.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				netHandler.disconnectFtp();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		submenuItem4.setMenu(submenu4);
		submenu3 = new Menu(submenuItem3);
		MenuItem push6 = new MenuItem(submenu3, SWT.PUSH);
		push6.setText("Command");
		push6.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				label.setText("Verbinden...");
				netHandler.connectCmd();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		MenuItem push7 = new MenuItem(submenu3, SWT.PUSH);
		push7.setText("SQL");
		push7.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				label.setText("Verbinden...");
				netHandler.connectSql();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		MenuItem push8 = new MenuItem(submenu3, SWT.PUSH);
		push8.setText("FTP");
		push8.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				label.setText("Verbinden...");
				netHandler.connectFtp();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		submenuItem3.setMenu(submenu3);
		MenuItem submenuItem1 = new MenuItem(menuBar, SWT.CASCADE);
		submenuItem1.setText("?");
		submenu1 = new Menu(submenuItem1);
		MenuItem push1 = new MenuItem(submenu1, SWT.PUSH);
		push1.setText("Info");
		push1.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Help.png")));
		submenuItem1.setMenu(submenu1);
		submenu = new Menu(submenuItem);
		MenuItem push2 = new MenuItem(submenu, SWT.PUSH);
		push2.setText("Neu");
		push2.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"File.png")));
		push2.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				newEvent();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
		});
		MenuItem push3 = new MenuItem(submenu, SWT.PUSH);
		push3.setText("Öffnen...");
		push3.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Open.png")));
		push3.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				openEvent(); 
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
		});
		MenuItem push4 = new MenuItem(submenu, SWT.PUSH);
		push4.setText("Speichern");
		push4.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Save.png")));
		push4.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				saveEvent();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
		});
		MenuItem push5 = new MenuItem(submenu, SWT.PUSH);
		push5.setText("Speichern unter...");
		push5.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Save_As.png")));
		push5.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				saveAsEvent();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
		});
		MenuItem separator = new MenuItem(submenu, SWT.SEPARATOR);
		MenuItem push = new MenuItem(submenu, SWT.PUSH);
		push.setText("Beenden");
		push.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Exit.png")));
		submenuItem.setMenu(submenu);
		sShell.setMenuBar(menuBar);
		sShell.addShellListener(new org.eclipse.swt.events.ShellAdapter() {
			public void shellClosed(org.eclipse.swt.events.ShellEvent e) {
				// Den TabItems die Möglichkeit geben, Dinge zu speichern
				if(tabItemProgram.closeAll()){
					e.doit = false; // auf Cancel geklickt
					return;
				}
				// Netzwerkverbindungen auflösen
				netHandler.disconnect();
				// Programm komplett beenden [bzw. abwürgen ;-) ]
				System.exit(0);
			}
		});
	}
	
	/**
	 * Erzeugt ein Bannerobjekt zur Aufname der Toolbar
	 */
	private void createCBanner() {
		cBanner = new CBanner(getShell(), SWT.NONE);
		createToolBar();
		cBanner.setLeft(toolBar);
	}
	
	/**
	 * Diese Methode initialisiert die Tollbar und ordnet alle
	 * Elemente auf dieser an
	 */
	private void createToolBar() {
		toolBar = new ToolBar(cBanner, SWT.NONE);
		ToolItem toolItem = new ToolItem(toolBar, SWT.PUSH);
		toolItem.setText("");
		toolItem.setToolTipText("Neu");
		toolItem.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"File.png")));
		toolItem.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				newEvent();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
		});
		ToolItem toolItem1 = new ToolItem(toolBar, SWT.PUSH);
		toolItem1.setText("");
		toolItem1.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Open.png")));
		toolItem1.setToolTipText("Öffnen");
		toolItem1.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				openEvent();
			}
		});
		ToolItem toolItem2 = new ToolItem(toolBar, SWT.PUSH);
		toolItem2.setText("");
		toolItem2.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Save.png")));
		toolItem2.setToolTipText("Speichern");
		toolItem2.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				saveEvent();
			}
		});
		ToolItem toolItem3 = new ToolItem(toolBar, SWT.PUSH);
		toolItem3.setToolTipText("Speichern unter");
		toolItem3.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Save_As.png")));
		ToolItem toolItem5 = new ToolItem(toolBar, SWT.SEPARATOR);
		ToolItem toolItem4 = new ToolItem(toolBar, SWT.PUSH);
		toolItem4.setToolTipText("Start");
		toolItem4.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Right1.png")));
		ToolItem toolItem9 = new ToolItem(toolBar, SWT.PUSH);
		ToolItem toolItem6 = new ToolItem(toolBar, SWT.PUSH);
		toolItem6.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Error.png")));
		toolItem6.setToolTipText("Halt");
		toolItem9.setToolTipText("Start (Endlosschleife)");
		toolItem9.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Right1b.png")));
		toolItem9.setText("");
		toolItem9.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				// direkter Aufruf, da dieser Button
				// nur für diesen Zweck verwendet wird
				tabItemProgram.parseProgramAndRun(1000,setHandler.getData().cmdPassw);
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		ToolItem toolItem8 = new ToolItem(toolBar, SWT.SEPARATOR);
		ToolItem toolItem7 = new ToolItem(toolBar, SWT.PUSH);
		toolItem7.setText("");
		toolItem7.setImage(new Image(Display.getCurrent(), getClass().getResourceAsStream(PathHelp.specDirIconSep()+"Refresh.png")));
		toolItem7.setToolTipText("Synchronisieren");
		toolItem7.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				syncEvent();				
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
			}
		});
		toolItem6.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				// direkter Aufruf, weil dieser Button
				// nur für diesen Zweck verwendet wird
				tabItemProgram.immediateHalt();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
		});
		toolItem4.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				startEvent();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
		});
		toolItem3.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				saveAsEvent();
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
		});
	}
	
	/**
	 * Diese Methode initialisiert die TabFolder.
	 * Wenn der VE mit einer NullPointerException daher kommt,
	 * einfach den Inhalt dieser Methode komplett einkommentieren,
	 * VE neu aufbauen lassen und den Kommentar wieder entfernen.
	 */
	private void createTabFolder() {
		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;
		tabFolder = new TabFolder(getShell(), SWT.NONE);
		tabFolder.setLayoutData(gridData);
		createTabItems();
		tabFolder.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				updateSpecificTabItemSettings();
			}
		});
		TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
		tabItem.setText("Programm");
		tabItem.setControl(tabItemProgram);
		TabItem tabItem1 = new TabItem(tabFolder, SWT.NONE);
		tabItem1.setText("Transportobjekte");
		tabItem1.setControl(tabItemTransObj);
		TabItem tabItem2 = new TabItem(tabFolder, SWT.NONE);
		tabItem2.setText("Hindernisse");
		tabItem2.setControl(tabItemObsDef);
		TabItem tabItem3 = new TabItem(tabFolder, SWT.NONE);
		tabItem3.setText("Manuell");
		tabItem3.setControl(tabItemManual);
		TabItem tabItem4 = new TabItem(tabFolder, SWT.NONE);
		tabItem4.setText("Kamera");
		tabItem4.setControl(tabItemCam);
	}
	
	/**
	 * Diese Methode initialisiert das Composite und ordnet die
	 * benötigten Komponeten auf diesem an
	 */
	private void createComposite() {
		composite = new Composite(getShell(), SWT.NONE);
		composite.setLayout(null);
		createCanvas();
		label = new Label(composite, SWT.NONE);
		label.setText("Nicht verbunden");
		label.setLocation(new Point(80, 0));
		label.setSize(new Point(133, 13));
		label1 = new Label(composite, SWT.NONE);
		label1.setSize(new Point(300, 15));
		label1.setLocation(new Point(650, 0));
		label1.setText("");
		label2 = new Label(composite, SWT.NONE);
		label2.setSize(new Point(300, 15));
		label2.setLocation(new Point(350, 0));
		label2.setText("");
		tabItemCam.setStatusbarLabel(label2);
		tabItemObsDef.setStatusbarLabel(label2);
	}

	/**
	 * Diese Methode initialisert das Canvas in der Statusbar
	 * in der die Symbole zur Visualisierung der Konnektivität
	 * angezeigt werden.
	 */
	private void createCanvas() {
		canvas = new Canvas(composite, SWT.NONE);
		canvas.setLocation(new Point(10, 0));
		canvas.setToolTipText("Konnektivität von CMD, SQL und FTP");
		canvas.setSize(new Point(60, 22));
		canvas.addPaintListener(new org.eclipse.swt.events.PaintListener() {
			public void paintControl(org.eclipse.swt.events.PaintEvent e) {
				// Graphics Context
				GC gc = new GC(canvas);
				// Farben
				Color green = sShell.getDisplay().getSystemColor(SWT.COLOR_GREEN);
				Color red = sShell.getDisplay().getSystemColor(SWT.COLOR_RED);
				gc.setForeground(sShell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
				// Maße
				int diameter = 16;
				int space = 4;
				boolean border = true;
				
				// Cmd zeichnen
				if(bConnectionCmd)
					gc.setBackground(green);
				else
					gc.setBackground(red);
				gc.fillOval(0, 0, diameter, diameter);
				Point p = gc.stringExtent("A");
				gc.drawString("C", diameter/2-p.x/2, diameter/2-p.y/2, true);
				if(border) gc.drawOval(0, 0, diameter, diameter);
				
				// Sql zeichnen
				if(bConnectionSql)
					gc.setBackground(green);
				else
					gc.setBackground(red);
				gc.fillOval(diameter+space, 0, diameter, diameter);
				gc.drawString("S",diameter+space+diameter/2-p.x/2, diameter/2-p.y/2, true);
				if(border) gc.drawOval(diameter+space, 0, diameter, diameter);
				
				// Ftp zeichnen
				if(bConnectionFtp)
					gc.setBackground(green);
				else
					gc.setBackground(red);
				gc.fillOval(2*(diameter+space), 0, diameter, diameter);
				gc.drawString("F",2*(diameter+space)+diameter/2-p.x/2, diameter/2-p.y/2, true);
				if(border) gc.drawOval(2*(diameter+space), 0, diameter, diameter);
				
				// Fertig
				gc.dispose();
			}
		});
	}
	
	/* ##########################################################################
	 * 						ÖFFENTLICHE METHODEN
	 * ##########################################################################*/

	/**
	 * Liefert die Shell zum Anzeigen und wieder Entfernen
	 */
	public Shell getShell(){
		return sShell;
	}
	
	/**
	 * Methode, die vom Network-Handler aufgerufen wird,
	 * wenn eine Verbindung abgebrochen wurde
	 */
	public void connectionNotification(){
		// Code hier wird üblicherweise im anderen Thread ausgeführt
		// (Timer-Thread des NetworkHandlers). Man kann aber nur im
		// Haupt-Thread GUI-Objekte verändern, darum ist folgende
		// Konstruktion nötig:
		sShell.getDisplay().syncExec(
			new Runnable() {
				public void run(){
					// Überprüfen, was genau passiert ist
					checkConnectionStates();
					// Icons neu zeichnen
					canvas.redraw();
					// Menüeinträge anpassen
					updateConnectionMenuItems();
				}
		});
	}
	
	/**
	 * Wird aufgerufen, wenn TabItem-übergreifend dynamisch Commands
	 * erstellt und ins Prg-Tab eingefügt werden sollen
	 * @param cmd das Command, um das es sich handelt
	 * @param line Zeile in der die dynamische Auswahl eingefügt wird
	 */ 
	public void dynamicCommandSelect(String cmd, int line){
		// Zeile speichern
		dynCmdSelectLine=line;
		// Schauen, was für ein Command
		if(cmd.equals("settransobj")){
			// Schauen, ob überhaupt möglich
			if(!tabItemTransObj.isDynamicCmdPossible()) return;
			// Tab öffnen
			tabFolder.setSelection(TAB_TRANSOBJ);
			// Tab merken
			dynCmdSelect = tabItemTransObj;
		}else if(cmd.equals("camif")){
			// Tab öffnen
			tabFolder.setSelection(TAB_CAM);
			// Tab merken
			dynCmdSelect = tabItemCam;
		}else if(cmd.equals("moveposition") ||
				cmd.equals("offset") ||
				cmd.equals("defineobstaclecircle") ||
				cmd.equals("defineobstaclerect")){
			// Tab öffnen
			tabFolder.setSelection(TAB_OBSDEF);
			// Tab merken
			dynCmdSelect = tabItemObsDef;
		}else if(cmd.equals("loadbitmap") ||
				cmd.equals("savebitmap")){
			// Schauen, ob überhaupt möglich
			if(!tabItemObsDef.isBitmapSelectionPossible()) return;
			// Tab öffnen
			tabFolder.setSelection(TAB_OBSDEF);
			// Tab merken
			dynCmdSelect = tabItemObsDef;
		}else{
			return;
		}
		// Starten
		dynCmdSelect.startDynamicCmdSelect(cmd);
	}
	
	/**
	 * Wird von den einzelnen Tabs aufgerufen, wenn dynamische
	 * Auswahl abgeschlossen
	 * @param cmd fertiger Command-String
	 */
	public void stopDynamicCommandSelect(String cmd){
		tabItemProgram.replaceDynamicSelectedCommand(cmd, dynCmdSelectLine);
		dynCmdSelect=null;
		tabFolder.setSelection(TAB_PRG);
	}
	
	/**
	 * Methode, die aufgerufen wird, wenn eine Nachricht vom Roboter gekommen ist
	 */
	public void messageEvent(final Message msg){
		// Code hier wird üblicherweise im anderen Thread ausgeführt
		// (Timer-Thread des NetworkHandlers). Man kann aber nur im
		// Haupt-Thread GUI-Objekte verändern, darum ist folgende
		// Konstruktion nötig:
		sShell.getDisplay().syncExec(
			new Runnable() {
				public void run(){
					// auf Message reagieren
					System.out.println("MessageID - "+msg.getID());
					if(msg.getID()>=128)
						reactToError(msg);
					else
						reactToMessage(msg);
				}
		});
	}
	
	/* ##########################################################################
	 * 						HILFSMETHODEN
	 * ##########################################################################*/
	
	/**
	 * Reagiert auf eingegangene Nachrichten
	 * @param msg Nachricht die eingegangen ist und verarbeitet werden muss
	 */
	private void reactToMessage(final Message msg){
		switch(msg.getID()){
		case Message.POS:
			label1.setText("Roboter-Position X: " + Math.round(msg.getfParam1()) + " Y: " +
					Math.round(msg.getfParam2()) + " Z: " + Math.round(msg.getfParam3()));
			tabItemManual.setPosition(Math.round(msg.getfParam1()),
					Math.round(msg.getfParam2()), Math.round(msg.getfParam3()));
			break;
		case Message.IMGAVAIL:
			tabItemCam.refreshCamPic();
			break;
		case Message.REFRESH_FTP:
			tabItemObsDef.refreshTable();
			break;
		}
	}
	
	/**
	 * Reagiert auf eingegangene Fehlermeldungen
	 * @param msg Fehlermeldung die eingegangen ist und verarbeitet werden muss
	 */
	private void reactToError(final Message msg){
		switch(msg.getID()){
		case Message.POSIMP:
			MsgBox.showError("Roboter: Zielposition generell nicht anfahrbar!");
			break;
		case Message.POSOCC:
			MsgBox.showError("Roboter: An der Zielposition befindet sich ein Hindernis!");
			break;
		case Message.WAYIMP:
			MsgBox.showError("Roboter: Kein Weg zur angegebenen Zielposition gefunden!");
			break;
		case Message.MOTIMP:
			MsgBox.showError("Roboter: Bewegung nicht möglich!");
			break;
		case Message.FILEERR:
			MsgBox.showError("Roboter: Datei öffnen nicht möglich!");
			break;
		case Message.LINEIMP:
			MsgBox.showError("Roboter: Min. eine Position der linearen Bewegung nicht anfahrbar!");
			break;
		case Message.NOTRANSOBJ:
			MsgBox.showError("Roboter: Transportobjekt existiert nicht!");
			break;
		case Message.AUTHERR:
			MsgBox.showError("Roboter: Authentifizierung für Command Verbindung fehlgeschlagen!");
			break;
		default:
			MsgBox.showError("Roboter: Unbekannter Fehler " + msg.getID());	
		}
	}
	
	/**
	 * Überprüft nach einem ConnectionNotification-Ereignis,
	 * welche Verbindung unterbrochen wurde bzw. welche
	 * aufgebaut wurde und benachrichtigt die TabItems.
	 */
	private void checkConnectionStates(){
		// Was hat sich geändert
		boolean cmdChanged = bConnectionCmd ^ netHandler.isCmdConnected();
		boolean sqlChanged = bConnectionSql ^ netHandler.isSqlConnected();
		boolean ftpChanged = bConnectionFtp ^ netHandler.isFtpConnected();
		// Command-Leitung
		if(cmdChanged){
			bConnectionCmd=!bConnectionCmd;
			if(bConnectionCmd)
				tabItemManual.connectionEstablished();
			else
				tabItemManual.connectionDisrupted();
		}
		// SQL-Leitung
		if(sqlChanged){
			bConnectionSql=!bConnectionSql;
			if(bConnectionSql)
				tabItemTransObj.connectionEstablished();
			else
				tabItemTransObj.connectionDisrupted();
		}
		// FTP-Leitung
		if(ftpChanged){
			bConnectionFtp=!bConnectionFtp;
			if(bConnectionFtp)
				tabItemObsDef.connectionEstablished();
			else
				tabItemObsDef.connectionDisrupted();
		}
		// Kombinationen
		if(ftpChanged||cmdChanged){
			if(bConnectionFtp&&bConnectionCmd)
				tabItemCam.connectionEstablished();
			else
				tabItemCam.connectionDisrupted();
		}
		
		// Label in Statusbar
		if(bConnectionFtp && bConnectionSql && bConnectionCmd)
			label.setText("Verbunden");
		else if(!(bConnectionFtp || bConnectionSql || bConnectionCmd))
			label.setText("Nicht verbunden");
		else
			label.setText("Teilweise verbunden");
	}
	
	/* ##########################################################################
	 * 						EREIGNISSE
	 * ##########################################################################*/
	
	/**
	 * Wird aufgerufen, wenn man auf das Neu-Symbol klickt
	 */
	private void newEvent(){
		switch(tabFolder.getSelectionIndex()){
		case TAB_PRG:
			tabItemProgram.newFile();
			break;
		case TAB_TRANSOBJ:
			tabItemTransObj.clickBNew();
			break;
		case TAB_OBSDEF:
			tabItemObsDef.newPicture();
			break;
		case TAB_MAN:
			break;
		case TAB_CAM:
			break;
		default:
		}
	}
	
	/**
	 * Wird aufgerufen, wenn man auf das Öffnen-Symbol klickt
	 */
	private void openEvent(){
		switch(tabFolder.getSelectionIndex()){
		case TAB_PRG:
			tabItemProgram.loadFile();
			break;
		case TAB_TRANSOBJ:
			tabItemTransObj.loadFromFolder();
			break;
		case TAB_OBSDEF:
			tabItemObsDef.loadLocal();
			break;
		case TAB_MAN:
			break;
		case TAB_CAM:
			break;
		default:
		}
	}
	
	/**
	 * Wird aufgerufen, wenn man auf das Speichern-Symbol klickt
	 */
	private void saveEvent(){
		switch(tabFolder.getSelectionIndex()){
		case TAB_PRG:
			tabItemProgram.saveFile();
			break;
		case TAB_TRANSOBJ:
			tabItemTransObj.saveAllIntoFolder();
			break;
		case TAB_OBSDEF:
			tabItemObsDef.saveLocal();
			break;
		case TAB_MAN:
			break;
		case TAB_CAM:
			break;
		default:
		}
	}
	
	/**
	 * Wird aufgerufen, wenn man auf das Speichern-Unter-Symbol klickt
	 */
	private void saveAsEvent(){
		switch(tabFolder.getSelectionIndex()){
		case TAB_PRG:
			tabItemProgram.saveFileAs();
			break;
		case TAB_TRANSOBJ:
			tabItemTransObj.saveAllIntoFolder();
			break;
		case TAB_OBSDEF:
			tabItemObsDef.saveLocalAs();
			break;
		case TAB_MAN:
			break;
		case TAB_CAM:
			break;
		default:
		}
	}
	
	/**
	 * Wird aufgerufen, wenn man auf das Aktualisieren-Symbol klickt
	 */
	private void syncEvent(){
		switch(tabFolder.getSelectionIndex()){
		case TAB_TRANSOBJ:
			tabItemTransObj.clickBSync();
			break;
		case TAB_CAM:
			tabItemCam.sendImageRequest();
			break;
		default:
		}
	}
	
	/**
	 * Wird aufgerufen, wenn man auf das Start-Symbol klickt
	 */
	private void startEvent(){
		switch(tabFolder.getSelectionIndex()){
		case TAB_PRG:
			tabItemProgram.parseProgramAndRun(0,setHandler.getData().cmdPassw);
			break;
		case TAB_MAN:
			netHandler.getComQueue().enqueue(new Command(NetPack.PRG_START,0,setHandler.getData().cmdPassw));
			//netHandler.getComQueue().enqueue(new Command(NetPack.MOVEPOS, 0, 0, x, y, z, "ka"));
			break;
		default:
		}
		
	}

	/**
	 * Erzeugt die einzelnen TabItems
	 */
	private void createTabItems(){
		// Programme
		tabItemProgram = new TabItemProgram(this, tabFolder, SWT.NONE, netHandler);
		tabItemProgram.setShell(getShell());
		// Transport-Objekte
		tabItemTransObj = new TabItemTransObj(this, tabFolder, SWT.NONE, netHandler);
		// Hindernisse
		tabItemObsDef = new TabItemObsDef(this, sShell.getDisplay(), tabFolder, SWT.NONE, netHandler);
		// Manuelle Steuerung
		tabItemManual = new TabItemManual(tabFolder, SWT.NONE, netHandler);
		// Kamera
		tabItemCam = new TabItemCam(this, sShell.getDisplay(), tabFolder, SWT.NONE, netHandler);
	}
	
	/**
	 * Enable oder Disable Menü Einträge je nach Konnektivität
	 */
	private void updateConnectionMenuItems(){
		submenu3.getItem(0).setEnabled(!bConnectionCmd);
		submenu3.getItem(1).setEnabled(!bConnectionSql);
		submenu3.getItem(2).setEnabled(!bConnectionFtp);
		submenu4.getItem(0).setEnabled(bConnectionCmd);
		submenu4.getItem(1).setEnabled(bConnectionSql);
		submenu4.getItem(2).setEnabled(bConnectionFtp);
	}
	
	/**
	 * Wird aufgerufen, wenn das TabItem wechselt.
	 * U.a. wird die Toolbar aktualisiert.
	 */
	private void updateSpecificTabItemSettings(){
		// Icon Indizes
		final int iPrgStart = 5;
		final int iPrgStartLoop = 6;
		final int iSync = 9;
	
		// Statusbar-Label leeren
		try{
			label2.setText("");
		}catch(Exception e){ }
		
		// Noch beim dyn. Auswählen von Commands?
		if(dynCmdSelect!=null){
			dynCmdSelect.cancelDynamicCmdSelect();
			dynCmdSelect=null;
			System.out.println("Abgebrochen");
		}
		
		// Benutzer im TransObj-Tab gerade beim Editieren?
		if(tabItemTransObj.isEditing()) tabItemTransObj.clickBDelete();
		
		switch(tabFolder.getSelectionIndex()){
		case TAB_PRG: // Programm
			setFileSystemIconsState(true);
			toolBar.getItem(iPrgStart).setEnabled(true);
			toolBar.getItem(iPrgStartLoop).setEnabled(true);
			toolBar.getItem(iSync).setEnabled(false);
			break;
		case TAB_TRANSOBJ: // Transport-Objekte
			setFileSystemIconsState(true);
			toolBar.getItem(iPrgStart).setEnabled(false);
			toolBar.getItem(iPrgStartLoop).setEnabled(false);
			toolBar.getItem(iSync).setEnabled(true);
			break;
		case TAB_OBSDEF: // Hindernisse
			setFileSystemIconsState(true);
			toolBar.getItem(iPrgStart).setEnabled(false);
			toolBar.getItem(iPrgStartLoop).setEnabled(false);
			toolBar.getItem(iSync).setEnabled(false);
			break;
		case TAB_MAN: // Manuelle Steuerung
			setFileSystemIconsState(false);
			toolBar.getItem(iPrgStart).setEnabled(true);
			toolBar.getItem(iPrgStartLoop).setEnabled(false);
			toolBar.getItem(iSync).setEnabled(false);
			break;
		case TAB_CAM: // Kamera
			setFileSystemIconsState(false);
			toolBar.getItem(iPrgStart).setEnabled(false);
			toolBar.getItem(iPrgStartLoop).setEnabled(false);
			toolBar.getItem(iSync).setEnabled(true);
			break;
		default:
		}
	}
	
	
	/**
	 * Ändert den Zustand der FileSystem-Icons in der Toolbar
	 * (Neu, Laden, Speichern, Speichern unter)
	 * @param enabled gibt an ob die Icons Enabled sind oder nicht
	 */
	private void setFileSystemIconsState(boolean enabled){
		toolBar.getItem(0).setEnabled(enabled);
		toolBar.getItem(1).setEnabled(enabled);
		toolBar.getItem(2).setEnabled(enabled);
		toolBar.getItem(3).setEnabled(enabled);
	}
	
}
