package lu.tudor.santec.gecamed.formeditor.gui.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Map;

import javax.swing.JFileChooser;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;

import lu.tudor.santec.gecamed.core.gui.widgets.GECAMedBaseDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.GECAMedBaseDialogImpl;
import lu.tudor.santec.gecamed.formeditor.gui.FormEditorModule;
import lu.tudor.santec.gecamed.formeditor.gui.component.EditableComponent;
import lu.tudor.santec.gecamed.formeditor.gui.model.ComboBoxElement;
import lu.tudor.santec.gecamed.formeditor.gui.model.FormEditorModel;
import lu.tudor.santec.gecamed.formeditor.gui.model.FormModel;
import lu.tudor.santec.i18n.Translatrix;

import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.FormSpec;
import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.layout.Sizes;

public class MenuPanelController implements ActionListener, ChangeListener {
	
	public static final String SAVE_BUTTON 					= "s";
	public static final String LOAD_BUTTON 					= "l";
	public static final String EXPORT_BUTTON 				= "e";
	public static final String IMPORT_BUTTON 				= "i";
	public static final String PREVIEW_BUTTON 				= "p";
	public static final String CLOSE_PREVIEW_BUTTON 		= "c_p";
	public static final String CLOSE_ALL_PREVIEWS_BUTTON 	= "c_a_p";
	public static final String CONFIG_FORM_BUTTON 			= "a_f";
	public static final String LOAD_TEMPLATE_BUTTON 		= "l_t";
	public static final String CANCEL_LOAD_TEMPLATE_BUTTON 	= "c_l_t";
	public static final String RESET_EDIT_PANEL 			= "r_e_p";
	public static final String DELETE_TEMPLATE_BUTTON 		= "d_t_b";
	
	public static final int CHANGE_WIDTH 					= 1;
	public static final int CHANGE_HEIGHT 					= 2;
	public static final int REARRANGE_PANEL 				= 3;
		
	private FormEditorModel model;
	private FormEditorModule view;
	
//	private int whatToDo;
	private ComboBoxElement<?> elem;
	// for temporarily storing
	private Object o;
	
	private JFileChooser fileChooser = new JFileChooser();
	
	public MenuPanelController (FormEditorModel model) {
		/* ======================================== */
		this.model = model;
		view = model.getView();
		/*
		 * defines which file are shown in the JFileChooser
		 */	
		FileFilter filter = new FileFilter() {
			@Override
			public String getDescription() {
				return ".xml";
			}				
			@Override
			public boolean accept(File f) {
				return f.getName().endsWith(".xml") || f.isDirectory();
			}
		};
		fileChooser.setFileFilter(filter);
		/* ======================================== */
	}
	
	// a constructor for those components, that don't have an action-command
//	public MenuPanelController (FormEditorModel model, int whatToDo) {
//		this.model = model;
//		view = model.getView();
//		this.whatToDo = whatToDo;
//	}

	public void setElem(ComboBoxElement<?> elem) {
		this.elem = elem;
	}
	public ComboBoxElement<?> getElem() {
		return elem;
	}
	
	public void setObject(Object o) {
		this.o = o;
	}
	public Object getObject() {
		return o;
	}

	public void actionPerformed(ActionEvent e) {
		/* ======================================== */
//		if (e.getActionCommand().equals(SAVE_BUTTON)) {
//			/* **********  SAVE  ********** */
//			model.saveTemplate();
//			/* **************************************** */
//		} else if (e.getActionCommand().equals(LOAD_BUTTON)) {
//			/* **********  LOAD  ********** */
//			model.chooseTemplate();
//			/* **************************************** */
		if (e.getActionCommand().equals(EXPORT_BUTTON)) {
			/* **********  EXPORT  ********** */
			model.updateFormModel();
			FormModel formModel = model.getFormModel();
			File f;
			
			if (formModel.getName().length() != 0) {
				/* ---------------------------------------- */
				f = new File(fileChooser.getCurrentDirectory().getAbsolutePath()
						+ File.separator + formModel.getName() + ".xml");
				fileChooser.setSelectedFile(f);
				/* ---------------------------------------- */
			}
			
			if (fileChooser.showSaveDialog(view) == JFileChooser.APPROVE_OPTION) {
				/* ---------------------------------------- */
				f = fileChooser.getSelectedFile();
				
				if (f.exists()) {
					/* ---------------------------------------- */
					int buttonOption = GECAMedBaseDialogImpl.showMessageDialog(view, 
							Translatrix.getTranslationString("formeditor.override_file_title"), 
							Translatrix.getTranslationString("formeditor.override_file"), 
							GECAMedBaseDialogImpl.YES_NO_CANCEL_BUTTON_MODE);
					if (buttonOption == GECAMedBaseDialog.NO_OPTION) {
						return;
					} else if (buttonOption == GECAMedBaseDialog.CANCEL_OPTION) {
						actionPerformed(e);
						return;
					}
					/* ---------------------------------------- */
				}
				
				if (!f.getName().endsWith(".xml")) {
					/* ---------------------------------------- */
					String[] tmp = f.getName().split("\\.");
					if (tmp.length > 1) {
						String ending = tmp[tmp.length-1];
						f = new File(f.getAbsolutePath().replace(ending, "xml"));
					} else {
						f = new File(f.getAbsolutePath().concat(".xml"));
					}
					/* ---------------------------------------- */
				}
//				fModel.setName(f.getName().replace(".xml", ""));
				formModel.exportTemplate(f);
				/* ---------------------------------------- */
			}
			/* **************************************** */
//		} else if (e.getActionCommand().equals(IMPORT_BUTTON)) {
//			/* **********  IMPORT  ********** */
//			// import an xml file, make it a FormModel and load it into the current Formeditor
//			if (fileChooser.showOpenDialog(view) == JFileChooser.APPROVE_OPTION) {
//				/* ---------------------------------------- */
//				int buttonOption = FormEditorDialog.showMessageDialog(view, 
//						Translatrix.getTranslationString("formeditor.import_and_reset_title"), 
//						Translatrix.getTranslationString("formeditor.import_and_reset_message"), 
//						FormEditorDialog.YES_NO_CANCEL_BUTTON_MODE);
//				if (buttonOption == FormEditorDialog.NO_BUTTON) {
//					/* ---------------------------------------- */
//					return;
//					/* ---------------------------------------- */
//				} else if (buttonOption == FormEditorDialog.CANCEL_BUTTON) {
//					/* ---------------------------------------- */
//					actionPerformed(e);
//					return;
//					/* ---------------------------------------- */
//				}
//				
//				File f = fileChooser.getSelectedFile();
//				model.destructFormModel();
//				model.destructScriptEditor();
//				view.clearMapAndPanel();
//				FormModel formModel = FormModel.importTemplate(f, model);
//				if (formModel != null) {
//					model.loadTemplate(formModel);
//				}
//				/* ---------------------------------------- */
//			}
//			/* **************************************** */
		} else if (e.getActionCommand().equals(PREVIEW_BUTTON)) {
			/* **********  PREVIEW  ********** */
			model.addPreviewTab();
			/* **************************************** */
//		} else if (e.getActionCommand().equals(CONFIG_FORM_BUTTON)) {
//			/* **********  CONFIG  ********** */
//			new ConfigDialog(model);
//			String name = null;
//			if (model.getFormModel() != null) {
//				name = model.getFormModel().getName();
//			}
//			view.updateTitle(name);
//			/* **************************************** */
		} else if (e.getActionCommand().equals(CLOSE_PREVIEW_BUTTON)) {
			/* **********  CLOSE PREVIEW  ********** */
			model.closePreviewTab();
			/* **************************************** */
		} else if (e.getActionCommand().equals(CLOSE_ALL_PREVIEWS_BUTTON)) {
			/* **********  CLOSE ALL PREVIEWS  ********** */
			model.closeAllPreviewTabs();
			/* **************************************** */
		} else if (e.getActionCommand().equals(RESET_EDIT_PANEL)) {
			/* **********  RESET EDITOR  ********** */
			int buttonPressed = GECAMedBaseDialogImpl.showMessageDialog(view, 
					Translatrix.getTranslationString("formeditor.reset"),
					Translatrix.getTranslationString("formeditor.reset_message"), 
					GECAMedBaseDialogImpl.YES_NO_BUTTON_MODE);
			
			if (buttonPressed == GECAMedBaseDialog.YES_OPTION) {
				view.resetEditPanelComponents();
				view.updateTitle(null);
			}
			/* **************************************** */
		}		
		/* ======================================== */
	}

	public void stateChanged(ChangeEvent e) {
		/* ======================================== */
		if (e.getSource() instanceof JTabbedPane) {
			/* ---------------------------------------- */
			JTabbedPane tabbedPane = (JTabbedPane)e.getSource();
			if (tabbedPane.getSelectedIndex() == 0) {
				/* ---------------------------------------- */
				model.setCurrentlySelectedComponent(null);
				view.enableMenuPanel(FormEditorModule.LIST_TAB);
				/* ---------------------------------------- */
			} else if (tabbedPane.getSelectedIndex() == 1) {
				/* ---------------------------------------- */
				view.enableMenuPanel(FormEditorModule.EDITOR_TAB);
				/* ---------------------------------------- */
			} else {
				/* ---------------------------------------- */
				model.setCurrentlySelectedComponent(null);
				view.enableMenuPanel(FormEditorModule.PREVIEW_TAB);
				/* ---------------------------------------- */
			}
			
			view.rearrangeSettingsPanel();
			view.repaint();
			/* ---------------------------------------- */
//		} else if (e.getSource() instanceof JSlider) {
//			/* ---------------------------------------- */
//			JSlider slider = (JSlider)e.getSource();
//			EditableComponent ec = model.getCurrentlySelectedComponent();
//			String definition = "";
//			
//			if (whatToDo == CHANGE_WIDTH) {
//				/* ---------------------------------------- */
//				// a column is selected, the width has to be fit
//				definition = view.getFormLayoutColDefinition(ec.getColumn());
//				String[] defArray = definition.split(":");
//				definition = defArray[0]+":"+slider.getValue()+"px:"+defArray[2];
//				view.setFormLayoutColDefinition(ec.getColumn(), definition);
//				/* ---------------------------------------- */
//			} else if (whatToDo == CHANGE_HEIGHT) {
//				/* ---------------------------------------- */
//				// a row is selected, the height has to be fit
//				definition = view.getFormLayoutRowDefinition(ec.getRow());
//				String[] defArray = definition.split(":");
//				definition = defArray[0]+":"+slider.getValue()+"px:"+defArray[2];
//				view.setFormLayoutRowDefinition(ec.getRow(), definition);
//				/* ---------------------------------------- */
//			}
//			
//			view.rearrangeEditPanel();
			/* ---------------------------------------- */
//		} else if (e.getSource() instanceof JSpinner) {
//			/* ---------------------------------------- */
//			if (whatToDo == REARRANGE_PANEL) {
//				view.rearrangeSettingsPanel();
//				view.rearrangeEditPanel();
//				
//				view.setModified(true);
//			}
//			/* ---------------------------------------- */
		}
		/* ======================================== */
	}

	public void changePanelSize(JSpinner usedSpinner, boolean columnChanged) 
	{
		FormLayout layout = view.getEditPanelLayout();
		
		if (layout.getColumnCount() != view.getEditorColumnCount()
				&& layout.getRowCount() != view.getEditorRowCount()) 
		{
			// both spinners have been changed simultaneously 
			// -> just rearrange the panel
			view.rearrangeEditPanel();
			view.rearrangeSettingsPanel();
			
			return;
		}
		
		int newSize;
		int oldSize;
		
		if (columnChanged) 
		{
			newSize = view.getEditorColumnCount();
			oldSize = layout.getColumnCount();
		} 
		else 
		{
			newSize = view.getEditorRowCount();
			oldSize = layout.getRowCount();
		}
		
		if (newSize == oldSize)
			return;
		
		if (newSize < oldSize) 
		{
			/* **************************************** */
			// 		DELETE A COLUMN / ROW
			/* **************************************** */
			
			Map<String, EditableComponent> components = model.getEditableComponents();
			
			int maxComponentIndex;
			for (EditableComponent ec : components.values()) 
			{
				if (ec == null) 
					continue;
				
				if (columnChanged) 
					 maxComponentIndex = ec.getColumn() + ec.getColumnWidth() - 1;
				else maxComponentIndex = ec.getRow() + ec.getRowHeight() - 1;
				
				if (maxComponentIndex > newSize) 
				{
					usedSpinner.setValue(oldSize - 1);
					usedSpinner.validate();
					return;
				}
			}
			
			EditableComponent ec = model.getCurrentlySelectedComponent();
			
			int currentComponentMaxIndex = 0;
			if (ec != null) 
			{
				if (columnChanged)
					 currentComponentMaxIndex = ec.getColumn() + ec.getColumnWidth() - 1;
				else currentComponentMaxIndex = ec.getRow() + ec.getRowHeight() - 1;
			}
			
			if (currentComponentMaxIndex > newSize) 
			{
				// the selected component was in the area being deleted
				model.setCurrentlySelectedComponent(null);
				view.rearrangeSettingsPanel();
			}
			
			// remove the dummy elements in the columns  / rows
			if (columnChanged) 
			{
				model.removeComponents(newSize+1, 1, layout.getColumnCount(), layout.getRowCount(), false);
				
				while (layout.getColumnCount() > newSize) 
					layout.removeColumn(layout.getColumnCount());
			} 
			else 
			{
				model.removeComponents(1, newSize+1, layout.getColumnCount(), layout.getRowCount(), false);
				
				while (layout.getRowCount() > newSize) 
					layout.removeRow(layout.getRowCount());
			}
		} 
		else 
		{
			/* **************************************** */
			// 		ADD A COLUMN / ROW
			/* **************************************** */
			if (columnChanged) 
			{
				for (int col = oldSize + 1; col <= newSize; col++) 
				{
					// add a column to the layout
					ColumnSpec spec = new ColumnSpec(ColumnSpec.FILL, Sizes.pixel(75), FormSpec.NO_GROW);
					layout.appendColumn(spec);
					view.addFormLayoutColDefinition(spec);
					
					// add the border component to this column
					model.addComponent(model.createBorderBarElement(col, 1));
					
					// add dummy components into each cell of the added column
					for (int row = 2; row <= layout.getRowCount(); row++)
						model.addComponent(model.createDummy(col, row), true);
				}
			} 
			else 
			{
				for (int row = layout.getRowCount()+1; row <= newSize; row++) 
				{
					// add a row to the layout
					RowSpec spec = new RowSpec(ColumnSpec.FILL, Sizes.pixel(25), FormSpec.NO_GROW);
					layout.appendRow(spec);
					view.addFormLayoutRowDefinition(spec);
					
					// add the border component to this column
					model.addComponent(model.createBorderBarElement(1, row));
					
					// add dummy components into each cell of the added column
					for (int col = 2; col <= layout.getColumnCount(); col++) 
						model.addComponent(model.createDummy(col, row), true);
				}
			}
		}
		
		view.validateEditorScrollpane();
		view.getEditPanel().repaint();
		
		view.setModified(true);
	}
}
