/*******************************************************************************
 * 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.common.properties.sections;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.SubContributionManager;
import org.eclipse.jface.action.SubStatusLineManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.FormColors;
import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eclipse.wst.xsd.ui.internal.editor.XSDEditorPlugin;
import org.eclipse.xsd.XSDComponent;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDSchema;

public abstract class AbstractSection extends AbstractPropertySection implements SelectionListener, Listener
{
  protected Composite composite;
  protected PaintListener painter;
  protected XSDSchema xsdSchema;
  protected Object input;
  protected boolean isReadOnly;
  protected boolean listenerEnabled = true;
  protected boolean isSimple;
  protected CustomListener customListener = new CustomListener();
  protected IEditorPart owningEditor;
  private IStatusLineManager statusLine;
  
  public static final Image ICON_ERROR = XSDEditorPlugin.getDefault().getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_ERROR_TSK);
  
  public AbstractSection()
  {
    super();
  }
  
  public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage)
  {
    super.createControls(parent, aTabbedPropertySheetPage);
    isSimple = getIsSimple();
    createContents(parent);
  }
  
  protected abstract void createContents(Composite parent);

    protected PaintListener createPainter() {
        return new PaintListener() {

            public void paintControl(PaintEvent e) {
//                Rectangle bounds = composite.getClientArea();
                GC gc = e.gc;

                gc.setForeground(gc.getBackground());
                gc.setBackground(getWidgetFactory().getColors().getColor(
                    FormColors.TB_BG));

//                gc.fillGradientRectangle(4 + bounds.width / 2, 0,
//                    bounds.width / 2 - 9, bounds.height, false);

                gc.setForeground(getWidgetFactory().getColors().getColor(
                    FormColors.TB_BORDER));
//                gc.drawLine(bounds.width - 5, 0, bounds.width - 5,
//                    bounds.height);
            }

        };

    }
    
    public void dispose()
    {
        if (composite != null && ! composite.isDisposed() && painter != null)
            composite.removePaintListener(painter);
        
        super.dispose();
    }

    public void setInput(IWorkbenchPart part, ISelection selection) {
        super.setInput(part, selection);
        isSimple = getIsSimple();
        Object input = ((IStructuredSelection)selection).getFirstElement();
        this.input = input;
        
        if (input instanceof XSDConcreteComponent)
        {
          xsdSchema = ((XSDConcreteComponent)input).getSchema();
        }
        
        // set owning editor of this section
        if (part!=null)
        {
            if (part instanceof IEditorPart)
            {
                owningEditor = (IEditorPart)part;
            }
            else
            {
                owningEditor = part.getSite().getWorkbenchWindow().getActivePage().getActiveEditor();
            }
        }
        if (xsdSchema == owningEditor.getAdapter(XSDSchema.class))
        {
          isReadOnly = false;
        }
        else
        {
          isReadOnly = true;
        }

    }

    public void refresh()
    {
      super.refresh();

      if (isReadOnly)
      {
        composite.setEnabled(false);
      }
      else
      {
        composite.setEnabled(true);
      }
    }

    public void applyAllListeners(Control control)
    {
      control.addListener(SWT.Modify, customListener);
      control.addListener(SWT.FocusOut, customListener);
      control.addListener(SWT.KeyDown, customListener);
    }
    
    public void applyModifyListeners(Control control)
    {
      control.addListener(SWT.Modify, customListener);
      control.addListener(SWT.FocusOut, customListener);
    }

    public void applyKeyListener(Control control)
    {
      control.addListener(SWT.KeyDown, customListener);
    }

    public void removeListeners(Control control)
    {
      control.removeListener(SWT.Modify, customListener);
      control.removeListener(SWT.FocusOut, customListener);
      control.removeListener(SWT.KeyDown, customListener);
    }
    
    public void doWidgetDefaultSelected(SelectionEvent e)
    {}
    
    public void doWidgetSelected(SelectionEvent e)
    {}

    public void widgetSelected(SelectionEvent e)
    {
      if (isListenerEnabled() &&
          input != null &&
          !isReadOnly) 
      {
        doWidgetSelected(e);
      }
    }

    public void widgetDefaultSelected(SelectionEvent e)
    {
      if (isListenerEnabled() &&
          input != null &&
          !isReadOnly) 
      {
        doWidgetDefaultSelected(e);
      }
    }

    /**
     * Get the value of listenerEnabled.
     * @return value of listenerEnabled.
     */
    public boolean isListenerEnabled() 
    {
      return listenerEnabled;
    }
    
    /**
     * Set the value of listenerEnabled.
     * @param v  Value to assign to listenerEnabled.
     */
    public void setListenerEnabled(boolean  v) 
    {
      this.listenerEnabled = v;
    }

    /**
     * Sent when an event that the receiver has registered for occurs.
     *
     * @param event the event which occurred
     */
    public void handleEvent(Event event)
    {
      if (isListenerEnabled() && !isReadOnly) 
      {
        doHandleEvent(event);
      }
    }

    /**
     * Subclasses should override
     * @param event
     */
    protected void doHandleEvent(Event event)
    {
    }

    protected IEditorPart getActiveEditor()
    {
      IWorkbench workbench = PlatformUI.getWorkbench();
      IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
      IEditorPart editorPart = workbenchWindow.getActivePage().getActiveEditor();
      this.owningEditor = editorPart;
      return editorPart;
    }
    
    public CommandStack getCommandStack()
    {
      Object commandStack = owningEditor.getAdapter(CommandStack.class); 
          
      if (commandStack==null)
          return null;
      else
          return (CommandStack)commandStack;
    }
    
    public boolean getIsSimple()
    {
      return false;
    }
    
    
    
    /**
     * Intended to display error messages.
     * @return
     */
    private IStatusLineManager getStatusLineManager()
    {
      if (statusLine==null && getPart()!=null)
      {
        if(getPart().getSite() instanceof IEditorSite)
          statusLine = ((IEditorSite)getPart().getSite()).getActionBars().getStatusLineManager();
        else if (getPart().getSite() instanceof IViewSite)
          statusLine = ((IViewSite)getPart().getSite()).getActionBars().getStatusLineManager();
        
        /* 
         * We must manually set the visibility of the status line since the action bars are from the editor
         * which means the status line only shows up when the editor is in focus (by default).
         * Note only a SubStatusLineManager can set the visibility.
         */
        if (statusLine instanceof SubStatusLineManager)
          ((SubStatusLineManager)statusLine).setVisible(true);
      }
      
      return statusLine;
    }

    /**
     * Display an error message in the status line.
     * Call setErrorMessage(null) to clear the status line.
     * @param text 
     */
    public void setErrorMessage(String text)
    {
      IStatusLineManager statusLine = getStatusLineManager();

      if (statusLine!=null)
      {
        if (text==null || text.length()<1)
          statusLine.setErrorMessage(null);
        else
          statusLine.setErrorMessage(ICON_ERROR, text);

        // ensure our message gets displayed
        if (statusLine instanceof SubContributionManager)
          ((SubContributionManager)statusLine).setVisible(true);
        
        statusLine.update(true);
      }
    }

    
    protected EObject getModel()
    {
      return (XSDComponent)input;
    }

    
    class CustomListener implements Listener
    {
      boolean handlingEvent = false;
      public void handleEvent(Event event)
      {
        if (isListenerEnabled() && !isReadOnly) 
        {
          switch (event.type)
          {
            case SWT.KeyDown :
            {
              if (event.character == SWT.CR)
              {
                if (!handlingEvent)
                {
                  handlingEvent = true;
                  doHandleEvent(event);
                  handlingEvent = false;
                }
              }
              break;
            }
            case SWT.FocusOut :
            {
              if (!handlingEvent)
              {
                handlingEvent = true;
                doHandleEvent(event);
                handlingEvent = false;
              }
              break;
            }
          }
        }
      }
    }

}
