/*******************************************************************************
 * Copyright (c) 2010 BSI Business Systems Integration AG.
 * 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:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.scout.nls.sdk.simple.ui.wizard;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator;
import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.JavaElementSorter;
import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
import org.eclipse.jdt.ui.wizards.NewTypeWizardPage;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.scout.nls.sdk.internal.NlsCore;
import org.eclipse.scout.nls.sdk.internal.jdt.IResourceFilter;
import org.eclipse.scout.nls.sdk.internal.jdt.NlsJdtUtility;
import org.eclipse.scout.nls.sdk.internal.ui.FieldValidator;
import org.eclipse.scout.nls.sdk.internal.ui.NlsUi;
import org.eclipse.scout.nls.sdk.internal.ui.TextButtonField;
import org.eclipse.scout.nls.sdk.internal.ui.TextField;
import org.eclipse.scout.nls.sdk.internal.ui.dialog.ResourceDialog;
import org.eclipse.scout.nls.sdk.internal.ui.fields.IInputChangedListener;
import org.eclipse.scout.nls.sdk.internal.ui.fields.TextProposalField;
import org.eclipse.scout.nls.sdk.internal.ui.formatter.IInputValidator;
import org.eclipse.scout.nls.sdk.simple.internal.NlsSdkSimple;
import org.eclipse.scout.nls.sdk.simple.operations.NewNlsFileOperationDesc;
import org.eclipse.scout.nls.sdk.util.concurrent.Lock;
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.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;

@SuppressWarnings({"restriction", "deprecation"})
public class NewNlsFileWizardPage2 extends NewTypeWizardPage {

  private Composite m_rootPane;

  private TextButtonField m_containerField;
  private TextProposalField m_package;
  private TextField<String> m_className;

  private TextProposalField m_translationFolderField;
  private TextField<String> m_translationFileName;

  private final FieldValidator m_fieldValidator;
  private final P_RootContainerModifyListener m_containerFieldModifyListener;

  private final NewNlsFileOperationDesc m_desc;

  private final Lock m_lock = new Lock();
  private final PackageProposalModel m_packageProposalModel;

  public NewNlsFileWizardPage2(String pageName, NewNlsFileOperationDesc desc) {
    super(true, pageName);
    setTitle("Create a new NLS class");
    setDescription("This class will be referenced to get a translated text.");
    m_desc = desc;
    m_fieldValidator = new FieldValidator();
    m_containerFieldModifyListener = new P_RootContainerModifyListener();
    m_packageProposalModel = new PackageProposalModel();
    setPageComplete(false);
  }

  @Override
  public void createControl(Composite parent) {
    m_rootPane = new Composite(parent, SWT.NONE);

    attachGridData(createServiceGroup(m_rootPane));
    attachGridData(createTranslationGroup(m_rootPane));

    // layout
    m_rootPane.setLayout(new GridLayout(1, false));
    initUi();
  }

  private void initUi() {
    m_desc.addPropertyChangeListener(new P_DescPropertyChangedListener());
    for (Entry<String, Object> entry : m_desc.getPropertiesMap().entrySet()) {
      handlePropertyChanged(entry.getKey(), null, entry.getValue());
    }
  }

  protected Control createServiceGroup(Composite parent) {
    Group group = new Group(parent, SWT.NONE);
    group.setText("Texts Class");

    m_containerField = new TextButtonField(group);
    m_fieldValidator.addField(m_containerField);
    // m_containerField.setInputFormatter(new P_RootPackageFormatter());
    // m_containerField.setTextEnabled(false);
    m_containerField.setLabelText("Source Folder");
    m_containerField.setButtonText("Browse");
    m_containerField.addTextModifyListener(m_containerFieldModifyListener);
    m_containerField.addButtonSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        IPackageFragmentRoot frag = chooseContainer();
        setPackageFragmentRoot(frag, false);
        if (frag == null) {
          m_desc.setSourceContainer(null);
        }
        else {
          m_desc.setSourceContainer(frag.getPath());
        }
      }
    });

    KeyStroke stoke = KeyStroke.getInstance(SWT.CONTROL, ' ');
    m_package = new TextProposalField(group, m_packageProposalModel, stoke);
    m_package.setLabelText("Package");
    m_package.addModifyListener(new ModifyListener() {
      @Override
      public void modifyText(ModifyEvent e) {
        m_desc.setPackage(m_package.getText());
      }
    });

    m_package.setLabelProvider(m_packageProposalModel);
    NlsUi.decorate(m_package, false);
    m_fieldValidator.addField(m_package);

    m_className = new TextField<String>(group);
    m_fieldValidator.addField(m_className);
    m_className.setLabelText("Class Name");
    m_className.addInputChangedListener(new IInputChangedListener<String>() {
      @Override
      public void inputChanged(String input) {
        m_desc.setClassName(input);
      }
    });
    m_className.setInputValidator(new IInputValidator() {
      private String m_regexp = "\\b[A-Za-z][a-zA-Z0-9_]{0,200}\\b";

      @Override
      public IStatus isValid(String value) {
        if (value.matches(m_regexp)) {
          return Status.OK_STATUS;
        }
        return Status.CANCEL_STATUS;
      }
    });

    group.setLayout(new GridLayout(1, true));
    attachGridData(m_containerField);
    attachGridData(m_package);
    attachGridData(m_className);

    return group;
  }

  private Control createTranslationGroup(Composite parent) {
    Group group = new Group(parent, SWT.NONE);
    group.setText("Translation File(s)");
    ResourceProposalModel model = new ResourceProposalModel();
    List<IProject> projectList = new ArrayList<IProject>();
    if (m_desc.getPlugin() != null) {
      try {
        projectList = NlsSdkSimple.getProjectGroup(m_desc.getPlugin());
      }
      catch (FileNotFoundException e) {
        NlsCore.logWarning(e);
      }
      catch (CoreException e) {
        NlsCore.logWarning(e);
      }
    }

    model.setResourceFilter(new IResourceFilter() {
      @Override
      public boolean accept(IProject project, IResource resource) {
        if (resource instanceof IFolder) {
          IFolder folder = (IFolder) resource;
          IJavaProject jp = JavaCore.create(project);
          try {
            if (jp.getOutputLocation().toOSString().equals(folder.getFullPath().toOSString())) {
              return false;
            }
          }
          catch (JavaModelException e) {
            NlsCore.logWarning(e);
          }
          if (folder.getProjectRelativePath().toOSString().equals("META-INF")) {
            return false;
          }
          return true;
        }
        return false;
      }
    });
    model.setProjects(projectList.toArray(new IProject[projectList.size()]));

    KeyStroke stoke = KeyStroke.getInstance(SWT.CONTROL, ' ');
    m_translationFolderField = new TextProposalField(group, model, stoke);
    m_translationFolderField.setLabelText("Translations Folder");
    m_translationFolderField.setLabelProvider(model);
    m_translationFolderField.addModifyListener(new ModifyListener() {
      @Override
      public void modifyText(ModifyEvent e) {
        m_desc.setTranslationFolder(m_translationFolderField.getText());
      }
    });
    NlsUi.decorate(m_translationFolderField, false);

    m_translationFileName = new TextField<String>(group, TextField.VALIDATE_ON_MODIFY);
    m_fieldValidator.addField(m_translationFileName);
    m_translationFileName.setLabelText("Translation File Prefix");
    m_translationFileName.setToolTipText("e.g. messages for messages[_language].properties");
    m_translationFileName.addInputChangedListener(new IInputChangedListener<String>() {
      @Override
      public void inputChanged(String input) {
        m_desc.setTranlationFileName(input);
      }
    });
    m_translationFileName.setInputValidator(new IInputValidator() {
      private String m_regexp = "\\b[A-Za-z][a-zA-Z0-9_]{0,200}\\b";

      @Override
      public IStatus isValid(String value) {
        if (value.matches(m_regexp)) {
          return Status.OK_STATUS;
        }
        return Status.CANCEL_STATUS;
      }
    });

    // layout
    group.setLayout(new GridLayout(1, true));
    attachGridData(m_translationFolderField);
    attachGridData(m_translationFileName);
    return group;
  }

  protected IFolder chooseTranslationFolder() {
    ResourceDialog dialog = new ResourceDialog(getShell(), "Choose Folder", m_desc.getPlugin());
    dialog.setInitialExpansion(new IResource[]{m_desc.getPlugin()});
    dialog.setInitialSelection(new IResource[]{m_desc.getPlugin()});
    dialog.addViewerFilter(new ViewerFilter() {
      @Override
      public Object[] filter(Viewer viewer, Object parent, Object[] elements) {
        List<Object> elList = new LinkedList<Object>();
        for (Object e : elements) {
          if (e instanceof IContainer) {
            if (parent instanceof IProject) {
              IJavaProject jp = JavaCore.create((IProject) parent);
              try {
                if (!((IContainer) e).getProjectRelativePath().lastSegment().equals(
                    jp.getOutputLocation().lastSegment())) {
                  elList.add(e);
                }
              }
              catch (JavaModelException e1) {
                NlsCore.logWarning(e1);
              }
            }
            else {
              elList.add(e);
            }
          }
        }
        return elList.toArray();
      }

      @Override
      public boolean select(Viewer viewer, Object parentElement, Object element) {
        return element instanceof IFolder;
      }
    });
    if (dialog.open() == Window.OK) {
      IResource selection = dialog.getFirstResult();
      if (selection instanceof IFolder) {
        return (IFolder) selection;
      }

    }
    return null;
  }

  @Override
  protected IPackageFragmentRoot chooseContainer() {
    IJavaElement initElement = getPackageFragmentRoot();
    Class<?>[] acceptedClasses = new Class[]{IPackageFragmentRoot.class, IJavaProject.class};
    TypedElementSelectionValidator validator = new TypedElementSelectionValidator(acceptedClasses, false) {
      @Override
      public boolean isSelectedValid(Object element) {
        try {
          if (element instanceof IJavaProject) {
            IJavaProject jproject = (IJavaProject) element;
            IPath path = jproject.getProject().getFullPath();
            return (jproject.findPackageFragmentRoot(path) != null);
          }
          else if (element instanceof IPackageFragmentRoot) {
            return (((IPackageFragmentRoot) element).getKind() == IPackageFragmentRoot.K_SOURCE);
          }
          return true;
        }
        catch (JavaModelException e) {
          JavaPlugin.log(e.getStatus()); // just log, no UI in validation
        }
        return false;
      }
    };

    acceptedClasses = new Class[]{IJavaModel.class, IPackageFragmentRoot.class, IJavaProject.class};
    ViewerFilter filter = new TypedViewerFilter(acceptedClasses) {
      @Override
      public boolean select(Viewer viewer, Object parent, Object element) {
        if (element instanceof IPackageFragmentRoot) {
          try {
            return (((IPackageFragmentRoot) element).getKind() == IPackageFragmentRoot.K_SOURCE);
          }
          catch (JavaModelException e) {
            JavaPlugin.log(e.getStatus()); // just log, no UI in validation
            return false;
          }
        }
        return super.select(viewer, parent, element);
      }
    };

    StandardJavaElementContentProvider provider = new StandardJavaElementContentProvider();
    ILabelProvider labelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
    ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), labelProvider, provider);
    dialog.setValidator(validator);
    dialog.setSorter(new JavaElementSorter());
    dialog.setTitle(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_title);
    dialog.setMessage(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_description);
    dialog.addFilter(filter);
    dialog.setInput(JavaCore.create(m_desc.getPlugin()));
    dialog.setInitialSelection(initElement);
    dialog.setHelpAvailable(false);

    if (dialog.open() == Window.OK) {
      Object element = dialog.getFirstResult();
      if (element instanceof IJavaProject) {
        IJavaProject jproject = (IJavaProject) element;
        return jproject.getPackageFragmentRoot(jproject.getProject());
      }
      else if (element instanceof IPackageFragmentRoot) {
        return (IPackageFragmentRoot) element;
      }
      return null;
    }
    return null;
  }

  @Override
  public Control getControl() {
    return m_rootPane;
  }

  @Override
  public void setVisible(boolean visible) {
    if (m_rootPane != null && !m_rootPane.isDisposed()) {
      m_rootPane.setVisible(visible);
    }
  }

  private void revalidate() {
    // enable disable
    m_fieldValidator.reset();

    if (m_desc.getSourceContainer() == null) {
      m_fieldValidator.setDisabled(m_package);
    }
    m_fieldValidator.apply();

    // messages
    setMessage(null);
    if (m_desc.getSourceContainer() == null) {
      setMessage("The source container must be specified.", WizardPage.WARNING);
      setPageComplete(false);
      return;
    }
    if (m_desc.getPackage() == null) {
      setMessage("The package must be specified.", WizardPage.WARNING);
      setPageComplete(false);
      return;
    }
    if (m_desc.getClassName() == null) {
      setMessage("The class name must be specified.", WizardPage.WARNING);
      setPageComplete(false);
      return;
    }
    if (m_desc.getTranslationFolder() == null) {
      setMessage("The translation folder must be specified.", WizardPage.WARNING);
      setPageComplete(false);
      return;
    }
    if (m_desc.getTranlationFileName() == null) {
      setMessage("The translation file name must be specified.", WizardPage.WARNING);
      setPageComplete(false);
      return;
    }
    setPageComplete(true);
  }

  private void attachGridData(Control c) {
    GridData data = new GridData();
    data.horizontalAlignment = SWT.FILL;
    data.grabExcessHorizontalSpace = true;
    c.setLayoutData(data);
  }

  protected void handlePropertyChanged(String name, Object oldValue, Object newValue) {
    if (name.equals(NewNlsFileOperationDesc.PROP_PLUGIN)) {
      m_containerFieldModifyListener.setPlugin((IProject) newValue);
      m_packageProposalModel.setProject((IProject) newValue);
    }
    if (name.equals(NewNlsFileOperationDesc.PROP_SRC_CONTAINER) && m_lock.acquire()) {
      try {
        IPath path = (IPath) newValue;
        if (path == null) {
          m_containerField.setText("");
          m_desc.setSourceContainer(null);
        }
        else {
          m_containerField.setText(path.lastSegment());
          m_desc.setSourceContainer(path);
        }
      }
      finally {
        m_lock.release();
      }
    }
    else if (name.equals(NewNlsFileOperationDesc.PROP_PACKAGE)) {
      // TODO uncomment
      // m_packageField.setInput((IPackageFragment) newValue);
    }
    revalidate();
  }

  private class P_DescPropertyChangedListener implements PropertyChangeListener {
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
      handlePropertyChanged(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
    }
  }

  private class P_RootContainerModifyListener implements ModifyListener {
    private HashMap<String, IClasspathEntry> m_map = new HashMap<String, IClasspathEntry>();

    private P_RootContainerModifyListener() {

    }

    public void setPlugin(IProject project) {
      if (project == null) {
        return;
      }
      m_map.clear();
      IJavaProject jp = JavaCore.create(project);
      try {
        for (IClasspathEntry entry : NlsJdtUtility.getSourceLocations(jp)) {
          m_map.put(entry.getPath().toPortableString(), entry);
        }
      }
      catch (JavaModelException e) {
        NlsCore.logWarning(e);
      }
    }

    @Override
    public void modifyText(ModifyEvent e) {
      if (m_lock.acquire()) {
        try {
          String input = m_containerField.getText();
          for (IClasspathEntry entry : m_map.values()) {
            if (entry.getPath().lastSegment().equals(input)) {
              m_desc.setSourceContainer(entry.getPath());
            }
            else {
              setMessage("invalid source container", WizardPage.WARNING);
            }
          }
        }
        finally {
          m_lock.release();
        }
      }
    }
  }
}
