/*******************************************************************************
 * Copyright (c) 2007 The Eclipse Foundation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *    The Eclipse Foundation - initial API and implementation
 *******************************************************************************/
package org.eclipse.epp.usagedata.internal.ui.preferences;

import java.util.Date;

import org.eclipse.epp.usagedata.internal.gathering.UsageDataCaptureActivator;
import org.eclipse.epp.usagedata.internal.gathering.settings.UsageDataCaptureSettings;
import org.eclipse.epp.usagedata.internal.recording.UsageDataRecordingActivator;
import org.eclipse.epp.usagedata.internal.recording.settings.UsageDataRecordingSettings;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;

import java.text.MessageFormat;

public class UsageDataUploadingPreferencesPage extends PreferencePage
	implements IWorkbenchPreferencePage {

	private static final int MILLISECONDS_IN_ONE_DAY = 24 * 60 * 60 * 1000;

	private static final long MINIMUM_PERIOD_IN_DAYS = UsageDataRecordingSettings.PERIOD_REASONABLE_MINIMUM / MILLISECONDS_IN_ONE_DAY;
	private static final long MAXIMUM_PERIOD_IN_DAYS = 90;
	
	private Text uploadPeriodText;
	private Label label;
	private Text lastUploadText;

	private Button askBeforeUploadingCheckbox;

	private Button uploadNowButton;
	
	IPropertyChangeListener capturePropertyChangeListener = new IPropertyChangeListener() {
		public void propertyChange(PropertyChangeEvent event) {
			if (UsageDataCaptureSettings.CAPTURE_ENABLED_KEY.equals(event.getProperty())) {
				updateButtons();
				return;
			}
		}		
	};

	IPropertyChangeListener recordingPropertyChangeListener = new IPropertyChangeListener() {
		public void propertyChange(PropertyChangeEvent event) {			
			if (UsageDataRecordingSettings.ASK_TO_UPLOAD_KEY.equals(event.getProperty())) {
				getControl().getDisplay().syncExec(new Runnable() {
					public void run() {
						updateAskToUploadCheckbox();
					}
				});
				return;
			}

			if (UsageDataRecordingSettings.UPLOAD_PERIOD_KEY.equals(event.getProperty())) {
				getControl().getDisplay().syncExec(new Runnable() {
					public void run() {
						updateUploadPeriodText();
					}
				});				
				return;
			}
			
			if (UsageDataRecordingSettings.LAST_UPLOAD_KEY.equals(event.getProperty())) {
				getControl().getDisplay().syncExec(new Runnable() {
					public void run() {
						updateLastUploadText();
					}
				});
				return;
			}
		}		
	};

	public UsageDataUploadingPreferencesPage() {
		setDescription(Messages.UsageDataUploadingPreferencesPage_0); 
		setPreferenceStore(UsageDataRecordingActivator.getDefault().getPreferenceStore());
	}

	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
	 */
	public void init(IWorkbench workbench) {
		getCapturePreferenceStore().addPropertyChangeListener(capturePropertyChangeListener);
		getPreferenceStore().addPropertyChangeListener(recordingPropertyChangeListener);
	}
	
	@Override
	public void dispose() {
		getCapturePreferenceStore().removePropertyChangeListener(capturePropertyChangeListener);
		getPreferenceStore().removePropertyChangeListener(recordingPropertyChangeListener);
		super.dispose();
	}

	@Override
	protected Control createContents(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		composite.setLayout(new GridLayout());
		
		createGeneralInformationArea(composite);
		createUploadingArea(composite);
		createButtonsArea(composite);
		
		Label filler = new Label(parent, SWT.NONE);
		filler.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true));
		
		initialize();
		
		return composite;
	}

	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void initialize() {
		updateAskToUploadCheckbox();		
		updateUploadPeriodText();		
		updateLastUploadText();
		updateButtons();
	}

	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void updateLastUploadText() {
		lastUploadText.setText(getLastUploadDateAsString());
	}


	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void updateUploadPeriodText() {
		uploadPeriodText.setText(String.valueOf(getRecordingPreferences().getLong(UsageDataRecordingSettings.UPLOAD_PERIOD_KEY) / MILLISECONDS_IN_ONE_DAY));
	}


	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void updateAskToUploadCheckbox() {
		askBeforeUploadingCheckbox.setSelection(getRecordingPreferences().getBoolean(UsageDataRecordingSettings.ASK_TO_UPLOAD_KEY));
	}
	
	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void updateButtons() {
		uploadNowButton.setEnabled(getCapturePreferenceStore().getBoolean(UsageDataCaptureSettings.CAPTURE_ENABLED_KEY));
	}


	private IPreferenceStore getCapturePreferenceStore() {
		return UsageDataCaptureActivator.getDefault().getPreferenceStore();
	}


	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	@Override
	public boolean performOk() {		
		getRecordingPreferences().setValue(UsageDataRecordingSettings.ASK_TO_UPLOAD_KEY, askBeforeUploadingCheckbox.getSelection());		
		getRecordingPreferences().setValue(UsageDataRecordingSettings.UPLOAD_PERIOD_KEY, Long.valueOf(uploadPeriodText.getText()) * MILLISECONDS_IN_ONE_DAY);
		
		return super.performOk();
	}
	
	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	@Override
	public boolean isValid() {
		if (!isValidUploadPeriod(uploadPeriodText.getText())) return false;
		return true;
	}

	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	@Override
	protected void performDefaults() {
		askBeforeUploadingCheckbox.setSelection(getRecordingPreferences().getDefaultBoolean(UsageDataRecordingSettings.ASK_TO_UPLOAD_KEY));
		uploadPeriodText.setText(String.valueOf(getRecordingPreferences().getDefaultLong(UsageDataRecordingSettings.UPLOAD_PERIOD_KEY) / MILLISECONDS_IN_ONE_DAY));

		updateLastUploadText();

		super.performDefaults();
	}

	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void createGeneralInformationArea(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false));
		
		composite.setLayout(new GridLayout());
				
		askBeforeUploadingCheckbox = new Button(composite, SWT.CHECK | SWT.LEFT);
		askBeforeUploadingCheckbox.setText(Messages.UsageDataUploadingPreferencesPage_1);  
	}


	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void createUploadingArea(Composite parent) {
		Group group = new Group(parent, SWT.NONE);
		group.setText(Messages.UsageDataUploadingPreferencesPage_2); 
		group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

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

		// Create the layout that will be used by all the fields.
		GridData fieldLayoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
		fieldLayoutData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
			
		createUploadPeriodField(group);
		createLastUploadField(group);
		createUploadUrlField(group);
	}
		
	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void createUploadPeriodField(Group composite) {
		Label label = new Label(composite, SWT.NONE);
		label.setText(Messages.UsageDataUploadingPreferencesPage_3); 
		
		uploadPeriodText = new Text(composite, SWT.SINGLE | SWT.BORDER | SWT.RIGHT);
		uploadPeriodText.setTextLimit(2);
		GridData gridData = new GridData(SWT.FILL, SWT.CENTER, false, false);
		gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
		gridData.horizontalSpan = 1;
		GC gc = new GC(uploadPeriodText.getDisplay());
		gc.setFont(uploadPeriodText.getFont());
		gridData.widthHint = gc.stringExtent(String.valueOf(MAXIMUM_PERIOD_IN_DAYS)).x;
		gc.dispose();
		uploadPeriodText.setLayoutData(gridData);
		
		new Label(composite, SWT.NONE).setText(Messages.UsageDataUploadingPreferencesPage_4); 
		
		final ControlDecoration rangeErrorDecoration = new ControlDecoration(uploadPeriodText, SWT.LEFT | SWT.TOP);
		rangeErrorDecoration.setDescriptionText(MessageFormat.format(Messages.UsageDataUploadingPreferencesPage_5, new Object[] {MINIMUM_PERIOD_IN_DAYS, MAXIMUM_PERIOD_IN_DAYS})); 
		rangeErrorDecoration.setImage(getErrorImage());
		rangeErrorDecoration.hide();
		
		uploadPeriodText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String contents = uploadPeriodText.getText();
				if (isValidUploadPeriod(contents))
					rangeErrorDecoration.hide();
				else {
					rangeErrorDecoration.show();
				}
				updateApplyButton();
				getContainer().updateButtons();
			}
		});
		if (System.getProperty(UsageDataRecordingSettings.UPLOAD_PERIOD_KEY) != null) {
			addOverrideWarning(uploadPeriodText);
		}
	}
	
	private boolean isValidUploadPeriod(String text) {
		try {
			long value = Long.parseLong(text);
			if (value < MINIMUM_PERIOD_IN_DAYS)
				return false;
			if (value > MAXIMUM_PERIOD_IN_DAYS)
				return false;
		} catch (NumberFormatException e) {
			return false;
		}
		return true;
	}
		
	private Image getErrorImage() {
		return FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR).getImage();
	}
	
	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void createLastUploadField(Group composite) {
		label = new Label(composite, SWT.NONE);
		label.setText(Messages.UsageDataUploadingPreferencesPage_6); 
		
		lastUploadText = new Text(composite, SWT.SINGLE | SWT.BORDER);
		lastUploadText.setEnabled(false);
		GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
		gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
		gridData.horizontalSpan = 2;
		lastUploadText.setLayoutData(gridData);
	}
	
	/*
	 * The Upload URL is not expected to change during execution, so
	 * we make not consideration for changes while the preferences
	 * page is open.
	 * 
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void createUploadUrlField(Group composite) {
		label = new Label(composite, SWT.NONE);
		label.setText(Messages.UsageDataUploadingPreferencesPage_9); 
		
		Text uploadUrlText = new Text(composite, SWT.SINGLE | SWT.BORDER);
		uploadUrlText.setEnabled(false);
		GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
		gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
		gridData.horizontalSpan = 2;
		uploadUrlText.setLayoutData(gridData);
		uploadUrlText.setText(getSettings().getUploadUrl());
	}
	
	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void createButtonsArea(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

		composite.setLayout(new RowLayout());

		createUploadNowButton(composite);
	}

	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	protected IWorkbenchPage getPage() {
		return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
	}


	protected UsageDataRecordingSettings getSettings() {
		return UsageDataRecordingActivator.getDefault().getSettings();
	}


	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void createUploadNowButton(Composite composite) {
		uploadNowButton = new Button(composite, SWT.PUSH);
		uploadNowButton.setText(Messages.UsageDataUploadingPreferencesPage_7); 
		uploadNowButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				UsageDataRecordingActivator.getDefault().getUploadManager().startUpload();
			}
		});
	}
	
	/*
	 * Note that this method expects to be run in the UI Thread.
	 */
	private void addOverrideWarning(Control control) {
		FieldDecoration decoration = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
		ControlDecoration warning = new ControlDecoration(control, SWT.BOTTOM | SWT.LEFT);
		warning.setImage(decoration.getImage());
		warning.setDescriptionText(Messages.UsageDataUploadingPreferencesPage_8); 
	}

	private String getLastUploadDateAsString() {
		long time = getRecordingSettings().getLastUploadTime();
		Date date = new Date(time);
		return date.toString();
	}


	private IPreferenceStore getRecordingPreferences() {
		return UsageDataRecordingActivator.getDefault().getPreferenceStore();
	}

	private UsageDataRecordingSettings getRecordingSettings() {
		return UsageDataRecordingActivator.getDefault().getSettings();
	}
}