/**
 * 
 */
package minijaja.ihm.vue;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;

import minijaja.ast_struct.Node;
import minijaja.ihm.controleur.JavaLineStyler;
import minijaja.parseur.MiniJaja;
import minijaja.parseur.ParseException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;

/**
 * Compilateur.minijaja.ihm.vue.Launcher.java
 * @author Ludovic
 * cree le 17 nov. 07
 */
public class Launcher {

	private Shell sShell = null;
	private FileDialog fileDialog = null;
	private File file = null;
	private EditeurMiniJaja editor = null;
	private StyledText text = null; 
	private JavaLineStyler lineStyler = null;
	private Menu maMenuBar = null;
	private Composite monComposite = null;
	private CTabFolder monCTabFolder = null;
	private VueArbre abr = null;

	
	
	

	
	/**
	 * Launcher.main
	 * @return void
	 * @param args
	 */
	public static void main(String[] args) {
		/* Before this is run, be sure to set up the launch configuration (Arguments->VM Arguments)
		 * for the correct SWT library path in order to run with the SWT dlls. 
		 * The dlls are located in the SWT plugin jar.  
		 * For example, on Windows the Eclipse SWT 3.1 plugin jar is:
		 *       installation_directory\plugins\org.eclipse.swt.win32_3.1.0.jar
		 */
		Display display = Display.getDefault();
		Launcher thisClass = new Launcher();
		thisClass.createSShell();
		thisClass.sShell.open();

		while (!thisClass.sShell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}

	/**
	 * This method initializes sShell
	 */
	private void createSShell() {
		sShell = new Shell();
		sShell.setText("Shell");
		FillLayout layout = new FillLayout();
		sShell.setSize(new Point(500, 400));
		sShell.setLayout(layout);
		createMonComposite();
		createMenuBar();
	}

	// --- initialisation de la Barre menu :
	
	void createMenuBar() {
		maMenuBar = new Menu(sShell, SWT.BAR);
		sShell.setMenuBar(maMenuBar);
		
		MenuItem fileItem = new MenuItem(maMenuBar, SWT.CASCADE);
		fileItem.setText("Fichier");
		fileItem.setMenu(createFileMenu());

	}
	
	// --- Menu Fichier :
	
	Menu createFileMenu() {
		Menu menu = new Menu(maMenuBar);
		MenuItem item;

		// --- Open
		item = new MenuItem(menu, SWT.CASCADE);
		item.setText("Ouvrir");
		item.setAccelerator(SWT.MOD1 + 'O');
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				openFile();
			}
		});

		// --- Exit
		item = new MenuItem(menu, SWT.PUSH);
		item.setText("Quitter");
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				menuFileExit();
			}
		});
		return menu;
	}
	
	// --- les listeners :
	
	void openFile() {
		if (fileDialog == null) {
			fileDialog = new FileDialog(sShell, SWT.OPEN);
		}

		fileDialog.setFilterExtensions(new String[] { "*.mjj", "*.*" });
		String name = fileDialog.open();

		open(name);
	}

	void open(String name) {
		final String textString;

		if ((name == null) || (name.length() == 0))
			return;

		file = new File(name);
		if (!file.exists()) {
			String message = "Err file no exist";
			displayError(message);
			return;
		}

		try {
			FileInputStream stream = new FileInputStream(file.getPath());
			try {
				Reader in = new BufferedReader(new InputStreamReader(stream));
				char[] readBuffer = new char[2048];
				StringBuffer buffer = new StringBuffer((int) file.length());
				int n;
				while ((n = in.read(readBuffer)) > 0) {
					buffer.append(readBuffer, 0, n);
				}
				textString = buffer.toString();
				stream.close();
			} catch (IOException e) {
				// Err_file_io
				String message = "Err_file_io";
				displayError(message);
				return;
			}
		} catch (FileNotFoundException e) {
			String message = "Err_not_found";
			displayError(message);
			return;
		}
		// Guard against superfluous mouse move events -- defer action until
		// later
		Display display = text.getDisplay();
		display.asyncExec(new Runnable() {
			public void run() {
				text.setText(textString);
			}
		});
		
		

		// parse the block comments up front since block comments can go across
		// lines - inefficient way of doing this
		lineStyler.parseBlockComments(textString);
	}

	void menuFileExit() {
		sShell.close();
	}

	
	// --- MsgBox Erreur :

	void displayError(String msg) {
		MessageBox box = new MessageBox(sShell, SWT.ICON_ERROR);
		box.setMessage(msg);
		box.open();
	}
	
	
	
	
	/* ---- Les composants : ---- */
	
	
	/**
	 * This method initializes monComposite	
	 *
	 */
	private void createMonComposite() {
		monComposite = new Composite(sShell, SWT.NONE);
		monComposite.setLayout(new FillLayout());
		createMonCTabFolder();
	}
	
	/**
	 * This method initializes monCTabFolder	
	 *
	 */
	@SuppressWarnings("static-access")
	private void createMonCTabFolder() {
		
		monCTabFolder = new CTabFolder(monComposite, SWT.NONE);
		
		editor = new EditeurMiniJaja(monCTabFolder,SWT.NONE);
		text = editor.getMonStyledText();
		lineStyler = editor.getMiniJajaColoration();
		
		CTabItem onglet1 = new CTabItem(monCTabFolder, SWT.NONE);
		onglet1.setText("Editeur MiniJaja");
		onglet1.setControl(editor);
		
		// Creer et intituler un onglet :
		CTabItem onglet2 = new CTabItem(monCTabFolder, SWT.NONE);
		onglet2.setText("Visalisateur d'Arbres");
		
		if(file != null){
			// Creer un composite en tant que page contenu dans l'onglet :
			// Implementation de la classe MiniJaja pour créer un parseur de fichier texte.
			FileReader stream = null;
			try {
				stream = new FileReader(file);
			} catch (FileNotFoundException e) {
				// Fichier inexistant
				e.printStackTrace();
			}
			
		    MiniJaja parser = new MiniJaja(stream);
		    
		    try {
				parser.axiome();
			} catch (ParseException e) {
				// Erreur de parsing
				e.printStackTrace();
			}
		    
		    // Recuperation de la racine de l'AST (Abstract Syntax Tree).
		    Node racine = parser.getJjtree().rootNode();
			
			abr = new VueArbre(monCTabFolder, SWT.NONE, racine);
			onglet2.setControl(abr);
			
			//ajouterOngletEditeur();
			//onglet2 = ajouterOnglet(this.monCTabFolder, "Visalisateur d'Arbres");	
		}
		
	}
	
//	private void ajouterOngletEditeur(){
//		// Creer et intituler un onglet pour l'éditeur :
//		CTabItem onglet1 = new CTabItem(monCTabFolder, SWT.NONE);
//		onglet1.setText("Editeur MiniJaja");
//		onglet1.setControl(editor);
//	
//	}
//
//	private static Composite ajouterOnglet(CTabFolder dossier, String label){
//		
//		// Creer et intituler un onglet :
//		CTabItem onglet = new CTabItem(dossier, SWT.NONE);
//		onglet.setText(label);
//		
//		// Creer un composite en tant que page contenu dans l'onglet :
//		Composite page = new Composite(dossier,SWT.NONE);
//		onglet.setControl(page);
//		
//		return page;
//	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
