package pl.zalewski.mikolaj.symbdev.properties;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.PropertyPage;

import pl.zalewski.mikolaj.symbdev.SymbdevPlugin;
import pl.zalewski.mikolaj.symbdev.SymbianSDKsList;
import pl.zalewski.mikolaj.symbdev.Win32ToolsList;
import pl.zalewski.mikolaj.symbdev.widgets.DefinedSymbolsDialog;
import pl.zalewski.mikolaj.symbdev.widgets.SymbianSDKCombo;
import pl.zalewski.mikolaj.symbdev.widgets.Win32ToolCombo;

public class SymbianPropertyPage extends PropertyPage {

    private static final String PAGE_TITLE = "Symbian OS C++ development options";
	private static final String BUILD_PATH_TITLE = "bld.inf path:";
	private static final String SRC_PATH_TITLE = "Default source path:";
	private static final String INC_PATH_TITLE = "Default include path:";
	private static final int TEXT_FIELD_WIDTH = 50;

	private Text fPathText;
//    private Text fSrcPathText;
    private Text fIncPathText;

	/**
	 * Constructor for Symbian Properties in Project > Properties.
	 */
	public SymbianPropertyPage() {
		super();
	}

	private void addFirstSection(Composite parent) {
		Composite composite = createDefaultComposite(parent);

		//Label for path field
		Label titleLabel = new Label(composite, SWT.NONE);
		titleLabel.setText(PAGE_TITLE);
	}

	private void addSeparator(Composite parent) {
		Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
		GridData gridData = new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		separator.setLayoutData(gridData);
	}

	private void addSecondSection(Composite parent) {
		Composite composite = createDefaultComposite(parent);

		// Label for path field
		Label pathLabel = new Label(composite, SWT.NONE);
		pathLabel.setText(BUILD_PATH_TITLE);

		// build path text field
		fPathText = new Text(composite, SWT.SINGLE | SWT.BORDER);
		GridData gd = new GridData();
		gd.widthHint = convertWidthInCharsToPixels(TEXT_FIELD_WIDTH);
		fPathText.setLayoutData(gd);

		// Source path
/*		pathLabel = new Label(composite, SWT.NONE);
		pathLabel.setText(SRC_PATH_TITLE);
		fSrcPathText = new Text(composite, SWT.SINGLE | SWT.BORDER);
		gd = new GridData();
		gd.widthHint = convertWidthInCharsToPixels(TEXT_FIELD_WIDTH);
		fSrcPathText.setLayoutData(gd);*/

		// build path text field
		pathLabel = new Label(composite, SWT.NONE);
		pathLabel.setText(INC_PATH_TITLE);
		fIncPathText = new Text(composite, SWT.SINGLE | SWT.BORDER);
		gd = new GridData();
		gd.widthHint = convertWidthInCharsToPixels(TEXT_FIELD_WIDTH);
		fIncPathText.setLayoutData(gd);
		
		// Populate owner text field
		try {
			fPathText.setText(ProjectProperties.getBuildPath((IProject)getElement()));
		} catch (CoreException e) {
			fPathText.setText(ProjectProperties.BUILD_PATH_DEFAULT);
		}
		
/*		try {
			fSrcPathText.setText(ProjectProperties.getSrcPath((IProject)getElement()));
		} catch (CoreException e) {
			fSrcPathText.setText(ProjectProperties.SRC_PATH_DEFAULT);
		}*/
		
		try {
			fIncPathText.setText(ProjectProperties.getIncPath((IProject)getElement()));
		} catch (CoreException e) {
			fIncPathText.setText(ProjectProperties.INC_PATH_DEFAULT);
		}
	}
	
	private void addThirdSection(Composite parent) {
		Composite composite = createDefaultComposite(parent);
		GridData data;
		Label label;
		
		if (SymbianSDKsList.getInstance().isEmpty())
		{
		    createError(composite, "ERROR: The list of SDKs is empty. You should have at least one SDK.");
		} else
		{
			// Symbian SDK
			label = new Label(composite, SWT.NONE);
			label.setText("Symbian SDK:");
			fSdkCombo=new SymbianSDKCombo(composite, SWT.NONE, false);
			data=new GridData(GridData.FILL_HORIZONTAL);
			fSdkCombo.getComboBox().setLayoutData(data);		    
		}

		if (Win32ToolsList.getInstance().isEmpty())
		{
		    createError(composite, "ERROR: The list of Win32 compilation tools is empty. You should have at least one Win32 toolchain.");
		} else
		{
			// Win32 tool
			label = new Label(composite, SWT.NONE);
			label.setText("Win32 compilation tool:");
			fToolCombo=new Win32ToolCombo(composite, SWT.NONE, false);
			data=new GridData(GridData.FILL_HORIZONTAL);
			fToolCombo.getComboBox().setLayoutData(data);	
		}
		
		label = new Label(composite, SWT.NONE);
		label.setText("ABLD build:");
		fBuildCombo=new Combo(composite, SWT.DROP_DOWN|SWT.READ_ONLY);
		fBuildCombo.add(ProjectProperties.BUILD_UREL);
		fBuildCombo.add(ProjectProperties.BUILD_UDEB);
		data=new GridData(GridData.FILL_HORIZONTAL);
		fBuildCombo.setLayoutData(data);
		
		fStopOnError=new Button(composite, SWT.CHECK);
		fStopOnError.setText("Stop build on first erronous file");
		data=new GridData(GridData.FILL_HORIZONTAL);
		data.horizontalSpan=2;
		fStopOnError.setLayoutData(data);
		
		if (fSdkCombo!=null)
		    fSdkCombo.setAssociatedCombo(fToolCombo);
		
		try {
		    if (fSdkCombo!=null)
		        fSdkCombo.setResultName(ProjectProperties.getSymbianSDK((IProject)getElement()).name);
		} catch (CoreException e) { SymbdevPlugin.showError(e, null, getShell()); }	

		try {
		    if (fToolCombo!=null)
		        fToolCombo.setResultId(ProjectProperties.getWin32Tool((IProject)getElement()).id);
		} catch (CoreException e) { SymbdevPlugin.showError(e, null, getShell()); }				

		try {
		    if (ProjectProperties.getABLDBuild((IProject)getElement()).equals("udeb"))
		        fBuildCombo.select(1);
		    else fBuildCombo.select(0);
		} catch (CoreException e) { SymbdevPlugin.showError(e, null, getShell()); }					

		try {
		    fStopOnError.setSelection(ProjectProperties.getStopOnError((IProject)getElement()));
		} catch (CoreException e) { SymbdevPlugin.showError(e, null, getShell()); }
		updateCurrent();
	}
	
	private void updateCurrent()
	{
		fCurrentBuild=fBuildCombo.getSelectionIndex();
		if (fSdkCombo!=null)
		    fCurrentSDK=fSdkCombo.getResultName();
		fCurrentIncPath=fIncPathText.getText();
	}

	private void addFourthSection(Composite parent) {
		Composite composite = createDefaultComposite(parent);
		
		Label l = new Label(composite, SWT.NONE);
		l.setText("For the Indexer to work correctly the plug-in has detected the symbols that are defined\nin that configuartion. "+
		          "In this version you cannot change the symbols but you can see\nthe symbols list and force a rescan.");
		GridData gd = new GridData();
		gd.horizontalSpan=2;
		l.setLayoutData(gd);
		
		Button b=new Button(composite, SWT.PUSH);
		b.setText("Show symbols...");
		b.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                showSymbolsDlg();
            }			
        });
		gd = new GridData();
		gd.horizontalSpan=2;
		gd.horizontalAlignment=GridData.END;
		b.setLayoutData(gd);
	}	
	
	protected void showSymbolsDlg()
	{
	    DefinedSymbolsDialog dlg=new DefinedSymbolsDialog(getShell(), (IProject)getElement());
	    dlg.open();
	}
	
    /**
     * Creates a label in red to signal an error
     * @param composite the composite to which the label will be added
     */
    private void createError(Composite composite, String error) {
        GridData data;
        Label err=new Label(composite, SWT.NONE);
        err.setText(error);
        err.setForeground(new Color(Display.getCurrent(), 255, 0, 0));
        data=new GridData(GridData.FILL_HORIZONTAL);
        data.horizontalSpan=2;
        err.setLayoutData(data);
    }

    /**
	 * @see PreferencePage#createContents(Composite)
	 */
	protected Control createContents(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		composite.setLayout(layout);
		GridData data = new GridData(GridData.FILL);
		data.grabExcessHorizontalSpace = true;
		composite.setLayoutData(data);

		addFirstSection(composite);
		addSeparator(composite);
		addSecondSection(composite);
		addSeparator(composite);
		addThirdSection(composite);
		addSeparator(composite);
		addFourthSection(composite);
		return composite;
	}

	private Composite createDefaultComposite(Composite parent) {
		Composite composite = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		composite.setLayout(layout);

		GridData data = new GridData();
		data.verticalAlignment = GridData.FILL;
		data.horizontalAlignment = GridData.FILL;
		composite.setLayoutData(data);

		return composite;
	}

	protected void performDefaults() {
		// Populate the owner text field with the default value
		fPathText.setText(ProjectProperties.BUILD_PATH_DEFAULT);
		fIncPathText.setText(ProjectProperties.INC_PATH_DEFAULT);
//		fSrcPathText.setText(ProjectProperties.SRC_PATH_DEFAULT);
		fBuildCombo.select(0);
		fStopOnError.setSelection(false);
		updateCurrent();
	}
	
	public boolean performOk() {
		// store the value in the owner text field
		try {
		    IProject prj=(IProject)getElement();
			ProjectProperties.setBuildPath(prj, fPathText.getText());
//			ProjectProperties.setSrcPath(prj, fSrcPathText.getText());
			
			if (fSdkCombo!=null)
			{
				String sdkname=fSdkCombo.getResultName();
				if (!fCurrentSDK.equals(sdkname))
				    ProjectProperties.setSymbianSDKName(prj, sdkname);
			}
			
			ProjectProperties.setWin32ToolId(prj, fToolCombo.getResultId());
			
			int build=fBuildCombo.getSelectionIndex();
			if (build!=fCurrentBuild)
			    ProjectProperties.setABLDBuild(prj, fBuildCombo.getItem(build));
			
			ProjectProperties.setStopOnError(prj, fStopOnError.getSelection());
			
			String incpath=fIncPathText.getText();
			if (!fCurrentIncPath.equals(incpath))
			    ProjectProperties.setIncPath(prj, fIncPathText.getText());
		} catch (CoreException e) {
			SymbdevPlugin.getDefault().getLog().log(e.getStatus());
			return false;
		}
		updateCurrent();
		return true;
	}
	
	int fCurrentBuild;       // to check if build changed
	String fCurrentSDK;      // to check if SDK changed
	String fCurrentIncPath;  // to check if in path changed
	
	SymbianSDKCombo fSdkCombo;
	Win32ToolCombo fToolCombo;
	Combo fBuildCombo;
	Button fStopOnError;
}