/*
 * 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.contexts.*;
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;

  private IContextActivation contextActivation;

  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();
    IContextService contextService = contextService();
    if (contextService != null) {
      contextActivation = contextService.activateContext("com.google.eclipse.terminal.local.context.localTerminal");
    }
    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 (contextActivation != null) {
      IContextService contextService = contextService();
      if (contextService != null) {
        contextService.deactivateContext(contextActivation);
      }
    }
    if (preferencesChangeListener != null) {
      preferenceStore().removePropertyChangeListener(preferencesChangeListener);
    }
    if (textFontChangeListener != null) {
      JFaceResources.getFontRegistry().removeListener(textFontChangeListener);
    }
    super.dispose();
  }

  private IContextService contextService() {
    return (IContextService) getSite().getService(IContextService.class);
  }

  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;
  }
}
