/*******************************************************************************
 * Copyright (c) 2011 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.rt.ui.rap.form;

import java.io.File;
import java.util.WeakHashMap;

import org.eclipse.rap.rwt.lifecycle.WidgetUtil;
import org.eclipse.scout.commons.beans.IPropertyObserver;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
import org.eclipse.scout.rt.client.ui.IEventHistory;
import org.eclipse.scout.rt.client.ui.form.FormEvent;
import org.eclipse.scout.rt.client.ui.form.FormListener;
import org.eclipse.scout.rt.client.ui.form.IForm;
import org.eclipse.scout.rt.client.ui.form.fields.IFormField;
import org.eclipse.scout.rt.client.ui.form.fields.smartfield.ISmartFieldProposalForm;
import org.eclipse.scout.rt.ui.rap.DefaultValidateRoot;
import org.eclipse.scout.rt.ui.rap.IValidateRoot;
import org.eclipse.scout.rt.ui.rap.LogicalGridLayout;
import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutComposite;
import org.eclipse.scout.rt.ui.rap.basic.RwtScoutComposite;
import org.eclipse.scout.rt.ui.rap.basic.WidgetPrinter;
import org.eclipse.scout.rt.ui.rap.form.fields.IRwtScoutFormField;
import org.eclipse.scout.rt.ui.rap.form.fields.RwtScoutFieldComposite;
import org.eclipse.scout.rt.ui.rap.form.fields.RwtScoutFormFieldGridData;
import org.eclipse.scout.rt.ui.rap.util.FocusUtility;
import org.eclipse.scout.rt.ui.rap.util.RwtUtility;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class RwtScoutForm extends RwtScoutComposite<IForm> implements IRwtScoutForm {
  private static final IScoutLogger LOG = ScoutLogManager.getLogger(RwtScoutForm.class);
  private static final String VARIANT_FORM = "form";

  private FormListener m_scoutFormListener;
  private WeakHashMap<FormEvent, Object> m_consumedScoutFormEvents = new WeakHashMap<FormEvent, Object>();

  @Override
  protected void initializeUi(Composite parent) {
    Composite container = getUiEnvironment().getFormToolkit().createComposite(parent);
    container.setData(WidgetUtil.CUSTOM_VARIANT, VARIANT_FORM);

    IRwtScoutFormField group = getUiEnvironment().createFormField(container, getScoutObject().getRootGroupBox());
    Composite field = group.getUiContainer();
    setUiContainer(container);
    setUiField(field);

    // use grid layout with decent min-width
    RwtScoutFormFieldGridData layoutData = new RwtScoutFormFieldGridData(getScoutObject().getRootGroupBox());
    getUiField().setLayoutData(layoutData);
    container.setLayout(new LogicalGridLayout(0, 0));
    container.setData(IValidateRoot.VALIDATE_ROOT_DATA, new DefaultValidateRoot(parent));
  }

  @Override
  protected void attachScout() {
    super.attachScout();
    if (getScoutObject() instanceof ISmartFieldProposalForm) {
      getUiContainer().setData(WidgetUtil.CUSTOM_VARIANT, RwtUtility.VARIANT_PROPOSAL_FORM);
    }
    if (m_scoutFormListener == null) {
      m_scoutFormListener = new P_ScoutFormListener();
      getScoutObject().addFormListener(m_scoutFormListener);
    }
    // process all pending events, except requestFocus
    IEventHistory<FormEvent> h = getScoutObject().getEventHistory();
    if (h != null) {
      for (FormEvent e : h.getRecentEvents()) {
        switch (e.getType()) {
          case FormEvent.TYPE_TO_BACK:
          case FormEvent.TYPE_TO_FRONT:
          case FormEvent.TYPE_PRINT: {
            handleScoutFormEventInUi(e);
            break;
          }
        }
      }
    }
    setInitialFocus();
  }

  @Override
  protected void detachScout() {
    super.detachScout();
    if (m_scoutFormListener != null) {
      getScoutObject().removeFormListener(m_scoutFormListener);
      m_scoutFormListener = null;
    }
  }

  @Override
  public Composite getUiFormPane() {
    return (Composite) getUiField();
  }

  @Override
  public Composite getUiField() {
    return (Composite) super.getUiField();
  }

  @Override
  public void setInitialFocus() {
    IFormField modelField = null;
    //check for request focus events in history
    IEventHistory<FormEvent> h = getScoutObject().getEventHistory();
    if (h != null) {
      for (FormEvent e : h.getRecentEvents()) {
        if (e.getType() == FormEvent.TYPE_REQUEST_FOCUS) {
          modelField = e.getFormField();
          break;
        }
      }
    }
    if (modelField == null) {
      setFocusOnFirstField();
    }
    else {
      handleRequestFocusFromScout(modelField, true);
    }
  }

  /**
   * Sets the focus into the first focusable control in the mainbox.
   * <p>
   * This should actually be done by rap itself, but the implementation seems not to be finished, see
   * Shell.traverseGroup
   */
  private void setFocusOnFirstField() {
    Control firstFocusableControl = FocusUtility.findFirstFocusableControl(getUiField());
    if (firstFocusableControl != null) {
      firstFocusableControl.setFocus();
    }
  }

  private Composite findUiContainer(IFormField modelField) {
    if (modelField == null) {
      return null;
    }
    for (Control comp : RwtUtility.findChildComponents(getUiContainer(), Control.class)) {
      IRwtScoutComposite<?> composite = RwtScoutFieldComposite.getCompositeOnWidget(comp);
      if (composite != null && composite.getScoutObject() == modelField) {
        return composite.getUiContainer();
      }
    }
    return null;
  }

  protected void handleScoutFormEventInUi(final FormEvent e) {
    if (m_consumedScoutFormEvents.containsKey(e)) {
      return;
    }
    m_consumedScoutFormEvents.put(e, Boolean.TRUE);
    //
    switch (e.getType()) {
      case FormEvent.TYPE_PRINT: {
        handlePrintFromScout(e);
        break;
      }
      case FormEvent.TYPE_TO_FRONT: {
        Shell sh = getUiFormPane().getShell();
        if (sh.isVisible()) {
          // TODO rap not supported in swt: sh.toFront()
        }
        break;
      }
      case FormEvent.TYPE_TO_BACK: {
        Shell sh = getUiFormPane().getShell();
        if (sh.isVisible()) {
          // TODO rap not supported in swt: sh.toBack()
        }
        break;
      }
      case FormEvent.TYPE_REQUEST_FOCUS: {
        handleRequestFocusFromScout(e.getFormField(), false);
        break;
      }
    }
  }

  protected void handlePrintFromScout(final FormEvent e) {
    WidgetPrinter wp = null;
    try {
      if (getUiFormPane() != null) {
        if (e.getFormField() != null) {
          for (Control c : RwtUtility.findChildComponents(getUiContainer(), Control.class)) {
            IPropertyObserver scoutModel = (IPropertyObserver) c.getData(IRwtScoutFormField.CLIENT_PROPERTY_SCOUT_OBJECT);
            if (scoutModel == e.getFormField()) {
              wp = new WidgetPrinter(c);
              break;
            }
          }
        }
        if (wp == null) {
          wp = new WidgetPrinter(getUiFormPane().getShell());
        }
      }
      if (wp != null) {
        try {
          wp.print(e.getPrintDevice(), e.getPrintParameters());
        }
        catch (Throwable ex) {
          LOG.error(null, ex);
        }
      }
    }
    finally {
      File outputFile = null;
      if (wp != null) {
        outputFile = wp.getOutputFile();
      }
      final File outputFileFinal = outputFile;
      Runnable r = new Runnable() {
        @Override
        public void run() {
          getScoutObject().getUIFacade().fireFormPrintedFromUI(outputFileFinal);
        }
      };
      getUiEnvironment().invokeScoutLater(r, 0);
    }
  }

  protected void handleRequestFocusFromScout(IFormField modelField, boolean force) {
    if (modelField == null) {
      return;
    }
    Composite comp = findUiContainer(modelField);
    Control control = FocusUtility.findFirstFocusableControl(comp);
    if (control != null) {
      if (force) {
        control.forceFocus();
      }
      else {
        control.setFocus();
      }
    }
  }

  private class P_ScoutFormListener implements FormListener {
    @Override
    public void formChanged(final FormEvent e) {
      Display display = getUiEnvironment().getDisplay();
      if (display == null) {
        return;
      }
      switch (e.getType()) {
        case FormEvent.TYPE_STRUCTURE_CHANGED: {
          break;
        }
        case FormEvent.TYPE_PRINT:
        case FormEvent.TYPE_TO_FRONT:
        case FormEvent.TYPE_TO_BACK:
        case FormEvent.TYPE_REQUEST_FOCUS: {
          Runnable t = new Runnable() {
            @Override
            public void run() {
              if (getUiFormPane() != null && !getUiFormPane().isDisposed()) {
                handleScoutFormEventInUi(e);
              }
            }
          };
          getUiEnvironment().invokeUiLater(t);
          break;
        }
      }
    }
  }// end private class
}
