/*******************************************************************************
 * Copyright (c) 2001, 2006 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.xsd.ui.internal.design.editparts;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.swt.graphics.Image;
import org.eclipse.wst.xsd.ui.internal.adapters.CategoryAdapter;
import org.eclipse.wst.xsd.ui.internal.adapters.XSDSchemaAdapter;
import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.BaseEditPart;
import org.eclipse.wst.xsd.ui.internal.adt.design.editpolicies.KeyBoardAccessibilityEditPolicy;
import org.eclipse.wst.xsd.ui.internal.adt.typeviz.design.figures.HeadingFigure;
import org.eclipse.wst.xsd.ui.internal.common.util.XSDCommonUIUtils;
import org.eclipse.wst.xsd.ui.internal.design.editpolicies.SelectionHandlesEditPolicyImpl;
import org.eclipse.wst.xsd.ui.internal.design.layouts.FillLayout;
import org.eclipse.wst.xsd.ui.internal.editor.Messages;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDSchema;

public class XSDSchemaEditPart extends BaseEditPart
{
  protected Label label;

  protected Figure outer, contentFigure;
  protected HeadingFigure headingFigure;

  public IFigure getContentPane()
  {
    return contentFigure;
  }

  protected IFigure createFigure()
  {
    outer = new Figure();
    // outer.setBorder(new RoundedLineBorder(1, 6));
    outer.setBorder(new LineBorder(1));

    FillLayout fillLayout = new FillLayout(4);
    outer.setLayoutManager(fillLayout);

    headingFigure = new HeadingFigure();
    outer.add(headingFigure);

    final int theMinHeight = 200;
    FillLayout outerLayout = new FillLayout()
    {
      protected Dimension calculatePreferredSize(IFigure parent, int width, int height)
      {
        Dimension d = super.calculatePreferredSize(parent, width, height);
        d.union(new Dimension(250, theMinHeight));
        return d;
      }
    };
    outerLayout.setHorizontal(false);
    outer.setLayoutManager(outerLayout);

    RectangleFigure line = new RectangleFigure()
    {
      public Dimension getPreferredSize(int wHint, int hHint)
      {
        Dimension d = super.getPreferredSize(wHint, hHint);
        d.width += 20;
        d.height = 1;
        return d;
      }
    };
    ToolbarLayout lineLayout = new ToolbarLayout(false);
    lineLayout.setVertical(true);
    lineLayout.setStretchMinorAxis(true);
    line.setLayoutManager(lineLayout);
    outer.add(line);

    contentFigure = new Figure();
    contentFigure.setBorder(new MarginBorder(4, 4, 4, 4));
    fillLayout = new FillLayout(4);
    contentFigure.setLayoutManager(fillLayout);

    outer.add(contentFigure);

    return outer;
  }

  protected List getModelChildren()
  {
    XSDSchemaAdapter schemaAdapter = (XSDSchemaAdapter) getModel();
    List list = new ArrayList();
    
    schemaAdapter.updateCategories();

    List templist = new ArrayList();
    templist.add(schemaAdapter.getCategory(CategoryAdapter.DIRECTIVES));
    Holder holder = new Holder(templist);
    list.add(holder);

    templist = new ArrayList();
    templist.add(schemaAdapter.getCategory(CategoryAdapter.ELEMENTS));
    templist.add(schemaAdapter.getCategory(CategoryAdapter.TYPES));
    holder = new Holder(templist);
    list.add(holder);

    templist = new ArrayList();
    templist.add(schemaAdapter.getCategory(CategoryAdapter.ATTRIBUTES));
    templist.add(schemaAdapter.getCategory(CategoryAdapter.GROUPS));
    holder = new Holder(templist);
    list.add(holder);

    return list;
  }

  protected EditPart createChild(Object model)
  {
    CategoryRowEditPart result = new CategoryRowEditPart();
    result.setModel(model);
    result.setParent(this);
    return result;
  }

  protected void refreshVisuals()
  {
    super.refreshVisuals();
    
    LineBorder border = (LineBorder) outer.getBorder();
    border.setWidth(isSelected ? 2 : 1);
    headingFigure.setSelected(isSelected);

    XSDSchemaAdapter schemaAdapter = (XSDSchemaAdapter) getModel();
    Image image = schemaAdapter.getImage();
    headingFigure.getLabel().setIcon(image);
    if (image != null)
    {
      headingFigure.getLabel().setIcon(XSDCommonUIUtils.getUpdatedImage((XSDConcreteComponent) schemaAdapter.getTarget(), image, false));
    }
    outer.repaint();
    
    String targetNamespaceValue = ((XSDSchema) ((XSDSchemaAdapter) getModel()).getTarget()).getTargetNamespace();
    if (targetNamespaceValue == null || targetNamespaceValue.length() == 0)
    {
      targetNamespaceValue = Messages._UI_GRAPH_XSDSCHEMA_NO_NAMESPACE;
    }
    headingFigure.getLabel().setText(Messages._UI_GRAPH_XSDSCHEMA + " : " + targetNamespaceValue);  //$NON-NLS-1$  
  }
  
  public EditPart doGetRelativeEditPart(EditPart editPart, int direction)
  {
      EditPart result = null;
      if (editPart instanceof CategoryEditPart)
      {
        CategoryAdapter adapter = (CategoryAdapter)editPart.getModel();    
        switch (adapter.getGroupType())
        { 
          case CategoryAdapter.DIRECTIVES:
          {
            if (direction == PositionConstants.SOUTH)
            {
              result = getCategoryEditPart(CategoryAdapter.ELEMENTS);
            }  
            break;
          }
          case CategoryAdapter.ELEMENTS:
          {
            if (direction == PositionConstants.SOUTH)
            {
              result = getCategoryEditPart(CategoryAdapter.ATTRIBUTES);
            }           
            else if (direction == PositionConstants.NORTH)
            {
              result = getCategoryEditPart(CategoryAdapter.DIRECTIVES);
            } 
            break;
          }
          case CategoryAdapter.TYPES:
          {
            if (direction == PositionConstants.SOUTH)
            {
              result = getCategoryEditPart(CategoryAdapter.GROUPS);
            }           
            else if (direction == PositionConstants.NORTH)
            {
              result = getCategoryEditPart(CategoryAdapter.DIRECTIVES);
            } 
            break;        
          }
          case CategoryAdapter.ATTRIBUTES:      
          {
            if (direction == PositionConstants.NORTH)
            {
              result = getCategoryEditPart(CategoryAdapter.ELEMENTS);
            }    
            break;
          }   
          case CategoryAdapter.GROUPS:      
          {
            if (direction == PositionConstants.NORTH)
            {
              result = getCategoryEditPart(CategoryAdapter.TYPES);
            }    
            break;
          }
        }        
      } 
      else if (editPart == this)
      {       
        if (direction == KeyBoardAccessibilityEditPolicy.IN_TO_FIRST_CHILD)
        {
          result = ((CategoryRowEditPart)getChildren().get(0)).doGetRelativeEditPart(editPart, direction);        
        }          
      }  
      return result;               
  }
  
  private EditPart getCategoryEditPart(int kind)
  {
    for (Iterator j = getChildren().iterator(); j.hasNext(); )      
    {    
      EditPart row = (EditPart)j.next();    
      for (Iterator i = row.getChildren().iterator(); i.hasNext(); )
      {
        EditPart editPart = (EditPart)i.next();
        if (editPart instanceof CategoryEditPart)
        {
          CategoryEditPart categoryEditPart = (CategoryEditPart)editPart;
          CategoryAdapter adapter = (CategoryAdapter)categoryEditPart.getModel();
          if (adapter.getGroupType() == kind)
          {
            return editPart;
          }
        }  
      }
    }
    return null;
  }  

  protected void createEditPolicies()
  {
    super.createEditPolicies();
    installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, new SelectionHandlesEditPolicyImpl());    
  }

  protected class Holder
  {
    List list;

    public Holder(List list)
    {
      this.list = list;
    }

    public List getList()
    {
      return list;
    }
  }

  protected class CategoryRowEditPart extends BaseEditPart
  {
    protected XSDSchema schema;
    protected Figure contentPane;

    protected IFigure createFigure()
    {
      Figure containerFigure = new Figure();
      containerFigure.setBorder(new MarginBorder(4, 4, 4, 4));
      // containerFigure.setBorder(new LineBorder(1));
      // containerFigure.setBackgroundColor(ColorConstants.green);

      FillLayout fillLayout = new FillLayout(4);
      fillLayout.setHorizontal(true);
      containerFigure.setLayoutManager(fillLayout);

      return containerFigure;
    }
    
    public EditPart doGetRelativeEditPart(EditPart editPart, int direction)
    {
      if (editPart instanceof CategoryEditPart)
      {
        if (direction == KeyBoardAccessibilityEditPolicy.OUT_TO_PARENT)
        {
          return getParent();
        }  
      }  
      else if (editPart instanceof XSDSchemaEditPart)
      {
        if (direction == KeyBoardAccessibilityEditPolicy.IN_TO_FIRST_CHILD)
        {
          return (EditPart)getChildren().get(0);
        }  
      }  
      return ((XSDSchemaEditPart)getParent()).doGetRelativeEditPart(editPart, direction);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getContentPane()
     */
    public IFigure getContentPane()
    {
      return super.getContentPane();
    }

    protected List getModelChildren()
    {
      Holder holder = (Holder) getModel();
      return holder.getList();
    }

    protected void createEditPolicies()
    {
      super.createEditPolicies();
    }
  }
}
