/* 
-*- coding: latin-1 -*-

This file is part of RefactorErl.

RefactorErl is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

RefactorErl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with RefactorErl.  If not, see <http://plc.inf.elte.hu/erlang/>.

The Original Code is RefactorErl.

The Initial Developer of the Original Code is Eötvös Loránd University.
Portions created  by Eötvös Loránd University and ELTE-Soft Ltd.
are Copyright 2007-2025 Eötvös Loránd University, ELTE-Soft Ltd.
and Ericsson Hungary. All Rights Reserved.
 */

package com.refactorerl.ui.presentation;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;

import com.refactorerl.ui.common.Environment;
import com.refactorerl.ui.communication.process.ReferlProcess;
import com.refactorerl.ui.communication.process.ReferlProcess.DatabaseType;

/**
 * Creates the widgets for RefactorErl preference page. Starting method is
 * createContents(Composite parent).
 * 
 * @author Daniel Lukacs, 2014 ELTE IK
 *
 */
public class WorkbenchPreferencePage extends PreferencePage implements
		IWorkbenchPreferencePage { 	// this class needs a refactoring

	private Text logDirText;
	private Button logDirButton;
	private Text eclDataDirText;
	private Button eclDataDirButton;
	private IPreferenceStore store;
	private Text cookieText;
	private Text clientAlivenameText;
	private Text serverAddressText;
	private Text localServerAddress;
	private Button useLocalServerCheckbox;
	private Text baseDirText;
	private Button baseDirButton;
	private Combo dbTypeCombo;
	private Text referlDataDirText;
	private Button referlDataDirButton;

	private Button reconnectCheckbox;
	private Button debugCheckbox;
	private Composite cmp;

	@Override
	public void init(IWorkbench workbench) {

	}

	@Override
	protected IPreferenceStore doGetPreferenceStore() {
		return Activator.getDefault().getPreferenceStore();
	}

	private Text createLabelledText(Composite parent, String labelLabel,
			String prefKey) {
		Label label = new Label(parent, SWT.LEFT);
		label.setText(labelLabel);
		Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
		text.setText(store.getString(prefKey));
		return text;
	}

	@Override
	protected Control createContents(Composite parent) { // SWT/JFace code

		cmp = new Composite(parent, SWT.NONE);

		store = Activator.getDefault().getPreferenceStore();

		cmp.setLayout(new GridLayout(3, false));

		// row
		final Label logDirLabel = new Label(cmp, SWT.NONE);
		logDirLabel.setText(Messages.WorkbenchPreferencePage1_0);

		logDirText = new Text(cmp, SWT.SINGLE | SWT.BORDER);
		logDirText.setText(store.getString("logs_dir")); //$NON-NLS-1$

		logDirButton = new Button(cmp, SWT.PUSH);
		logDirButton.setText(Messages.WorkbenchPreferencePage1_2);
		logDirButton.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				DirectoryDialog dialog = new DirectoryDialog(cmp.getShell());
				String logsDir = dialog.open();
				if (logsDir != null)
					logDirText.setText(logsDir);
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// not called
			}
		});

		// row
		final Label eclDataDirLabel = new Label(cmp, SWT.NONE);
		eclDataDirLabel.setText(Messages.WorkbenchPreferencePage1_3);
		eclDataDirText = new Text(cmp, SWT.SINGLE | SWT.BORDER);
		eclDataDirText.setText(store.getString("data_dir")); //$NON-NLS-1$

		eclDataDirButton = new Button(cmp, SWT.PUSH);
		eclDataDirButton.setText(Messages.WorkbenchPreferencePage1_5);
		eclDataDirButton.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				DirectoryDialog dialog = new DirectoryDialog(cmp.getShell());
				String dataDir = dialog.open();
				if (dataDir != null)
					eclDataDirText.setText(dataDir);
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// not called

			}
		});
	
		// row
		Label useLocalServerLabel = new Label(cmp, SWT.NONE);
		useLocalServerLabel.setText(Messages.WorkbenchPreferencePage1_1);
		useLocalServerCheckbox = new Button(cmp, SWT.CHECK | SWT.LEFT);
		useLocalServerCheckbox.setSelection(store.getBoolean("local_server")); //$NON-NLS-1$

		new Label(cmp, SWT.NONE); // placeholder
		
		// row
		Label sep =	new Label(cmp, SWT.SEPARATOR | SWT.HORIZONTAL);
		sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		new Label(cmp, SWT.NONE); // placeholder
		new Label(cmp, SWT.NONE); // placeholder
		
		// row
		serverAddressText = createLabelledText(cmp,
				Messages.WorkbenchPreferencePage1_8, "server_address"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-1$
	
		new Label(cmp, SWT.NONE); // placeholder
		
		// row
		clientAlivenameText = createLabelledText(cmp,
				Messages.WorkbenchPreferencePage1_6, "client_alivename"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-1$
		new Label(cmp, SWT.NONE); // placeholder
		
		// row
		cookieText = createLabelledText(cmp,
				Messages.WorkbenchPreferencePage_0, "cookie"); //$NON-NLS-2$ 
		new Label(cmp, SWT.NONE); // placeholder
		
		sep =	new Label(cmp, SWT.SEPARATOR | SWT.HORIZONTAL);
		sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		new Label(cmp, SWT.NONE); // placeholder
		new Label(cmp, SWT.NONE); // placeholder
		
		// row
		final Label baseDirLabel = new Label(cmp, SWT.NONE);
		baseDirLabel.setText(Messages.WorkbenchPreferencePage1_13);
		baseDirText = new Text(cmp, SWT.SINGLE | SWT.BORDER);
		baseDirText.setText(store.getString("refactorerl_base_dir")); //$NON-NLS-1$
		configureGridData(baseDirText, SWT.FILL, SWT.NONE, true, false);

		baseDirButton = new Button(cmp, SWT.PUSH);
		baseDirButton.setText(Messages.WorkbenchPreferencePage1_15);
		baseDirButton.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				DirectoryDialog dialog = new DirectoryDialog(cmp.getShell());
				String baseDir = dialog.open();
				if (baseDir != null)
					baseDirText.setText(baseDir);
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// not called

			}
		});

		// row
		Label dbTypeLabel = new Label(cmp, SWT.NONE);
		dbTypeLabel.setText(Messages.WorkbenchPreferencePage1_20);
		dbTypeCombo = new Combo(cmp, SWT.NONE);

		dbTypeCombo.add(DatabaseType.NIF.toString());
		dbTypeCombo.add(DatabaseType.MNESIA.toString());
		dbTypeCombo.add(DatabaseType.KYOTO.toString());
		dbTypeCombo.select(dbTypeCombo.indexOf(store.getString("db_type"))); //$NON-NLS-1$
		new Label(cmp, SWT.NONE); // placeholder

		// row
		localServerAddress = createLabelledText(cmp,
				Messages.WorkbenchPreferencePage1_18, "local_server_address"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-1$
		new Label(cmp, SWT.NONE); // placeholder

		// row
		Label referlDataDirLabel = new Label(cmp, SWT.NONE);
		referlDataDirLabel.setText(Messages.WorkbenchPreferencePage1_21);
		referlDataDirText = new Text(cmp, SWT.SINGLE | SWT.BORDER);
		referlDataDirText.setText(store.getString("refactorerl_data_dir")); //$NON-NLS-1$
		configureGridData(referlDataDirText, SWT.FILL, SWT.NONE, true, false);

		referlDataDirButton = new Button(cmp, SWT.PUSH);
		referlDataDirButton.setText(Messages.WorkbenchPreferencePage1_23);
		referlDataDirButton.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				DirectoryDialog dialog = new DirectoryDialog(cmp.getShell());
				String dataDir = dialog.open();
				if (dataDir != null)
					referlDataDirText.setText(dataDir);
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// not called

			}
		});
		
		serverAddressText.setEnabled(!store.getBoolean("local_server")); //$NON-NLS-1$
		clientAlivenameText.setEnabled(!store.getBoolean("local_server")); //$NON-NLS-1$
		cookieText.setEnabled(!store.getBoolean("local_server")); //$NON-NLS-1$
		
		baseDirButton.setEnabled(store.getBoolean("local_server")); //$NON-NLS-1$
		baseDirText.setEnabled(store.getBoolean("local_server")); //$NON-NLS-1$		
		localServerAddress.setEnabled(store.getBoolean("local_server")); //$NON-NLS-1$
		dbTypeCombo.setEnabled(store.getBoolean("local_server")); //$NON-NLS-1$
		referlDataDirText
				.setEnabled(store.getBoolean("local_server")); //$NON-NLS-1$
		referlDataDirButton
				.setEnabled(store.getBoolean("local_server")); //$NON-NLS-1$

		useLocalServerCheckbox.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				boolean useLocalServer = useLocalServerCheckbox.getSelection();

				serverAddressText.setEnabled(!useLocalServer);
				clientAlivenameText.setEnabled(!useLocalServer);
				cookieText.setEnabled(!useLocalServer);
				localServerAddress.setEnabled(useLocalServer);
				baseDirButton.setEnabled(useLocalServer);
				baseDirText.setEnabled(useLocalServer);
				dbTypeCombo.setEnabled(useLocalServer);
				referlDataDirText.setEnabled(useLocalServer);
				referlDataDirButton.setEnabled(useLocalServer);
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// not called
			}
		});

		sep =	new Label(cmp, SWT.SEPARATOR | SWT.HORIZONTAL);
		sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		new Label(cmp, SWT.NONE); // placeholder
		new Label(cmp, SWT.NONE); // placeholder
		
		// row
		Label reconnectLabel = new Label(cmp, SWT.NONE);
		reconnectLabel.setText(Messages.WorkbenchPreferencePage1_31);
		reconnectCheckbox = new Button(cmp, SWT.CHECK | SWT.LEFT);
		reconnectCheckbox.setSelection(false);
		new Label(cmp, SWT.NONE); // placeholder

		// row
		Label debugLabel = new Label(cmp, SWT.NONE);
		debugLabel.setText(Messages.WorkbenchPreferencePage_10);
		debugCheckbox = new Button(cmp, SWT.CHECK | SWT.LEFT);
		debugCheckbox.setSelection(store.getBoolean("debug_mode")); //$NON-NLS-1$
		new Label(cmp, SWT.NONE); // placeholder
		
		return parent;
	}

	// NOTE error prone, needs rewrite (hashmap?)
	@Override
	public boolean performOk() {
		if(Environment.isLocalSysWindows() && dbTypeCombo.getText().equals(ReferlProcess.DatabaseType.KYOTO.toString())){ //$NON-NLS-1$
			MessageDialog.openError(cmp.getShell(), Messages.WorkbenchPreferencePage_13, Messages.WorkbenchPreferencePage_14);
			return false;
		}
		
		if(logDirText.getText().isEmpty()){
			logDirText.setText(store.getDefaultString("logs_dir")); //$NON-NLS-1$
		}
		if(eclDataDirText.getText().isEmpty()){
			eclDataDirText.setText(store.getDefaultString("data_dir")); //$NON-NLS-1$
		}
	
		boolean restartNeeded = !store.getString("client_alivename").equals(clientAlivenameText.getText()) //$NON-NLS-1$
				|| !(store.getBoolean("local_server") == useLocalServerCheckbox.getSelection()) //$NON-NLS-1$
				|| !store.getString("cookie").equals(cookieText.getText()) //$NON-NLS-1$
				|| !store
						.getString("server_address").equals(serverAddressText.getText()) //$NON-NLS-1$
				|| !store
						.getString("local_server_address").equals(localServerAddress.getText()) //$NON-NLS-1$
				||  !store.getString("refactorerl_base_dir").equals( //$NON-NLS-1$
						baseDirText.getText())
				|| !store.getString("db_type").equals(dbTypeCombo.getText()) //$NON-NLS-1$
				|| !store
						.getString("refactorerl_data_dir").equals(referlDataDirText.getText()) //$NON-NLS-1$
				|| !(store.getBoolean("debug_mode") == debugCheckbox.getSelection()); //$NON-NLS-1$
		
		boolean resetLogsNeeded = !store.getString("logs_dir").equals( //$NON-NLS-1$
				logDirText.getText()) ; 
	
		store.setValue("logs_dir", logDirText.getText()); //$NON-NLS-1$
		store.setValue("data_dir", eclDataDirText.getText()); //$NON-NLS-1$

		store.setValue("local_server", useLocalServerCheckbox.getSelection()); //$NON-NLS-1$
		store.setValue("debug_mode", debugCheckbox.getSelection()); //$NON-NLS-1$

		if (!store.getBoolean("local_server")){ //$NON-NLS-1$
			store.setValue("server_address", serverAddressText.getText()); //$NON-NLS-1$	
			store.setValue("client_alivename", clientAlivenameText.getText()); //$NON-NLS-1$
			store.setValue("cookie", cookieText.getText().trim()); //$NON-NLS-1$
		} else {
			store.setValue(
						"local_server_address", localServerAddress.getText()); //$NON-NLS-1$
			store.setValue("refactorerl_base_dir", baseDirText.getText()); //$NON-NLS-1$
			store.setValue("db_type", dbTypeCombo.getText()); //$NON-NLS-1$
			store.setValue(
					"refactorerl_data_dir", referlDataDirText.getText()); //$NON-NLS-1$
		}

		if (resetLogsNeeded) {
			Activator.resetLogHandlers();
		}

		if (reconnectCheckbox.getSelection()
				|| (restartNeeded && MessageDialog.openQuestion(cmp.getShell(),
						Messages.WorkbenchPreferencePage1_50,
						Messages.WorkbenchPreferencePage1_51
								+ Messages.WorkbenchPreferencePage1_52))){
			Activator.getDefault().restart();
		}
		
		return super.performOk();
	}
	@Override
	public boolean performCancel() {
		logDirText.setText(store.getString("logs_dir")); //$NON-NLS-1$
		clientAlivenameText.setText(store.getString("client_alivename")); //$NON-NLS-1$
		serverAddressText.setText(store.getString("server_address")); //$NON-NLS-1$
		cookieText.setText(store.getString("cookie")); //$NON-NLS-1$
		useLocalServerCheckbox.setSelection(store.getBoolean("local_server")); //$NON-NLS-1$
		localServerAddress.setText(store.getString("local_server_address")); //$NON-NLS-1$
		baseDirText.setText(store.getString("refactorerl_base_dir")); //$NON-NLS-1$
		dbTypeCombo.setText(store.getString("db_type")); //$NON-NLS-1$
		referlDataDirText.setText(store.getString("refactorerl_data_dir")); //$NON-NLS-1$
		debugCheckbox.setSelection(store.getBoolean("debug_mode")); //$NON-NLS-1$
	return super.performCancel();
	}
	@Override
	protected void performDefaults() {

		super.performDefaults();
		
		logDirText.setText(store.getDefaultString("logs_dir")); //$NON-NLS-1$
		clientAlivenameText.setText(store.getDefaultString("client_alivename")); //$NON-NLS-1$
		serverAddressText.setText(store.getDefaultString("server_address")); //$NON-NLS-1$
		cookieText.setText(store.getDefaultString("cookie")); //$NON-NLS-1$
		useLocalServerCheckbox.setSelection(store.getDefaultBoolean("local_server")); //$NON-NLS-1$	
		localServerAddress.setText(store.getDefaultString("local_server_address")); //$NON-NLS-1$
		baseDirText.setText(store.getDefaultString("refactorerl_base_dir")); //$NON-NLS-1$
		dbTypeCombo.setText(store.getDefaultString("db_type")); //$NON-NLS-1$
		referlDataDirText.setText(store.getDefaultString("refactorerl_data_dir")); //$NON-NLS-1$
		debugCheckbox.setSelection(store.getDefaultBoolean("debug_mode")); //$NON-NLS-1$
		
		serverAddressText.setEnabled(true);
		clientAlivenameText.setEnabled(true);
		cookieText.setEnabled(true);
		localServerAddress.setEnabled(false);
		baseDirButton.setEnabled(false);
		baseDirText.setEnabled(false);
		dbTypeCombo.setEnabled(false);
		referlDataDirText.setEnabled(false);
		referlDataDirButton.setEnabled(false);

	}

	private GridData configureGridData(final Control control,
			int horizontalAlignment, int verticalAlignment,
			boolean grabExcessHorizontalSpace, boolean grabExcessVerticalSpace) {
		GridData data = new GridData(horizontalAlignment, verticalAlignment,
				grabExcessHorizontalSpace, grabExcessVerticalSpace);
		control.setLayoutData(data);
		return data;
	}


}
