/*******************************************************************************
 * 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.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"); 
  protected static final String PREFIX = XMLCommonResources.getInstance().getString("_UI_LABEL_PREFIX"); 
  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); 
    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");  
            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);
    }
  }
}
