/*
 * Copyright (c) 2012 Google Inc.
 *
 * 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
 */
package com.google.eclipse.terminal.local.ui.view;

import static com.google.eclipse.terminal.local.Activator.*;
import static com.google.eclipse.terminal.local.ImageKeys.*;
import static com.google.eclipse.terminal.local.ui.preferences.ColorsAndFontsPreferences.*;
import static com.google.eclipse.terminal.local.ui.preferences.GeneralPreferences.*;
import static com.google.eclipse.terminal.local.ui.view.Messages.*;
import static com.google.eclipse.terminal.local.util.Platform.userHomeDirectory;
import static org.eclipse.core.runtime.Path.fromOSString;
import static org.eclipse.core.runtime.Status.OK_STATUS;
import static org.eclipse.jface.resource.JFaceResources.TEXT_FONT;
import static org.eclipse.ui.IWorkbenchPage.VIEW_ACTIVATE;

import java.util.UUID;

import org.eclipse.core.runtime.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.*;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.widgets.*;
import org.eclipse.tm.internal.terminal.control.ITerminalListener;
import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
import org.eclipse.ui.*;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.UIJob;

import com.google.eclipse.terminal.local.core.connector.LifeCycleListener;
import com.google.eclipse.terminal.local.ui.preferences.AbstractPreferencesChangeListener;

/**
 * @author alruiz@google.com (Alex Ruiz)
 */
public class TerminalView extends ViewPart implements ISaveablePart2 {
  private static final String SCROLL_LOCK_ENABLED = "scrollLock";
  private static final String TITLE_STATE_TYPE = "title";
  private static final String WORKING_DIRECTORY_STATE_TYPE = "workingDirectory";

  private static final String VIEW_ID = "com.google.eclipse.terminal.local.localTerminalView";

  private IPropertyChangeListener preferencesChangeListener;
  private IPropertyChangeListener textFontChangeListener;
  private IMemento savedState;
  private TerminalWidget terminalWidget;
  private IPath workingDirectory;

  private Action newTerminalAction;
  private Action scrollLockAction;

  private boolean checkCanBeClosed;
  private boolean forceClose;

  public static void openTerminalView(IPath workingDirectory) {
    openTerminalView(null, workingDirectory);
  }

  private static void openTerminalView(String id, IPath workingDirectory) {
    IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
    IPath safeWorkingDirectory = (workingDirectory != null) ? workingDirectory : userHomeDirectory();
    try {
      String directoryName = safeWorkingDirectory.lastSegment();
      String secondaryId = (id != null) ? id : directoryName;
      TerminalView view = (TerminalView) page.showView(VIEW_ID, secondaryId, VIEW_ACTIVATE);
      view.setPartName(directoryName);
      view.open(safeWorkingDirectory);
    } catch (PartInitException e) {
      log("Unable to create Terminal View", e);
    }
  }

  @Override public void init(IViewSite site, IMemento memento) throws PartInitException {
    super.init(site, memento);
    savedState = memento;
  }

  @Override public void saveState(IMemento memento) {
    saveState(memento, SCROLL_LOCK_ENABLED, String.valueOf(terminalWidget.isScrollLockEnabled()));
    saveState(memento, TITLE_STATE_TYPE, getPartName());
    saveState(memento, WORKING_DIRECTORY_STATE_TYPE, workingDirectory.toOSString());
  }

  private void saveState(IMemento memento, String type, String data) {
    IMemento child = memento.createChild(type);
    child.putTextData(data);
  }

  @Override public void createPartControl(Composite parent) {
    terminalWidget = new TerminalWidget(parent, getViewSite());
    terminalWidget.setLifeCycleListener(new LifeCycleListener() {
      @Override public void executionFinished() {
        closeViewOnExitIfPossible();
      }
    });
    terminalWidget.setTerminalListener(new ITerminalListener() {
      @Override public void setTerminalTitle(final String title) {
        updatePartName(title);
      }

      @Override public void setState(TerminalState state) {
      }
    });
    IViewSite viewSite = getViewSite();
    preferencesChangeListener = new AbstractPreferencesChangeListener() {
      @Override protected void onBufferLineCountChanged() {
        updateBufferLineCount();
      }

      @Override protected void onColorChanged() {
        updateColors();
      }

      @Override protected void onFontChanged() {
        updateFont();
      }
    };
    preferenceStore().addPropertyChangeListener(preferencesChangeListener);
    updateBufferLineCount();
    updateColors();
    textFontChangeListener = new IPropertyChangeListener() {
      @Override public void propertyChange(PropertyChangeEvent event) {
        if (TEXT_FONT.equals(event.getProperty())) {
          if (!useCustomFont()) {
            setFont(JFaceResources.getTextFont());
          }
        }
      }
    };
    JFaceResources.getFontRegistry().addListener(textFontChangeListener);
    updateFont();
    setupToolBarActions();
    if (savedState != null) {
      updateScrollLockUsingSavedState();
      connectUsingSavedState();
      return;
    }
    if (viewSite.getSecondaryId() == null) {
      setPartName(defaultViewTitle);
      open(userHomeDirectory());
    }
    enableScrollLock(scrollLockAction.isChecked());
  }

  private void closeViewOnExitIfPossible() {
    if (closeViewOnExit() && terminalWidget != null && !terminalWidget.isDisposed()) {
      // must run in UI thread.
      forceClose = true;
      terminalWidget.getDisplay().asyncExec(new Runnable() {
        @Override public void run() {
          IWorkbenchPartSite site = getSite();
          site.getPage().hideView((IViewPart) site.getPart());
        }
      });
    }
  }

  private void updateColors() {
    terminalWidget.setColors(background(), foreground());
  }

  private void updateFont() {
    setFont(terminalFont());
  }

  private Font terminalFont() {
    if (useCustomFont()) {
      return new Font(Display.getDefault(), customFontData());
    }
    return JFaceResources.getTextFont();
  }

  private void setFont(Font font) {
    terminalWidget.setFont(font);
  }

  private void updateBufferLineCount() {
    terminalWidget.setBufferLineCount(bufferLineCount());
  }

  private void setupToolBarActions() {
    IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
    newTerminalAction = new NewTerminalAction();
    toolBarManager.add(newTerminalAction);
    scrollLockAction = new ScrollLockAction();
    toolBarManager.add(scrollLockAction);
  }

  private void updateScrollLockUsingSavedState() {
    boolean newValue = Boolean.valueOf(savedState(SCROLL_LOCK_ENABLED));
    enableScrollLockAndUpdateAction(newValue);
  }

  private void enableScrollLockAndUpdateAction(boolean enabled) {
    enableScrollLock(enabled);
    scrollLockAction.setChecked(enabled);
  }

  private void enableScrollLock(boolean enabled) {
    terminalWidget.enableScrollLock(enabled);
  }

  private void connectUsingSavedState() {
    String title = savedState(TITLE_STATE_TYPE);
    setPartName(title);
    String savedWorkingDirectory = savedState(WORKING_DIRECTORY_STATE_TYPE);
    if (savedWorkingDirectory != null) {
      open(fromOSString(savedWorkingDirectory));
    }
  }

  private String savedState(String type) {
    IMemento child = savedState.getChild(type);
    return (child != null) ? child.getTextData() : null;
  }

  private void open(IPath workingDirectory) {
    if (terminalWidget.isConnected()) {
      return;
    }
    this.workingDirectory = workingDirectory;
    terminalWidget.setWorkingDirectory(workingDirectory);
    terminalWidget.connect();
  }

  private void updatePartName(final String value) {
    UIJob job = new UIJob("Update terminal view title") {
      @Override public IStatus runInUIThread(IProgressMonitor monitor) {
        setPartName(value);
        return OK_STATUS;
      }
    };
    job.schedule();
  }

  @Override public void setFocus() {
    terminalWidget.setFocus();
  }

  @Override public void dispose() {
    if (preferencesChangeListener != null) {
      preferenceStore().removePropertyChangeListener(preferencesChangeListener);
    }
    if (textFontChangeListener != null) {
      JFaceResources.getFontRegistry().removeListener(textFontChangeListener);
    }
    super.dispose();
  }

  private class NewTerminalAction extends Action {
    NewTerminalAction() {
      setImageDescriptor(imageDescriptor(NEW_TERMINAL));
      setText(newLocalTerminal);
    }

    @Override public void run() {
      openTerminalView(UUID.randomUUID().toString(), workingDirectory);
    }
  }

  private class ScrollLockAction extends Action {
    ScrollLockAction() {
      super(scrollLock, AS_RADIO_BUTTON);
      setChecked(false);
      setImageDescriptor(imageDescriptor(SCROLL_LOCK));
    }

    @Override public void run() {
      boolean newValue = !terminalWidget.isScrollLockEnabled();
      enableScrollLockAndUpdateAction(newValue);
    }
  }

  @Override public boolean isDirty() {
    if (checkCanBeClosed) {
      checkCanBeClosed = false;
      return true;
    }
    return false;
  }

  @Override public boolean isSaveOnCloseNeeded() {
    if (forceClose) {
      return false;
    }
    checkCanBeClosed = true;
    return true;
  }

  @Override public int promptToSaveOnClose() {
    if (warnOnClose()) {
      boolean close = WarnOnCloseDialog.open(terminalWidget.getShell());
      if (!close) {
        return CANCEL;
      }
    }
    return NO;
  }

  @Override public void doSave(IProgressMonitor monitor) {}

  @Override public void doSaveAs() {}

  @Override public boolean isSaveAsAllowed() {
    return false;
  }
}
