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

import java.io.File;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.supplemental.fileupload.DiskFileUploadReceiver;
import org.eclipse.rap.rwt.supplemental.fileupload.FileUploadEvent;
import org.eclipse.rap.rwt.supplemental.fileupload.FileUploadHandler;
import org.eclipse.rap.rwt.supplemental.fileupload.FileUploadListener;
import org.eclipse.rap.rwt.supplemental.fileupload.FileUploadReceiver;
import org.eclipse.scout.commons.CompareUtility;
import org.eclipse.scout.commons.StringUtility;
import org.eclipse.scout.commons.exception.IProcessingStatus;
import org.eclipse.scout.commons.exception.ProcessingStatus;
import org.eclipse.scout.commons.holders.Holder;
import org.eclipse.scout.commons.job.JobEx;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
import org.eclipse.scout.rt.client.ui.form.fields.IFormField;
import org.eclipse.scout.rt.client.ui.form.fields.ScoutFieldStatus;
import org.eclipse.scout.rt.client.ui.form.fields.filechooserfield.IFileChooserField;
import org.eclipse.scout.rt.ui.rap.LogicalGridLayout;
import org.eclipse.scout.rt.ui.rap.RwtMenuUtility;
import org.eclipse.scout.rt.ui.rap.ext.IDropDownFileUploadForPatch;
import org.eclipse.scout.rt.ui.rap.ext.MenuAdapterEx;
import org.eclipse.scout.rt.ui.rap.ext.StatusLabelEx;
import org.eclipse.scout.rt.ui.rap.ext.StyledTextEx;
import org.eclipse.scout.rt.ui.rap.ext.custom.StyledText;
import org.eclipse.scout.rt.ui.rap.form.fields.LogicalGridDataBuilder;
import org.eclipse.scout.rt.ui.rap.form.fields.RwtScoutValueFieldComposite;
import org.eclipse.scout.rt.ui.rap.internal.TextFieldEditableSupport;
import org.eclipse.scout.rt.ui.rap.keystroke.IRwtKeyStroke;
import org.eclipse.scout.rt.ui.rap.keystroke.RwtKeyStroke;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ProgressBar;

public class RwtScoutFileUploadField extends RwtScoutValueFieldComposite<IFileChooserField> implements IRwtScoutFileUploadField {
  private static final IScoutLogger LOG = ScoutLogManager.getLogger(RwtScoutFileUploadField.class);

  private Composite m_fileContainer;
  private IDropDownFileUploadForPatch m_browseButton;
  private ProgressBar m_progressBar;
  private Menu m_contextMenu;
  private TextFieldEditableSupport m_editableSupport;

  private FileUploadHandler m_handler;
  private FileUploadListener m_uploadListener;
  private File m_uploadedFile = null;

  private String m_originalVariant = "";

  public RwtScoutFileUploadField() {
    initializeFileUpload();
  }

  @Override
  protected void initializeUi(Composite parent) {
    super.initializeUi(parent);
    Composite container = getUiEnvironment().getFormToolkit().createComposite(parent);
    StatusLabelEx label = getUiEnvironment().getFormToolkit().createStatusLabel(container, getScoutObject());

    m_fileContainer = getUiEnvironment().getFormToolkit().createComposite(container, SWT.BORDER);
    m_fileContainer.setData(RWT.CUSTOM_VARIANT, VARIANT_FILECHOOSER);

    StyledText textField = new StyledTextEx(m_fileContainer, SWT.SINGLE | getUiEnvironment().getFormToolkit().getOrientation()) {
      private static final long serialVersionUID = 1L;

      @Override
      public void setBackground(Color color) {
        if (getUiProgressBar() != null && !getUiProgressBar().isDisposed()) {
          getUiProgressBar().setBackground(color);
        }
        if (getUiBrowseButton() != null && !getUiBrowseButton().isDisposed()) {
          getUiBrowseButton().setBackground(color);
        }
      }
    };
    getUiEnvironment().getFormToolkit().adapt(textField, false, false);
    // correction to look like a normal text
    textField.setData(RWT.CUSTOM_VARIANT, VARIANT_FILECHOOSER);
    //textfield must be disabled. We can't upload the file from it for now.
    textField.setEnabled(false);

    setUiContainer(container);
    setUiLabel(label);
    setUiField(textField);

    createProgressBar();
    createBrowseButton();

    // prevent the button from grabbing focus
    m_fileContainer.setTabList(new Control[]{textField});

    // context menu
    m_contextMenu = new Menu(getUiBrowseButton().getShell(), SWT.POP_UP);
    m_contextMenu.addMenuListener(new P_ContextMenuListener());
    getUiBrowseButton().setMenu(m_contextMenu);

    // layout
    container.setLayout(new LogicalGridLayout(1, 0));

    m_fileContainer.setLayoutData(LogicalGridDataBuilder.createField(((IFormField) getScoutObject()).getGridData()));
    m_fileContainer.setLayout(new FormLayout());

    final FormData textLayoutData = new FormData(SWT.DEFAULT, SWT.DEFAULT);
    textLayoutData.right = new FormAttachment(100, -20);
    textLayoutData.left = new FormAttachment(0, 0);
    textLayoutData.bottom = new FormAttachment(textField, -1, SWT.BOTTOM);
    textField.setLayoutData(textLayoutData);
  }

  private void createBrowseButton() {
    m_browseButton = getUiEnvironment().getFormToolkit().createDropDownFileUpload(m_fileContainer, SWT.DROP_DOWN);
    m_browseButton.setData(RWT.CUSTOM_VARIANT, VARIANT_FILECHOOSER);
    // to ensure the text is validated on a context menu call this mouse
    // listener is used.
    m_browseButton.addMouseListener(new MouseAdapter() {
      private static final long serialVersionUID = 1L;

      @Override
      public void mouseDown(MouseEvent e) {
        handleUiInputVerifier(true);
      }
    });
    m_browseButton.addFocusListener(new FocusAdapter() {
      private static final long serialVersionUID = 1L;

      @Override
      public void focusGained(FocusEvent e) {
        getUiField().setFocus();
      }
    });
    setBackgroundFromScout(getScoutObject().getBackgroundColor());

    getUiBrowseButton().addSelectionListener(new SelectionAdapter() {
      private static final long serialVersionUID = 1L;

      @Override
      public void widgetSelected(SelectionEvent event) {
        String filename = getUiBrowseButton().getFileName();
        if (filename == null) {
          return;
        }

        getUiField().setText(filename);
        handleUpload();
      }
    });

    final FormData buttonLayoutData = new FormData(SWT.DEFAULT, SWT.DEFAULT);
    buttonLayoutData.left = new FormAttachment(getUiField(), 0, SWT.RIGHT);
    buttonLayoutData.bottom = new FormAttachment((Control) getUiBrowseButton(), 0, SWT.BOTTOM);
    buttonLayoutData.height = 20;
    buttonLayoutData.width = 20;
    getUiBrowseButton().setLayoutData(buttonLayoutData);

    setEnabledFromScout(getScoutObject().isEnabled());
    m_fileContainer.layout();
  }

  private void createProgressBar() {
    m_progressBar = new ProgressBar(m_fileContainer, SWT.HORIZONTAL | SWT.SMOOTH | getUiEnvironment().getFormToolkit().getOrientation());
    getUiEnvironment().getFormToolkit().adapt(m_progressBar, true, true);
    setBackgroundFromScout(getScoutObject().getBackgroundColor());

    final FormData progressLayoutData = new FormData(SWT.DEFAULT, SWT.DEFAULT);
    progressLayoutData.right = new FormAttachment(100, -20);
    progressLayoutData.left = new FormAttachment(0, 0);
    progressLayoutData.top = new FormAttachment(2, 0);
    progressLayoutData.bottom = new FormAttachment(m_progressBar, 4, SWT.BOTTOM);
    m_progressBar.setLayoutData(progressLayoutData);

    m_fileContainer.layout();
  }

  @Override
  public void disposeImpl() {
    if (m_uploadListener != null) {
      m_handler.removeUploadListener(m_uploadListener);
      m_uploadListener = null;
    }
    if (m_handler != null) {
      m_handler.dispose();
      m_handler = null;
    }
    if (m_browseButton != null) {
      m_browseButton.dispose();
      m_browseButton = null;
    }
  }

  private void initializeFileUpload() {
    FileUploadReceiver receiver = new DiskFileUploadReceiver();
    m_handler = new FileUploadHandler(receiver);
  }

  @Override
  public IDropDownFileUploadForPatch getUiBrowseButton() {
    return m_browseButton;
  }

  @Override
  public ProgressBar getUiProgressBar() {
    return m_progressBar;
  }

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

  @Override
  protected IRwtKeyStroke[] getUiKeyStrokes() {
    return new IRwtKeyStroke[]{
        new RwtKeyStroke(SWT.ESC) {
          @Override
          public void handleUiAction(Event e) {
            if (cancelUpload()) {
              e.doit = false;
            }
          }
        },
        new RwtKeyStroke(SWT.CR) {
          @Override
          public void handleUiAction(Event e) {
            handleUiInputVerifier(e.doit);
          }
        }};
  }

  /*
   * scout properties
   */
  @Override
  protected void attachScout() {
    super.attachScout();
    setFileIconIdFromScout(getScoutObject().getFileIconId());
    getUiBrowseButton().setDropdownEnabled(getScoutObject().hasMenus());
    if (getScoutObject().isFolderMode()) {
      String msg = "IFileChooserField.isFolderMode() == true is not possible in RAP";
      LOG.error(msg);
      getUiLabel().setStatus(new ProcessingStatus(msg, IProcessingStatus.ERROR));
    }
  }

  @Override
  protected void setDisplayTextFromScout(String s) {
    if (s == null) {
      s = "";
    }
    getUiField().setText(s);
    super.handleUiFocusGained();
    getUiField().setCaretOffset(0);
  }

  @Override
  protected void setEnabledFromScout(boolean b) {
    super.setEnabledFromScout(b);
    getUiBrowseButton().setButtonEnabled(b);
    //textfield must be disabled. We can't upload the file from it for now.
    getUiField().setEnabled(false);

    if (!StringUtility.hasText(m_originalVariant)) {
      m_originalVariant = (String) m_fileContainer.getData(RWT.CUSTOM_VARIANT);
    }
    String customVariant = b ? m_originalVariant : m_originalVariant + VARIANT_DISABLED_SUFFIX;
    m_fileContainer.setData(RWT.CUSTOM_VARIANT, customVariant);
  }

  @Override
  protected void setFieldEnabled(Control field, boolean enabled) {
    if (m_editableSupport == null) {
      m_editableSupport = new TextFieldEditableSupport(getUiField());
    }
    m_editableSupport.setEditable(enabled);
  }

  protected void setFileIconIdFromScout(String s) {
    m_originalVariant = s;
    m_fileContainer.setData(RWT.CUSTOM_VARIANT, s);
    getUiField().setData(RWT.CUSTOM_VARIANT, s);
    getUiBrowseButton().setData(RWT.CUSTOM_VARIANT, s);
  }

  @Override
  protected void handleUiInputVerifier(boolean doit) {
    if (!doit) {
      return;
    }
    if (m_uploadedFile == null) {
      return;
    }
    // only handle if text has changed
    if (CompareUtility.equals(m_uploadedFile, getScoutObject().getDisplayText()) && getScoutObject().getErrorStatus() == null) {
      return;
    }
    final Holder<Boolean> result = new Holder<Boolean>(Boolean.class, false);
    // notify Scout
    Runnable t = new Runnable() {
      @Override
      public void run() {
        boolean b = getScoutObject().getUIFacade().setTextFromUI(m_uploadedFile.getAbsolutePath());
        result.setValue(b);
      }
    };
    JobEx job = getUiEnvironment().invokeScoutLater(t, 0);
    try {
      job.join(2345);
    }
    catch (InterruptedException e) {
      //nop
    }
    getUiEnvironment().dispatchImmediateUiJobs();
    // end notify
    return;
  }

  @Override
  protected void handleUiFocusGained() {
    super.handleUiFocusGained();
    getUiField().setSelection(0, getUiField().getText().length());
  }

  @Override
  protected void handleUiFocusLost() {
    getUiField().setSelection(0, 0);
  }

  private void handleUpload() {
    m_uploadedFile = null;
    String url = m_handler.getUploadUrl();
    if (m_uploadListener == null) {
      m_uploadListener = new P_FileUploadListener();
    }
    m_handler.addUploadListener(m_uploadListener);
    getUiBrowseButton().submit(url);
  }

  private boolean cancelUpload() {
    if (m_uploadedFile != null) {
      return false;
    }
    if (m_uploadListener != null) {
      m_handler.removeUploadListener(m_uploadListener);
      m_uploadListener = null;
    }
    m_handler.dispose();
    getUiBrowseButton().dispose();
    getUiProgressBar().dispose();
    getUiField().setText("");

    initializeFileUpload();

    createProgressBar();
    createBrowseButton();
    return true;
  }

  @Override
  protected void handleScoutPropertyChange(String name, Object newValue) {
    super.handleScoutPropertyChange(name, newValue);
    if (name.equals(IFileChooserField.PROP_FILE_ICON_ID)) {
      setFileIconIdFromScout((String) newValue);
    }
  }

  private class P_ContextMenuListener extends MenuAdapterEx {

    private static final long serialVersionUID = 1L;

    public P_ContextMenuListener() {
      super((Control) RwtScoutFileUploadField.this.getUiBrowseButton(), RwtScoutFileUploadField.this.getUiBrowseButton().getParent());
    }

    @Override
    public void menuShown(MenuEvent e) {
      super.menuShown(e);
      /*
       * Since the FileUpload widget does fire a MouseEvent when it is clicked on, we do not know if the right mouse button has been clicked or not.
       * Therefore, a MenuDetect listener cannot be attached. The creation of the menu is done once after initialization.
       * While handling the menuShown, the menu (event source) might already contain contributed Scout menus from the previous right mouse click. To
       * avoid the menus being added several times, the menu items are removed first before the Scout menus are contributed.
       */
      Menu contextMenu = (Menu) e.getSource();
      cleanUpMenuItems(contextMenu);

      final AtomicReference<IMenu[]> scoutMenusRef = new AtomicReference<IMenu[]>();
      Runnable t = new Runnable() {
        @Override
        public void run() {
          IMenu[] scoutMenus = getScoutObject().getUIFacade().firePopupFromUI();
          scoutMenusRef.set(scoutMenus);
        }
      };
      JobEx job = RwtScoutFileUploadField.this.getUiEnvironment().invokeScoutLater(t, 1200);
      try {
        job.join(1200);
      }
      catch (InterruptedException ex) {
        //nop
      }
      // grab the actions out of the job, when the actions are providden within
      // the scheduled time the popup will be handled.
      if (scoutMenusRef.get() != null) {
        RwtMenuUtility.fillContextMenu(scoutMenusRef.get(), RwtScoutFileUploadField.this.getUiEnvironment(), contextMenu);
      }
    }

    protected void cleanUpMenuItems(Menu menu) {
      for (MenuItem menuItem : menu.getItems()) {
        disposeMenuItem(menuItem);
      }
    }

    protected void disposeMenuItem(MenuItem item) {
      Menu menu = item.getMenu();
      if (menu != null) {
        for (MenuItem childItem : menu.getItems()) {
          disposeMenuItem(childItem);
        }
        menu.dispose();
      }
      item.dispose();
    }
  } // end class P_ContextMenuListener

  private class P_FileUploadListener implements FileUploadListener {

    @Override
    public void uploadProgress(final FileUploadEvent uploadEvent) {
      getUiEnvironment().getDisplay().asyncExec(new Runnable() {
        @Override
        public void run() {
          double fraction = uploadEvent.getBytesRead() / (double) uploadEvent.getContentLength();
          int percent = (int) Math.floor(fraction * 100);
          if (getUiProgressBar() != null && !getUiProgressBar().isDisposed()) {
            getUiProgressBar().setSelection(percent);
            getUiProgressBar().setToolTipText("Upload progress: " + percent + "%");
          }
        }
      });
    }

    @Override
    public void uploadFinished(final FileUploadEvent uploadEvent) {
      DiskFileUploadReceiver receiver = (DiskFileUploadReceiver) m_handler.getReceiver();
      m_uploadedFile = receiver.getTargetFile();
      getUiEnvironment().getDisplay().asyncExec(new Runnable() {

        @Override
        public void run() {
          if (m_uploadedFile != null) {
            handleUiInputVerifier(true);
          }
        }
      });
      getUiEnvironment().getDisplay().asyncExec(new Runnable() {
        @Override
        public void run() {
          int percent = 0;
          if (getUiProgressBar() != null && !getUiProgressBar().isDisposed()) {
            getUiProgressBar().setSelection(percent);
            getUiProgressBar().setToolTipText("");
          }
          m_handler.removeUploadListener(m_uploadListener);
        }
      });
    }

    @Override
    public void uploadFailed(final FileUploadEvent uploadEvent) {
      getUiEnvironment().getDisplay().asyncExec(new Runnable() {
        @Override
        public void run() {
          if (getUiLabel() != null) {
            getUiLabel().setStatus(new ScoutFieldStatus(uploadEvent.getException().getMessage(), IStatus.ERROR));
          }
          m_handler.removeUploadListener(m_uploadListener);
        }
      });
    }
  }
}
