/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.uiDesigner.radComponents;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.uiDesigner.*;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.designSurface.*;
import com.intellij.uiDesigner.lw.*;
import com.intellij.uiDesigner.palette.ComponentItem;
import com.intellij.uiDesigner.palette.Palette;
import com.intellij.uiDesigner.propertyInspector.*;
import com.intellij.uiDesigner.propertyInspector.editors.IconEditor;
import com.intellij.uiDesigner.propertyInspector.editors.string.StringEditor;
import com.intellij.uiDesigner.propertyInspector.properties.AbstractBooleanProperty;
import com.intellij.uiDesigner.propertyInspector.properties.IntroIconProperty;
import com.intellij.uiDesigner.propertyInspector.renderers.IconRenderer;
import com.intellij.uiDesigner.propertyInspector.renderers.LabelPropertyRenderer;
import com.intellij.uiDesigner.propertyInspector.renderers.StringRenderer;
import com.intellij.uiDesigner.snapShooter.SnapshotContext;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.plaf.TabbedPaneUI;
import java.awt.*;
import java.awt.event.MouseEvent;

/**
 * @author Anton Katilin
 * @author Vladimir Kondratyev
 * @author yole
 */
public final class RadTabbedPane extends RadContainer implements ITabbedPane {

  public static class Factory extends RadComponentFactory {
    public RadComponent newInstance(ModuleProvider module, Class aClass, String id) {
      return new RadTabbedPane(module, aClass, id);
    }

    public RadComponent newInstance(final Class componentClass, final String id, final Palette palette) {
      return new RadTabbedPane(componentClass, id, palette);
    }
  }

  private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.radComponents.RadTabbedPane");
  /**
   * value: HashMap<String, LwTabbedPane.Constraints>
   */
  @NonNls
  private static final String CLIENT_PROP_ID_2_CONSTRAINTS = "index2descriptor";

  private int mySelectedIndex = -1;
  private IntrospectedProperty mySelectedIndexProperty = null;

  public RadTabbedPane(final ModuleProvider module, Class componentClass, final String id){
    super(module, componentClass, id);
  }

  public RadTabbedPane(Class componentClass, @NotNull final String id, final Palette palette) {
    super(componentClass, id, palette);
  }

  @Override protected RadLayoutManager createInitialLayoutManager() {
    return new RadTabbedPaneLayoutManager();
  }

  @Override public RadComponent getComponentToDrag(final Point pnt) {
    final int i = getTabbedPane().getUI().tabForCoordinate(getTabbedPane(), pnt.x, pnt.y);
    if (i >= 0) {
      RadComponent c = getRadComponent(i);
      if (c != null) {
        return c;
      }
    }
    return this;
  }

  private RadComponent getRadComponent(final int i) {
    RadComponent c = null;
    final Component component = getTabbedPane().getComponentAt(i);
    if (component instanceof JComponent) {
      JComponent jc = (JComponent) component;
      c = (RadComponent) jc.getClientProperty(RadComponent.CLIENT_PROP_RAD_COMPONENT);
    }
    return c;
  }

  @Override public void init(final GuiEditor editor, @NotNull final ComponentItem item) {
    super.init(editor, item);
    // add one tab by default
    addComponent(InsertComponentProcessor.createPanelComponent(editor));
  }

  @NotNull
  private JTabbedPane getTabbedPane(){
    return (JTabbedPane)getDelegee();
  }

  private String calcTabName(final StringDescriptor titleDescriptor) {
    if (titleDescriptor == null) {
      return UIDesignerBundle.message("tab.untitled");
    }
    return getDescriptorText(titleDescriptor);
  }

  @Nullable
  private String getDescriptorText(@Nullable final StringDescriptor titleDescriptor) {
    if (titleDescriptor == null) return null;
    final String value = titleDescriptor.getValue();
    if (value == null) { // from res bundle
      final String resolvedValue = StringDescriptorManager.getInstance(getModule()).resolve(this, titleDescriptor);
      titleDescriptor.setResolvedValue(resolvedValue);
      return resolvedValue;
    }
    return value;
  }

  /**
   * @return inplace property for editing of the title of the clicked tab
   */
  public Property getInplaceProperty(final int x, final int y) {
    final JTabbedPane tabbedPane = getTabbedPane();
    final TabbedPaneUI ui = tabbedPane.getUI();
    LOG.assertTrue(ui != null);
    final int index = ui.tabForCoordinate(tabbedPane, x, y);
    return index != -1 ? new MyTitleProperty(null, index) : null;
  }

  @Override @Nullable
  public Property getDefaultInplaceProperty() {
    final int index = getTabbedPane().getSelectedIndex();
    if (index >= 0) {
      return new MyTitleProperty(null, index);
    }
    return null;
  }

  public Rectangle getInplaceEditorBounds(final Property property, final int x, final int y) {
    final JTabbedPane tabbedPane = getTabbedPane();
    final TabbedPaneUI ui = tabbedPane.getUI();
    LOG.assertTrue(ui != null);
    final int index = ui.tabForCoordinate(tabbedPane, x, y);
    LOG.assertTrue(index != -1);
    return ui.getTabBounds(tabbedPane, index);
  }

  @Override @Nullable
  public Rectangle getDefaultInplaceEditorBounds() {
    final JTabbedPane tabbedPane = getTabbedPane();
    final int index = tabbedPane.getSelectedIndex();
    if (index >= 0) {
      return tabbedPane.getUI().getTabBounds(tabbedPane, index);
    }
    return null;
  }

  @Nullable
  public StringDescriptor getChildTitle(RadComponent component) {
    final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(this);
    final LwTabbedPane.Constraints constraints = id2Constraints.get(component.getId());
    return constraints == null ? null : constraints.myTitle;
  }

  public void setTabProperty(RadComponent component, final String propName, StringDescriptor title) throws Exception {
    final JComponent delegee = component.getDelegee();
    final JTabbedPane tabbedPane = getTabbedPane();
    int index = tabbedPane.indexOfComponent(delegee);
    if (index >= 0) {
      if (propName.equals(ITabbedPane.TAB_TITLE_PROPERTY)) {
        new MyTitleProperty(null, index).setValue(component, title);
      }
      else if (propName.equals(ITabbedPane.TAB_TOOLTIP_PROPERTY)) {
        new MyToolTipProperty(null, index).setValue(component, title);
      }
      else {
        throw new IllegalArgumentException("Invalid property name " + propName);
      }
    }
  }

  /**
   * This allows user to select and scroll tabs via the mouse
   */
  public void processMouseEvent(final MouseEvent event){
    event.getComponent().dispatchEvent(event);
  }

  public void write(final XmlWriter writer) {
    writer.startElement(UIFormXmlConstants.ELEMENT_TABBEDPANE);
    try{
      writeId(writer);
      writeClassIfDifferent(writer, JTabbedPane.class.getName());
      writeBinding(writer);

      // Constraints and properties
      writeConstraints(writer);
      writeProperties(writer);

      writeBorder(writer);
      writeChildren(writer);
    }finally{
      writer.endElement();
    }
  }

  @NotNull
  private static HashMap<String, LwTabbedPane.Constraints> getId2Constraints(final RadComponent component){
    //noinspection unchecked
    HashMap<String, LwTabbedPane.Constraints> id2Constraints = (HashMap<String, LwTabbedPane.Constraints>)component.getClientProperty(CLIENT_PROP_ID_2_CONSTRAINTS);
    if(id2Constraints == null){
      id2Constraints = new HashMap<String,LwTabbedPane.Constraints>();
      component.putClientProperty(CLIENT_PROP_ID_2_CONSTRAINTS, id2Constraints);
    }
    return id2Constraints;
  }

  @Nullable
  public RadComponent getSelectedTab() {
    int index = getTabbedPane().getSelectedIndex();
    return index < 0 ? null : getComponent(index);
  }

  public void selectTab(final RadComponent component) {
    final JTabbedPane tabbedPane = getTabbedPane();
    int index = tabbedPane.indexOfComponent(component.getDelegee());
    if (index >= 0) {
      tabbedPane.setSelectedIndex(index);
    }
  }

  public StringDescriptor getTabProperty(IComponent component, final String propName) {
    final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(this);
    final LwTabbedPane.Constraints constraints = id2Constraints.get(component.getId());
    return constraints == null ? null : constraints.getProperty(propName);
  }

  public boolean refreshChildTitle(final RadComponent radComponent) {
    StringDescriptor childTitle = getChildTitle(radComponent);
    if (childTitle == null) return false;
    String oldTitle = childTitle.getResolvedValue();
    childTitle.setResolvedValue(null);
    try {
      setTabProperty(radComponent, ITabbedPane.TAB_TITLE_PROPERTY, childTitle);
    }
    catch (Exception e) {
      LOG.error(e);
    }
    return !Comparing.equal(oldTitle, childTitle.getResolvedValue());
  }

  @Override public void loadLwProperty(final LwComponent lwComponent, final LwIntrospectedProperty lwProperty, final IntrospectedProperty property) {
    if (lwProperty.getName().equals(SwingProperties.SELECTED_INDEX)) {
      mySelectedIndexProperty = property;
      mySelectedIndex = ((Integer)lwProperty.getPropertyValue(lwComponent)).intValue();
    }
    else {
      super.loadLwProperty(lwComponent, lwProperty, property);
    }
  }

  @Override public void doneLoadingFromLw() {
    if (mySelectedIndex >= 0) {
      getTabbedPane().setSelectedIndex(mySelectedIndex);
      markPropertyAsModified(mySelectedIndexProperty);
    }
  }

  @Override
  protected void importSnapshotComponent(final SnapshotContext context, final JComponent component) {
    JTabbedPane tabbedPane = (JTabbedPane) component;
    for(int i=0; i<tabbedPane.getTabCount(); i++) {
      String title = tabbedPane.getTitleAt(i);
      Component child = tabbedPane.getComponentAt(i);
      if (child instanceof JComponent) {
        RadComponent childComponent = createSnapshotComponent(context, (JComponent) child);
        if (childComponent != null) {
          childComponent.setCustomLayoutConstraints(new LwTabbedPane.Constraints(StringDescriptor.create(title)));
          addComponent(childComponent);
        }
      }
    }
  }

  @NotNull
  private LwTabbedPane.Constraints getConstraintsForComponent(final RadComponent tabComponent) {
    final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(this);
    LwTabbedPane.Constraints constraints = id2Constraints.get(tabComponent.getId());
    if (constraints == null) {
      int index = indexOfComponent(tabComponent);
      constraints = new LwTabbedPane.Constraints(StringDescriptor.create(getTabbedPane().getTitleAt(index)));
      id2Constraints.put(tabComponent.getId(), constraints);
    }
    return constraints;
  }

  private final class MyTabGroupProperty extends ReadOnlyProperty {
    private final int myIndex;
    private final LabelPropertyRenderer myRenderer = new LabelPropertyRenderer("");

    public MyTabGroupProperty(final int index) {
      super(null, "Tab");
      myIndex = index;
    }

    @NotNull
    public PropertyRenderer getRenderer() {
      return myRenderer;
    }


    @NotNull @Override
    public Property[] getChildren(final RadComponent component) {
      return new Property[] {
        new MyTitleProperty(this, myIndex),
        new MyToolTipProperty(this, myIndex),
        new MyIconProperty(this, myIndex, false),
        new MyIconProperty(this, myIndex, true),
        new MyEnabledProperty(this, myIndex)
      };
    }
  }

  private class MyTitleProperty extends Property<RadComponent, StringDescriptor> {
    protected final int myIndex;
    private final StringEditor myEditor = new StringEditor(getProject());
    private final StringRenderer myRenderer = new StringRenderer();

    public MyTitleProperty(final Property parent, final int index) {
      super(parent, TAB_TITLE_PROPERTY);
      myIndex = index;
    }

    protected MyTitleProperty(final Property parent, @NonNls final String name, final int index) {
      super(parent, name);
      myIndex = index;
    }

    public StringDescriptor getValue(final RadComponent component) {
      final RadComponent tabComponent = getRadComponent(myIndex);
      // 1. resource bundle
      final LwTabbedPane.Constraints constraints = getId2Constraints(RadTabbedPane.this).get(tabComponent.getId());
      final StringDescriptor descriptor = constraints == null ? null : getValueFromConstraints(constraints);
      if(descriptor != null){
        return descriptor;
      }

      // 2. plain value
      return StringDescriptor.create(getValueFromTabbedPane());
    }

    protected void setValueImpl(final RadComponent component, StringDescriptor value) throws Exception {
      final RadComponent tabComponent = getRadComponent(myIndex);
      // 1. Put value into map
      if (value == null) value = StringDescriptor.create("");
      LwTabbedPane.Constraints constraints = getConstraintsForComponent(tabComponent);
      putValueToConstraints(value, constraints);

      // 2. Apply real string value to JComponent peer
      final String text = StringDescriptorManager.getInstance(getModule()).resolve(RadTabbedPane.this, value);
      if (value.getValue() == null) {
        value.setResolvedValue(text);
      }
      putValueToTabbedPane(text);
    }

    protected String getValueFromTabbedPane() {
      return getTabbedPane().getTitleAt(myIndex);
    }

    protected StringDescriptor getValueFromConstraints(final LwTabbedPane.Constraints constraints) {
      return constraints.myTitle;
    }

    protected void putValueToTabbedPane(final String text) {
      getTabbedPane().setTitleAt(myIndex, text);
    }

    protected void putValueToConstraints(final StringDescriptor value, final LwTabbedPane.Constraints constraints) {
      constraints.myTitle = value;
    }

    @NotNull
    public PropertyRenderer<StringDescriptor> getRenderer() {
      return myRenderer;
    }

    public PropertyEditor<StringDescriptor> getEditor() {
      return myEditor;
    }

    @Override public boolean isModified(final RadComponent component) {
      return !getTabbedPane().getTitleAt(myIndex).equals(UIDesignerBundle.message("tab.untitled"));
    }

    @Override public void resetValue(final RadComponent component) throws Exception {
      setValue(component, StringDescriptor.create(UIDesignerBundle.message("tab.untitled")));
    }
  }

  private class MyToolTipProperty extends MyTitleProperty {
    protected MyToolTipProperty(final Property parent, final int index) {
      super(parent, TAB_TOOLTIP_PROPERTY, index);
    }

    @Override protected String getValueFromTabbedPane() {
      return getTabbedPane().getToolTipTextAt(myIndex);
    }

    @Override protected StringDescriptor getValueFromConstraints(final LwTabbedPane.Constraints constraints) {
      return constraints.myToolTip;
    }

    @Override protected void putValueToTabbedPane(final String text) {
      getTabbedPane().setToolTipTextAt(myIndex, text);
    }

    @Override protected void putValueToConstraints(final StringDescriptor value, final LwTabbedPane.Constraints constraints) {
      constraints.myToolTip = value;
    }

    @Override public boolean isModified(final RadComponent component) {
      String toolTipText = getTabbedPane().getToolTipTextAt(myIndex);
      return !StringUtil.isEmpty(toolTipText);
    }

    @Override public void resetValue(final RadComponent component) throws Exception {
      setValue(component, StringDescriptor.create(""));
    }
  }

  private class MyIconProperty extends Property<RadComponent, IconDescriptor> {
    private final int myIndex;
    private final boolean myDisabledIcon;
    private final IconRenderer myRenderer = new IconRenderer();
    private final IconEditor myEditor = new IconEditor();

    public MyIconProperty(final Property parent, final int index, final boolean disabledIcon) {
      super(parent, disabledIcon ? "Tab Disabled Icon" : "Tab Icon");
      myIndex = index;
      myDisabledIcon = disabledIcon;
    }

    public IconDescriptor getValue(final RadComponent component) {
      LwTabbedPane.Constraints constraints = getConstraintsForComponent(component);
      return myDisabledIcon ? constraints.myDisabledIcon : constraints.myIcon;
    }

    protected void setValueImpl(final RadComponent component, final IconDescriptor value) throws Exception {
      Icon icon = (value != null) ? value.getIcon() : null;
      LwTabbedPane.Constraints constraints = getConstraintsForComponent(component);
      if (myDisabledIcon) {
        constraints.myDisabledIcon = value;
        getTabbedPane().setDisabledIconAt(myIndex, icon);
      }
      else
      {
        constraints.myIcon = value;
        getTabbedPane().setIconAt(myIndex, icon);
      }
    }

    @NotNull
    public PropertyRenderer<IconDescriptor> getRenderer() {
      return myRenderer;
    }

    public PropertyEditor<IconDescriptor> getEditor() {
      return myEditor;
    }

    @Override public boolean isModified(final RadComponent radComponent) {
      return getValue(radComponent) != null;
    }

    @Override public void resetValue(final RadComponent radComponent) throws Exception {
      setValue(radComponent, null);
    }
  }

  private class MyEnabledProperty extends AbstractBooleanProperty<RadComponent> {
    private final int myIndex;

    public MyEnabledProperty(final Property parent, final int index) {
      super(parent, "Tab Enabled", true);
      myIndex = index;
    }

    public Boolean getValue(final RadComponent component) {
      LwTabbedPane.Constraints constraints = getConstraintsForComponent(component);
      return constraints.myEnabled;
    }

    protected void setValueImpl(final RadComponent component, final Boolean value) throws Exception {
      LwTabbedPane.Constraints constraints = getConstraintsForComponent(component);
      constraints.myEnabled = value.booleanValue();
      getTabbedPane().setEnabledAt(myIndex, value.booleanValue());
    }
  }

  private class RadTabbedPaneLayoutManager extends RadLayoutManager {

    @Nullable public String getName() {
      return null;
    }

    @Override @NotNull
    public ComponentDropLocation getDropLocation(RadContainer container, @Nullable final Point location) {
      final JTabbedPane tabbedPane = getTabbedPane();
      final TabbedPaneUI ui = tabbedPane.getUI();
      if (location != null && tabbedPane.getTabCount() > 0) {
        for(int i=0; i<tabbedPane.getTabCount(); i++) {
          Rectangle rc = ui.getTabBounds(tabbedPane, i);
          if (location.x < rc.getCenterX()) {
            return new InsertTabDropLocation(i, new Rectangle(rc.x-4, rc.y, 8, rc.height));
          }
        }
      }
      return new InsertTabDropLocation(tabbedPane.getTabCount(), null);
    }

    public void writeChildConstraints(final XmlWriter writer, final RadComponent child) {
      writer.startElement(UIFormXmlConstants.ELEMENT_TABBEDPANE);
      try{
        final JComponent delegee = child.getDelegee();
        final JTabbedPane tabbedPane = getTabbedPane();
        final int i = tabbedPane.indexOfComponent(delegee);
        if (i == -1) {
          throw new IllegalArgumentException("cannot find tab for " + child);
        }

        final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(RadTabbedPane.this);
        final LwTabbedPane.Constraints tabTitleConstraints = id2Constraints.get(child.getId());
        if (tabTitleConstraints != null) {
          writer.writeStringDescriptor(tabTitleConstraints.myTitle,
                                       UIFormXmlConstants.ATTRIBUTE_TITLE,
                                       UIFormXmlConstants.ATTRIBUTE_TITLE_RESOURCE_BUNDLE,
                                       UIFormXmlConstants.ATTRIBUTE_TITLE_KEY);

          if (tabTitleConstraints.myIcon != null) {
            writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_ICON, tabTitleConstraints.myIcon.getIconPath());
          }
          if (tabTitleConstraints.myDisabledIcon != null) {
            writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_DISABLED_ICON, tabTitleConstraints.myDisabledIcon.getIconPath());
          }
          if (!tabTitleConstraints.myEnabled) {
            writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_ENABLED, false);
          }
          if (tabTitleConstraints.myToolTip != null) {
            writer.startElement(UIFormXmlConstants.ELEMENT_TOOLTIP);
            writer.writeStringDescriptor(tabTitleConstraints.myToolTip,
                                         UIFormXmlConstants.ATTRIBUTE_VALUE,
                                         UIFormXmlConstants.ATTRIBUTE_RESOURCE_BUNDLE,
                                         UIFormXmlConstants.ATTRIBUTE_KEY);
            writer.endElement();
          }
        }
        else {
          final String title = tabbedPane.getTitleAt(i);
          writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_TITLE, title != null ? title : "");
        }
      }
      finally{
        writer.endElement();
      }
    }

    public void addComponentToContainer(final RadContainer container, final RadComponent component, final int index) {
      final JTabbedPane tabbedPane = getTabbedPane();
      LwTabbedPane.Constraints constraints = null;
      if (component.getCustomLayoutConstraints() instanceof LwTabbedPane.Constraints) {
        constraints = ((LwTabbedPane.Constraints)component.getCustomLayoutConstraints());
      }
      component.setCustomLayoutConstraints(null);
      final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(RadTabbedPane.this);
      id2Constraints.put(component.getId(), constraints);
      final String tabName = calcTabName(constraints == null ? null : constraints.myTitle);
      String toolTip = null;
      Icon icon = null;
      if (constraints != null) {
        toolTip = getDescriptorText(constraints.myToolTip);
        if (constraints.myIcon != null) {
          IntroIconProperty.ensureIconLoaded(getModule(), constraints.myIcon);
          icon = constraints.myIcon.getIcon();
        }
      }
      tabbedPane.insertTab(tabName, icon, component.getDelegee(), toolTip, index);
      if (constraints != null) {
        if (constraints.myDisabledIcon != null) {
          IntroIconProperty.ensureIconLoaded(getModule(), constraints.myDisabledIcon);
          tabbedPane.setDisabledIconAt(index, constraints.myDisabledIcon.getIcon());
        }
        tabbedPane.setEnabledAt(index, constraints.myEnabled);
      }
    }

    @Override public void removeComponentFromContainer(final RadContainer container, final RadComponent component) {
      LOG.debug("Removing component with ID " + component.getId());
      final JTabbedPane tabbedPane = getTabbedPane();

      final JComponent delegee = component.getDelegee();
      final int i = tabbedPane.indexOfComponent(delegee);
      if (i == -1) {
        throw new IllegalArgumentException("cannot find tab for " + component);
      }
      final HashMap<String, LwTabbedPane.Constraints> id2Constraints = getId2Constraints(RadTabbedPane.this);
      LwTabbedPane.Constraints constraints = id2Constraints.get(component.getId());
      if (constraints == null) {
        LOG.debug("title of removed component is null");
        constraints = new LwTabbedPane.Constraints(StringDescriptor.create(tabbedPane.getTitleAt(i)));
      }
      else {
        LOG.debug("title of removed component is " + constraints.myTitle.toString());
      }
      component.setCustomLayoutConstraints(constraints);
      id2Constraints.remove(component.getId());
      tabbedPane.removeTabAt(i);
    }

    @Override public Property[] getComponentProperties(final Project project, final RadComponent component) {
      final JComponent delegee = component.getDelegee();
      final JTabbedPane tabbedPane = getTabbedPane();
      int index = tabbedPane.indexOfComponent(delegee);
      if (index >= 0) {
        return new Property[] { new MyTabGroupProperty(index) };
      }
      return Property.EMPTY_ARRAY;
    }

    @Override
    public boolean isSwitchedToChild(RadContainer container, RadComponent child) {
      return child == getSelectedTab();
    }

    @Override
    public boolean switchContainerToChild(RadContainer container, RadComponent child) {
      RadTabbedPane.this.selectTab(child);
      return true;
    }

    @Override
    public boolean areChildrenExclusive() {
      return true;
    }
  }

  private final class InsertTabDropLocation implements ComponentDropLocation {
    private int myInsertIndex;
    private String myInsertBeforeId;
    private final Rectangle myFeedbackRect;

    public InsertTabDropLocation(final int insertIndex, final Rectangle feedbackRect) {
      myInsertIndex = insertIndex;
      if (myInsertIndex < getTabbedPane().getTabCount()) {
        myInsertBeforeId = getRadComponent(myInsertIndex).getId();
      }
      myFeedbackRect = feedbackRect;
    }

    public RadContainer getContainer() {
      return RadTabbedPane.this;
    }

    public boolean canDrop(ComponentDragObject dragObject) {
      return dragObject.getComponentCount() == 1;
    }

    public void placeFeedback(FeedbackLayer feedbackLayer, ComponentDragObject dragObject) {
      final String tooltipText = UIDesignerBundle.message("insert.feedback.add.tab", getDisplayName(), myInsertIndex);
      if (myInsertIndex < getTabbedPane().getTabCount()) {
        feedbackLayer.putFeedback(getDelegee(), myFeedbackRect, VertInsertFeedbackPainter.INSTANCE, tooltipText);
      }
      else {
        Rectangle rcFeedback;
        final JTabbedPane tabbedPane = getTabbedPane();
        final TabbedPaneUI ui = tabbedPane.getUI();
        if (tabbedPane.getTabCount() > 0) {
          Rectangle rc = ui.getTabBounds(tabbedPane, tabbedPane.getTabCount()-1);
          rcFeedback = new Rectangle(rc.x+rc.width, rc.y, 50, rc.height);
        }
        else {
          // approximate
          rcFeedback = new Rectangle(0, 0, 50, tabbedPane.getFontMetrics(tabbedPane.getFont()).getHeight() + 8);
        }
        feedbackLayer.putFeedback(getDelegee(), rcFeedback, tooltipText);
      }
    }

    public void processDrop(GuiEditor editor,
                            RadComponent[] components,
                            GridConstraints[] constraintsToAdjust,
                            ComponentDragObject dragObject) {
      if (myInsertBeforeId != null) {
        for(int i=0; i<getTabbedPane().getTabCount(); i++) {
          if (getRadComponent(i).getId().equals(myInsertBeforeId)) {
            myInsertIndex = i;
            break;
          }
        }
      }
      if (myInsertIndex > getTabbedPane().getTabCount()) {
        myInsertIndex = getTabbedPane().getTabCount();
      }
      RadComponent componentToAdd = components [0];
      if (componentToAdd instanceof RadContainer) {
        addComponent(componentToAdd, myInsertIndex);
      }
      else {
        Palette palette = Palette.getInstance(editor.getProject());
        RadContainer panel = InsertComponentProcessor.createPanelComponent(editor);
        addComponent(panel);
        panel.getDropLocation(null).processDrop(editor, new RadComponent[] { componentToAdd }, null,
                                                new ComponentItemDragObject(palette.getPanelItem()));
      }
      getTabbedPane().setSelectedIndex(myInsertIndex);
    }

    @Nullable
    public ComponentDropLocation getAdjacentLocation(Direction direction) {
      return null;
    }
  }
}
