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

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import org.eclipse.rap.rwt.lifecycle.WidgetUtil;
import org.eclipse.scout.commons.OptimisticLock;
import org.eclipse.scout.commons.RunnableWithData;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
import org.eclipse.scout.rt.client.ui.form.fields.groupbox.IGroupBox;
import org.eclipse.scout.rt.client.ui.form.fields.tabbox.ITabBox;
import org.eclipse.scout.rt.ui.rap.form.fields.RwtScoutFieldComposite;
import org.eclipse.scout.rt.ui.rap.util.RwtLayoutUtility;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

public class RwtScoutTabBox extends RwtScoutFieldComposite<ITabBox> implements IRwtScoutTabBox {
  private static final IScoutLogger LOG = ScoutLogManager.getLogger(RwtScoutTabBox.class);

  private HashMap<Composite, RwtScoutTabItem> m_tabs;
  private Listener m_uiTabFocusListener;
  private P_TabListener m_tabListener = new P_TabListener();
  private OptimisticLock m_selectedTabLock;
  private OptimisticLock m_rebuildItemsLock = new OptimisticLock();

  private Composite m_tabboxButtonbar;
  private StackLayout m_stackLayout;
  private Composite m_tabboxContainer;

  private RwtScoutTabItem m_focusedItem;

  public RwtScoutTabBox() {
    m_selectedTabLock = new OptimisticLock();
  }

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

    m_tabboxButtonbar = createTabboxButtonBar(container);
    m_tabboxContainer = getUiEnvironment().getFormToolkit().createComposite(container, SWT.NONE);

    //layout
    container.setLayout(RwtLayoutUtility.createGridLayoutNoSpacing(1, false));

    GridData tabboxButtonBarLayoutdata = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_END);
    m_tabboxButtonbar.setLayoutData(tabboxButtonBarLayoutdata);

    m_tabboxContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
    m_stackLayout = new StackLayout();
    m_tabboxContainer.setLayout(m_stackLayout);

    setUiLabel(null);
    setUiField(m_tabboxContainer);
    setUiContainer(container);
    // set up tabs
    for (IGroupBox box : getScoutObject().getGroupBoxes()) {
      box.addPropertyChangeListener(m_tabListener);
    }
    rebuildItems();
    if (m_uiTabFocusListener == null) {
      m_uiTabFocusListener = new P_RwtFocusListener();
    }
    m_tabboxContainer.addListener(SWT.FocusIn, m_uiTabFocusListener);
    m_tabboxContainer.addListener(SWT.FocusOut, m_uiTabFocusListener);
  }

  protected Composite createTabboxButtonBar(Composite parent) {
    Composite tabboxButtonBar = getUiEnvironment().getFormToolkit().createComposite(parent);
    tabboxButtonBar.setData(WidgetUtil.CUSTOM_VARIANT, VARIANT_TABBOX_CONTAINER);
    //layout
    RowLayout layout = new RowLayout(SWT.HORIZONTAL);
    layout.marginBottom = 0;
    layout.marginTop = 5;
    layout.marginLeft = 10;
    tabboxButtonBar.setLayout(layout);

    return tabboxButtonBar;
  }

  @Override
  protected void disposeImpl() {
    super.disposeImpl();
    if (m_tabboxButtonbar != null && !m_tabboxButtonbar.isDisposed()) {
      m_tabboxButtonbar.dispose();
      m_tabboxButtonbar = null;
    }
  }

  protected void rebuildItems() {
    try {
      m_rebuildItemsLock.acquire();
      getUiContainer().setRedraw(false);
      // remove old
      if (m_tabs != null) {
        for (RwtScoutTabItem item : m_tabs.values()) {
          item.dispose();
        }
      }
      m_tabs = new HashMap<Composite, RwtScoutTabItem>();
      LinkedList<RwtScoutTabItem> tabList = new LinkedList<RwtScoutTabItem>();
      for (IGroupBox box : getScoutObject().getGroupBoxes()) {
        if (box.isVisible()) {
          RwtScoutTabItem item = new RwtScoutTabItem(getScoutObject(), m_tabboxButtonbar, m_tabboxContainer, VARIANT_TABBOX_BUTTON, VARIANT_TABBOX_BUTTON_ACTIVE, VARIANT_TABBOX_BUTTON_MARKED, VARIANT_TABBOX_BUTTON_ACTIVE_MARKED);
          item.createUiField(getUiField(), box, getUiEnvironment());
          m_tabs.put(item.getTabItem(), item);
          tabList.add(item);
        }
      }

      // link the tab items together.
      if (tabList.size() > 0) {
        RwtScoutTabItem previousItem = null;
        for (RwtScoutTabItem curItem : tabList) {
          if (previousItem != null) {
            curItem.setPreviousTabItem(previousItem);
            previousItem.setNextTabItem(curItem);
          }
          previousItem = curItem;
        }

        /* the previous item of the first one is linked to the last one 
         * the next item of the last one is linked to the first one.
         */
        RwtScoutTabItem firstItem = tabList.getFirst();
        RwtScoutTabItem lastItem = tabList.getLast();
        firstItem.setPreviousTabItem(lastItem);
        lastItem.setNextTabItem(firstItem);
      }
      
      setSelectedTabFromScout();
    }
    finally {
      getUiContainer().setRedraw(true);
      m_rebuildItemsLock.release();
    }
  }

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

  @Override
  protected void attachScout() {
    super.attachScout();
    setSelectedTabFromScout();
  }

  @Override
  protected void detachScout() {
    for (IGroupBox b : getScoutObject().getGroupBoxes()) {
      b.removePropertyChangeListener(m_tabListener);
    }
    super.detachScout();
  }

  @Override
  protected void setEnabledFromScout(boolean b) {
    // void here
  }

  /**
   * scout settings
   */
  protected void setSelectedTabFromScout() {
    try {
      m_selectedTabLock.acquire();
      //
      IGroupBox selectedTab = getScoutObject().getSelectedTab();
      Composite foundItem = null;
      for (Map.Entry<Composite, RwtScoutTabItem> e : m_tabs.entrySet()) {
        IGroupBox test = e.getValue().getScoutObject();
        if (test == selectedTab) {
          foundItem = e.getKey();
          break;
        }
      }
      if (foundItem != null) {
        m_stackLayout.topControl = foundItem;
        m_tabboxContainer.layout();

        m_focusedItem = m_tabs.get(foundItem);
        m_focusedItem.setUiFocus();
        m_tabboxButtonbar.layout();
      }
    }
    finally {
      m_selectedTabLock.release();
    }
  }

  /**
   * scout property observer
   */
  @Override
  protected void handleScoutPropertyChange(String name, Object newValue) {
    super.handleScoutPropertyChange(name, newValue);
    if (name.equals(ITabBox.PROP_SELECTED_TAB)) {
      setSelectedTabFromScout();
    }
  }

  private class P_RwtFocusListener implements Listener {
    private static final long serialVersionUID = 1L;

    @Override
    public void handleEvent(Event event) {
      RwtScoutTabItem item = m_tabs.get(m_stackLayout.topControl);
      switch (event.type) {
        case SWT.FocusOut:
          if (m_focusedItem != null) {
            m_focusedItem = null;
          }
          break;
        case SWT.FocusIn:
          if (item.setUiFocus()) {
            m_focusedItem = item;
          }
          break;
        default:
          break;
      }
    }
  }

  private class P_TabListener implements PropertyChangeListener {
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
      if (evt.getPropertyName().equals(IGroupBox.PROP_VISIBLE)) {
        try {
          if (m_rebuildItemsLock.acquire()) {
            RunnableWithData t = new RunnableWithData() {
              @Override
              public void run() {
                rebuildItems();
              }
            };
            getUiEnvironment().invokeUiLater(t);
          }
        }
        finally {
          m_rebuildItemsLock.release();
        }
      }
    }
  }
}
