/*******************************************************************************
 * Copyright (c) 2001, 2007 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.wsdl.ui.internal.wizards;

import java.util.List;
import java.util.Vector;

import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.wst.common.ui.internal.viewers.NavigableTableViewer;
import org.eclipse.wst.wsdl.ui.internal.Messages;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin;
import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
import org.eclipse.wst.xml.ui.internal.dialogs.EditNamespaceInfoDialog;
import org.eclipse.wst.xml.ui.internal.dialogs.UpdateListener;
import org.eclipse.wst.xml.ui.internal.util.XMLCommonResources;
 
public class NamespaceTable extends Composite
{
  protected static final String NAMESPACE_URI = XMLCommonResources.getInstance().getString("_UI_LABEL_NAMESPACE_NAME");  //$NON-NLS-1$
  protected static final String PREFIX = XMLCommonResources.getInstance().getString("_UI_LABEL_PREFIX");  //$NON-NLS-1$
  protected static final String INCLUDE = Messages._UI_TITLE_SELECT; //$NON-NLS-1$
    
  protected List namespaceInfoList = new Vector();
  protected List checkedList = new Vector();
  protected NamespaceNavigableTableViewer tableViewer;    
  protected Button addButton;

  protected NamespaceInfoTableLabelProvider provider;
  protected UpdateListener updateListener;   
  protected IPath resourceLocation;  
  protected int visibleRows = -1;  
  protected boolean dummyRowsRemoved = false;
  Table table;

  public NamespaceTable(Composite parent)
  {  
    this(parent, -1, -1, -1);
  }    

  public NamespaceTable(Composite parent, int visibleRows)
  {
    this(parent, -1, -1, visibleRows);
  }

  public NamespaceTable(Composite parent, int widthHint, int heightHint)
  {
    this(parent, widthHint, heightHint, -1);
  }

  public NamespaceTable(Composite parent, int widthHint, int heightHint, int visibleRows)
  {
    super(parent, SWT.NONE);                                                               
    setLayout(createGridLayout());                                 
    GridData fillGD= new GridData();
    fillGD.horizontalAlignment= GridData.FILL;
    fillGD.grabExcessHorizontalSpace= true;
    fillGD.verticalAlignment= GridData.FILL;
    fillGD.grabExcessVerticalSpace= true;
    
    setLayoutData(fillGD);             
    
    Group namespaceInfoGroup = new Group(this, SWT.NONE);
    namespaceInfoGroup.setText(Messages._UI_LABEL_NAMESPACE_URIS_TO_BE_INCLUDED); //$NON-NLS-1$
    namespaceInfoGroup.setLayout(new GridLayout());   
    GridData gd = fillGD;
    if (widthHint != -1)
    {
      gd.widthHint = widthHint;
    }   
    if (heightHint != -1)
    {
      gd.heightHint = heightHint;
    }
    namespaceInfoGroup.setLayoutData(gd); 
    //WorkbenchHelp.setHelp(namespaceInfoGroup, new ControlContextComputer(namespaceInfoGroup, XMLBuilderContextIds.XMLC_NAMESPACE_GROUP));
                    
    String[] titleArray = {INCLUDE, PREFIX, NAMESPACE_URI};

    table = new Table(namespaceInfoGroup, SWT.FULL_SELECTION);
    table.setHeaderVisible(true);
    
    table.setLayoutData(fillGD);
    table.setLinesVisible(true);
    table.addMouseListener(new MouseAdapter()
    {
      public void mouseDown(MouseEvent e)
      {
        TableItem item = table.getItem(new Point(e.x, e.y));
        if (item != null)
        {
          Object obj = item.getData();
          if (obj != null)
          {
            TableElement holder = (TableElement)obj;
            TableColumn col = table.getColumn(0);
            if (e.x < col.getWidth()) // if the point falls within the Select column then perform check/uncheck
            {
              String currentState = holder.getChecked();
              if (currentState.equals("true")) //$NON-NLS-1$
              {
                holder.setChecked("false"); //$NON-NLS-1$
                checkedList.set(holder.getIndex(), "false"); //$NON-NLS-1$
              }  
              else if (currentState.equals("false")) //$NON-NLS-1$
              {
                holder.setChecked("true");  //$NON-NLS-1$
                checkedList.set(holder.getIndex(), "true"); //$NON-NLS-1$
              }
              tableViewer.refresh();
              if (updateListener != null)
              {
                updateListener.updateOccured(this, namespaceInfoList);
              }
            }
          }
        }        
      }
    });

    tableViewer = new NamespaceNavigableTableViewer(table);
    provider = new NamespaceInfoTableLabelProvider();
    tableViewer.setContentProvider(provider);   
    tableViewer.setLabelProvider(provider);
    tableViewer.setColumnProperties(titleArray);
    tableViewer.setCellModifier(new NamespaceInfoCellModifier());

                    
    int[] widthArray = {10, 20, 50};
    TableLayout layout = new TableLayout();  

    for (int i = 0; i < titleArray.length; i++)
    {
      TableColumn column = new TableColumn(table, i);
      column.setText(titleArray[i]);
      column.setAlignment(SWT.LEFT);
      layout.addColumnData(new ColumnWeightData(widthArray[i], true));
    }         
    this.visibleRows = visibleRows;
    for (int i = 0; i < visibleRows; i++)
    {
      TableItem item = new TableItem(table, SWT.NONE); 
      item.setText("#######"); //$NON-NLS-1$
    }
    table.setLayout(layout);  
    
    CellEditor[] cellEditors = new CellEditor[titleArray.length];
    cellEditors[0] = new NamespaceInfoCheckboxCellEditor(table);
    cellEditors[1] = new TextCellEditor(table);
    tableViewer.setCellEditors(cellEditors);

//    createButtons(namespaceInfoGroup);            

    initialize();    
  }    

  public void setUpdateListener(UpdateListener updateListener)
  {
    this.updateListener = updateListener;
  }

  public void setNamespaceInfoList(List namespaceInfoList)
  {    
    this.namespaceInfoList = namespaceInfoList;
    update();
  }                       

  public List getNamespaceInfoList()
  {
    return namespaceInfoList;
  }  

  public List getNamespaceCheckedList()
  {
    return checkedList;
  }  

  public String getWSDLPrefix()
  {
    return ((NamespaceInfo)(namespaceInfoList.get(0))).prefix;
  }

  public void setResourceLocation(IPath resourceLocation)
  {
    this.resourceLocation = resourceLocation;
  }

  public GridLayout createGridLayout()
  {
    GridLayout gridLayout = new GridLayout();
    gridLayout.marginWidth = 0;
    gridLayout.horizontalSpacing = 0;
    return gridLayout;
  }
    
  protected void initialize()
  {
    // better way to do this....
    NamespaceInfo info1 = new NamespaceInfo();
    info1.prefix = "wsdl"; //$NON-NLS-1$
    info1.uri = "http://schemas.xmlsoap.org/wsdl/"; //$NON-NLS-1$
    namespaceInfoList.add(info1);
    checkedList.add("true"); //$NON-NLS-1$
    NamespaceInfo info2 = new NamespaceInfo();
    info2.prefix = "soap"; //$NON-NLS-1$
    info2.uri = "http://schemas.xmlsoap.org/wsdl/soap/"; //$NON-NLS-1$
    namespaceInfoList.add(info2);
    checkedList.add("false"); //$NON-NLS-1$
    NamespaceInfo info3 = new NamespaceInfo();
    info3.prefix = "http";  //$NON-NLS-1$
    info3.uri = "http://schemas.xmlsoap.org/wsdl/http/"; //$NON-NLS-1$
    namespaceInfoList.add(info3);
    checkedList.add("false"); //$NON-NLS-1$
    NamespaceInfo info4 = new NamespaceInfo();
    info4.prefix = "mime"; //$NON-NLS-1$
    info4.uri = "http://schemas.xmlsoap.org/wsdl/mime/"; //$NON-NLS-1$
    namespaceInfoList.add(info4);
    checkedList.add("false"); //$NON-NLS-1$
    NamespaceInfo info5 = new NamespaceInfo();
    info5.prefix = "soapenc"; //$NON-NLS-1$
    info5.uri = "http://schemas.xmlsoap.org/soap/encoding/"; //$NON-NLS-1$
    namespaceInfoList.add(info5);
    checkedList.add("false"); //$NON-NLS-1$
    NamespaceInfo info6 = new NamespaceInfo();
    info6.prefix = "soapenv"; //$NON-NLS-1$
    info6.uri = "http://schemas.xmlsoap.org/soap/envelope/"; //$NON-NLS-1$
    namespaceInfoList.add(info6);
    checkedList.add("false"); //$NON-NLS-1$
    NamespaceInfo info7 = new NamespaceInfo();
    info7.prefix = "xsi"; //$NON-NLS-1$
    info7.uri = "http://www.w3.org/2001/XMLSchema-instance"; //$NON-NLS-1$
    namespaceInfoList.add(info7);
    checkedList.add("false"); //$NON-NLS-1$
    NamespaceInfo info8 = new NamespaceInfo();
    info8.prefix = "xsd"; //$NON-NLS-1$
    info8.uri = "http://www.w3.org/2001/XMLSchema"; //$NON-NLS-1$
    namespaceInfoList.add(info8);
    checkedList.add("true"); //$NON-NLS-1$
    update();
  }

  protected void createButtons(Composite parent)
  {
    Composite composite = new Composite(parent, SWT.NONE);
    GridData hFillGD = new GridData();
    hFillGD.horizontalAlignment= GridData.FILL;
    hFillGD.grabExcessHorizontalSpace= true;
    
    composite.setLayoutData(hFillGD);
    GridLayout gridLayout = new GridLayout();
    gridLayout.numColumns = 2;
    gridLayout.marginHeight = 0;
    gridLayout.marginWidth = 0;
    composite.setLayout(gridLayout);

    GridData gd = new GridData();
    gd.horizontalAlignment = GridData.FILL;
    gd.grabExcessHorizontalSpace= true;
    
    Button hiddenButton = new Button(composite, SWT.NONE);
    hiddenButton.setLayoutData(gd);
    hiddenButton.setVisible(false);
    hiddenButton.setEnabled(false);

    SelectionListener selectionListener = new SelectionAdapter()
    {
      public void widgetSelected(SelectionEvent e)
      {  
        if (e.widget == addButton)
        {
          performNew();
        }
      }
    };   
    
    // create a composite to hold the three buttons
    Composite buttonComposite = new Composite(composite, SWT.NONE);

    buttonComposite.setLayoutData(hFillGD);
    GridLayout buttonGridLayout = new GridLayout();
    buttonGridLayout.numColumns = 1;
    buttonGridLayout.makeColumnsEqualWidth = true;
    buttonComposite.setLayout(buttonGridLayout);

    // add the New button
    //
    gd = new GridData();
    gd.horizontalAlignment = GridData.FILL;
    gd.grabExcessHorizontalSpace = true;

    addButton = new Button(buttonComposite, SWT.NONE);
    addButton.setText(Messages._UI_ACTION_ADD); //$NON-NLS-1$
    addButton.setLayoutData(gd);//ViewUtility.createHorizontalFill());
    addButton.addSelectionListener(selectionListener);
  }

  public void performNew()
  {
    NamespaceInfo info = new NamespaceInfo();
    EditNamespaceInfoDialog dialog = invokeDialog(XMLCommonResources.getInstance().getString("_UI_LABEL_NEW_NAMESPACE_INFORMATION"), info);  //$NON-NLS-1$
    if (dialog.getReturnCode() == Dialog.OK)
    {
      namespaceInfoList.add(info);
      checkedList.add("true"); //$NON-NLS-1$
      performDelayedUpdate();
    }
  } 
                     
  protected EditNamespaceInfoDialog invokeDialog(String title, NamespaceInfo info)
  {
    Shell shell = XMLCommonResources.getInstance().getWorkbench().getActiveWorkbenchWindow().getShell();
    EditNamespaceInfoDialog dialog = new EditNamespaceInfoDialog(shell, info);
    dialog.create();
    dialog.getShell().setText(title);
    dialog.setBlockOnOpen(true);
    dialog.setResourceLocation(resourceLocation);
    dialog.open();      
    return dialog;
  }

  protected void performDelayedUpdate()
  {
    Runnable delayedUpdate = new Runnable()
    {
      public void run()
      {
        update();
      }
    };
    Display.getCurrent().asyncExec(delayedUpdate);

    if (updateListener != null)
    {
      updateListener.updateOccured(this, namespaceInfoList);
    }
  }
 
  protected NamespaceInfo getTargetNamespaceInfo()
  {
    return (namespaceInfoList != null && namespaceInfoList.size() > 0) ? 
           (NamespaceInfo)namespaceInfoList.get(0) :
           null;
  }    

                    
  public void update()
  {
    updateHelper(namespaceInfoList);
  }
                           
  public void updateHelper(List namespaceInfoList)
  {                                      
    if (visibleRows != -1 && !dummyRowsRemoved)
    {
//      dummyRowsRemoved = true;
//      tableViewer.getTable().removeAll();
    }                                                      
    ISelection selection = tableViewer.getSelection();
    tableViewer.setInput(namespaceInfoList);
    if (selection.isEmpty())
    {                     
      if (namespaceInfoList.size() > 0)
      {
        tableViewer.setSelection(new StructuredSelection(namespaceInfoList.get(0)));
      }
    }
    else
    {
      tableViewer.setSelection(selection);
    }
  }

  protected class NamespaceInfoCheckboxCellEditor extends CheckboxCellEditor implements MouseListener
  {
    public NamespaceInfoCheckboxCellEditor(Composite parent)
    {
      super(parent);
    }

    protected void doSetValue(Object value)
    {
    }

    public void activate()
    {
       super.activate();
       deactivate();
       Display.getCurrent().getFocusControl().redraw();
    }

    public void mouseDown(MouseEvent e)   
    {      
      if (tableViewer.getTable().getItem(new Point(e.x, e.y)) != null)
      {
      }
    }    
    public void mouseDoubleClick(MouseEvent e) {}
    public void mouseUp(MouseEvent e) {}


  }


  protected class NamespaceInfoCellModifier implements ICellModifier
  {
    public NamespaceInfoCellModifier()
    {
      
    }
    
    public boolean canModify(Object element, String property)
    {
      if (property.equals(INCLUDE))
      {
        return true;
      }
      else if (property.equals(PREFIX))
      {
        return true;
      }
      return false;      
    }

    public Object getValue(Object element, String property)
    {
      int column = 0;
      if (property.equals(INCLUDE))
      {
        column = 0;
      }
      else if (property.equals(PREFIX))
      {
        column = 1;
      }
      else if (property.equals(NAMESPACE_URI))
      {
        column = 2;
      }

      if (element instanceof TableElement)
      {
        return provider.getColumnText(element, column);
      }
      else
      {
        return null;
      }
    }

    public void modify(Object element, String property, Object value)
    {
      TableItem item = (TableItem)element;
      if (item != null)
      {
        Object obj = item.getData();
        if (obj != null)
        {
          TableElement holder = (TableElement)obj;
          NamespaceInfo info = holder.getNamespaceInfo();
          if (property.equals(INCLUDE))
          {
            if (value instanceof Boolean)
            {
              if (((Boolean)value).booleanValue())
              {
                holder.setChecked("true"); //$NON-NLS-1$
                checkedList.set(holder.getIndex(), "true"); //$NON-NLS-1$
              }
              else
              {
                holder.setChecked("false"); //$NON-NLS-1$
                checkedList.set(holder.getIndex(), "false"); //$NON-NLS-1$
              }
            }
          }
          else if (property.equals(PREFIX))
          {
            info.prefix = ((String)value).trim();
          }

          Runnable delayedUpdate = new Runnable()
          {
            public void run()
            {
              tableViewer.refresh();
            }
          };
          Display.getCurrent().asyncExec(delayedUpdate);
          if (updateListener != null)
          {
            updateListener.updateOccured(this, namespaceInfoList);
          }

//          performDelayedUpdate();
        }
      }
    }
  }                   

  protected class TableElement
  {
    NamespaceInfo info;
    int index;
    String checked = "true"; //$NON-NLS-1$
    
    TableElement(NamespaceInfo info, int index)
    {
      this.info = info;
      this.index = index;
    }
    
    public NamespaceInfo getNamespaceInfo()
    {
      return info;
    }
    
    public int getIndex()
    {
      return index;
    }
    
    public String getChecked()
    {
      return checked;
    }
    
    public void setChecked(String checked)
    {
      this.checked = checked;
    }
  }

  /**
   * NamespaceInfoTableLabelProvider
   */
  protected class NamespaceInfoTableLabelProvider implements ITableLabelProvider, IStructuredContentProvider
  {
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
    {
    }

    public boolean isLabelProperty(Object element, String property)
    {
      return false;
    }

    public boolean isDeleted(Object element)
    {
      return false;
    }

    public Object[] getElements(Object inputElement)
    {
      Vector v = new Vector();
      for (int i = 0; i < namespaceInfoList.size(); i++)
      {
        NamespaceInfo info = (NamespaceInfo)namespaceInfoList.get(i);
        TableElement holder = new TableElement(info, i);
        holder.setChecked((String)checkedList.get(i));
        v.add(holder);
      }
      return v.toArray();
    }

    public String getColumnText(Object object, int column)
    {
      TableElement holder = (TableElement)object;
      NamespaceInfo info = holder.getNamespaceInfo();
      String result = null;
      switch (column)
      {
        case 1: { result = info.prefix; break; }
        case 2: { result = info.uri; break; }
      }
      result = result != null ? result.trim() : ""; //$NON-NLS-1$
      if (result.equals("")) //$NON-NLS-1$
      {
        switch (column)
        {
          case 2: 
          { 
            result = XMLCommonResources.getInstance().getString("_UI_NO_NAMESPACE_NAME");   //$NON-NLS-1$
            break; 
          }
        }
      }
      return result;
    }

//    private String getDefaultPrefix()
//    {
//      String defaultPrefix = "p";
//      if (namespaceInfoList == null)
//        return defaultPrefix;
//
//      Vector v = new Vector();
//      for (int i=0; i<namespaceInfoList.size(); i++)
//      {
//        NamespaceInfo nsinfo = (NamespaceInfo)namespaceInfoList.get(i);
//        if (nsinfo.prefix != null)
//          v.addElement(nsinfo.prefix);
//      }
//
//      if (v.contains(defaultPrefix))
//      {
//        String s = defaultPrefix;
//        for (int j=0; v.contains(s); j++)
//        {
//          s = defaultPrefix + Integer.toString(j);
//        }
//        return s;
//      }
//      else
//        return defaultPrefix;
//    }

    public Image getColumnImage(Object object, int columnIndex)
    {
      if (columnIndex == 0)  // Output Column
      {
        if (object instanceof TableElement)
        {
          TableElement holder = (TableElement) object;
          String result = holder.getChecked();
          if (result.equals("true")) //$NON-NLS-1$
          {
            return WSDLEditorPlugin.getInstance().getImage("icons/output_yes.gif"); //$NON-NLS-1$
          }
          else
          {
            return WSDLEditorPlugin.getInstance().getImage("icons/output_no.gif"); //$NON-NLS-1$
          }
        }
      }
      return null;
    }

    public boolean isLabelProperty(Object object, Object property)
    {
      return false;
    }

    public void addListener(ILabelProviderListener listener)
    {
    }

    public void removeListener(ILabelProviderListener listener)
    {
    }

    public void dispose()
    {
    }
  }

  class NamespaceNavigableTableViewer extends NavigableTableViewer
  {
    public NamespaceNavigableTableViewer(Table parent)
    {
      super(parent);
    }
  }
}
