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

import java.text.Collator;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilder;
import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
import org.eclipse.wst.xml.ui.dialogs.NamespaceInfoErrorHelper;
import org.eclipse.wst.xml.ui.dialogs.SelectFileOrXMLCatalogIdPanel;
import org.eclipse.wst.xml.ui.dialogs.UpdateListener;
import org.eclipse.wst.xml.ui.nsedit.CommonEditNamespacesDialog;
import org.eclipse.wst.xml.uriresolver.XMLCatalogEntry;
import org.eclipse.wst.xml.uriresolver.util.URIHelper;

public class NewXMLWizard extends NewModelWizard
{                                  
  protected static final int CREATE_FROM_DTD     = 0;
  protected static final int CREATE_FROM_XSD     = 1;
  protected static final int CREATE_FROM_SCRATCH = 2;

  protected static final String[] createFromRadioButtonLabel
    = {XMLWizardsMessages._UI_RADIO_XML_FROM_DTD,
       XMLWizardsMessages._UI_RADIO_XML_FROM_SCHEMA,
       XMLWizardsMessages._UI_RADIO_XML_FROM_SCRATCH};

  protected static final String[] filePageFilterExtensions = {".xml"}; //$NON-NLS-1$
  protected static final String[] browseXSDFilterExtensions = {".xsd"}; //$NON-NLS-1$
  protected static final String[] browseDTDFilterExtensions = {".dtd"}; //$NON-NLS-1$

  protected NewFilePage newFilePage;
  protected StartPage startPage;
  protected SelectGrammarFilePage selectGrammarFilePage; 
  protected SelectRootElementPage selectRootElementPage;
                 
  protected String cmDocumentErrorMessage;

  protected NewXMLGenerator generator;


  public NewXMLWizard()
  {
    setWindowTitle(XMLWizardsMessages._UI_WIZARD_CREATE_XML_HEADING);
    setDefaultPageImageDescriptor(ImageDescriptor.createFromFile(XMLWizard.class,"icons/generatexml_wiz.gif")); //$NON-NLS-1$
    generator = new NewXMLGenerator();
  }
  

  public NewXMLWizard(IFile file, CMDocument cmDocument)
  {
    this();       

    generator.setGrammarURI(URIHelper.getPlatformURI(file));
    generator.setCMDocument(cmDocument);
  }


  public static void showDialog(Shell shell, IFile file, IStructuredSelection structuredSelection)
  {                        
    List errorList = new Vector();          
    String[] errorInfo = new String[2];
    CMDocument cmDocument = NewXMLGenerator.createCMDocument(file.getLocation().toOSString(), errorInfo);
    if (errorInfo[0] == null)
    {
      NewXMLWizard wizard = new NewXMLWizard(file, cmDocument);
      wizard.init(PlatformUI.getWorkbench(), structuredSelection);
      wizard.setNeedsProgressMonitor(true);
      WizardDialog dialog = new WizardDialog(shell, wizard);
      dialog.create();          
      dialog.getShell().setText(XMLWizardsMessages._UI_DIALOG_NEW_TITLE);     
      dialog.setBlockOnOpen(true);
      dialog.open();
    }         
    else
    {
      MessageDialog.openInformation(shell, errorInfo[0], errorInfo[1]);
    }
  }  


  public void addPages()
  {
    String grammarURI = generator.getGrammarURI();

    if (grammarURI == null)
    {
      // start page
      startPage = new StartPage("StartPage", createFromRadioButtonLabel) //$NON-NLS-1$
      {
        public void createControl(Composite parent)
        {
          super.createControl(parent);
        }
                    
        public void setVisible(boolean visible)
        {
          super.setVisible(visible);
          getRadioButtonAtIndex(getCreateMode()).setSelection(true);
          getRadioButtonAtIndex(getCreateMode()).setFocus();

          // Set the help context for each button
          //WorkbenchHelp.setHelp(startPage.getRadioButtonAtIndex(0), XMLBuilderContextIds.XMLC_FROM_DTD_RADIO);
          //WorkbenchHelp.setHelp(startPage.getRadioButtonAtIndex(1), XMLBuilderContextIds.XMLC_XML_SCHEMA_RADIO);
          //WorkbenchHelp.setHelp(startPage.getRadioButtonAtIndex(2), XMLBuilderContextIds.XMLC_SCRATCH_RADIO);
        }
      };


      startPage.setTitle(XMLWizardsMessages._UI_WIZARD_CREATE_XML_HEADING);
      startPage.setDescription(XMLWizardsMessages._UI_WIZARD_CREATE_XML_EXPL);
      addPage(startPage);
    }
                                   
    // new file page                              
    newFilePage = new NewFilePage(selection);
    newFilePage.setTitle(XMLWizardsMessages._UI_WIZARD_CREATE_XML_FILE_HEADING);
    newFilePage.setDescription(XMLWizardsMessages._UI_WIZARD_CREATE_XML_FILE_EXPL); 
    newFilePage.defaultName = (grammarURI != null) ? URIHelper.removeFileExtension(URIHelper.getLastSegment(grammarURI)) : "NewFile"; //$NON-NLS-1$
    newFilePage.defaultFileExtension = ".xml"; //$NON-NLS-1$
    newFilePage.filterExtensions = filePageFilterExtensions;
    addPage(newFilePage);
     
    // selectGrammarFilePage
    selectGrammarFilePage = new SelectGrammarFilePage();   
    addPage(selectGrammarFilePage);                                                                     
            
    // select root element page
    selectRootElementPage = new SelectRootElementPage();
    selectRootElementPage.setTitle(XMLWizardsMessages._UI_WIZARD_SELECT_ROOT_HEADING);
    selectRootElementPage.setDescription(XMLWizardsMessages._UI_WIZARD_SELECT_ROOT_EXPL);
    addPage(selectRootElementPage);
  }
                  

  public IWizardPage getStartingPage()
  {
    WizardPage result = null;
    if (startPage != null)
    {
      result = startPage;
    }
    else
    {
      result = newFilePage;
    }
    return result;
  }


  public int getCreateMode()
  {
    String grammarURI = generator.getGrammarURI();

    int result = CREATE_FROM_SCRATCH;
    if (grammarURI != null)
    {              
      if (grammarURI.endsWith(".dtd")) //$NON-NLS-1$
      {
        result = CREATE_FROM_DTD;
      }
      else if (grammarURI.endsWith(".xsd")) //$NON-NLS-1$
      {
        result = CREATE_FROM_XSD;
      }
    }
    else if (startPage != null)
    {
      int selectedIndex = startPage.getSelectedRadioButtonIndex();
      if (selectedIndex != -1)
      {
        result = selectedIndex;
      }
    }
    return result;
  }
 

  public IWizardPage getNextPage(IWizardPage currentPage)
  {
    WizardPage nextPage = null;
    if (currentPage == startPage)
    {
      nextPage = newFilePage;
    }
    else if (currentPage == newFilePage)
    {                       
      if (getCreateMode() == CREATE_FROM_SCRATCH)
      {
        nextPage = null;
      }
      else if (generator.getGrammarURI() == null)
      {
        nextPage = selectGrammarFilePage;
      }
      else
      {
        nextPage = selectRootElementPage;
      }
    }
    else if (currentPage == selectGrammarFilePage)
    {
      nextPage = selectRootElementPage;
    }                           
    return nextPage;
  }


  public boolean canFinish()
  {
    boolean result = false;

    IWizardPage currentPage = getContainer().getCurrentPage();

    if ((startPage != null && startPage.getSelectedRadioButtonIndex() == CREATE_FROM_SCRATCH && currentPage == newFilePage) ||
        (currentPage == selectRootElementPage))
    {
      result = currentPage.isPageComplete();
    }
    return result;
  }      
  

  public boolean performFinish()
  {       
    boolean result = true;
    super.performFinish();
    try
    {                                                                                   

      String[] namespaceErrors = generator.getNamespaceInfoErrors();
      if (namespaceErrors !=  null) 
      {
        String title = namespaceErrors[0];
        String message = namespaceErrors[1];
        result = MessageDialog.openQuestion(getShell(), title, message);
      }

      if (result)
      {
        String fileName = newFilePage.getFileName();
        if ((new Path(fileName)).getFileExtension() == null)
        {
          newFilePage.setFileName(fileName.concat(".xml")); //$NON-NLS-1$
        }

        IFile newFile = newFilePage.createNewFile();
        String xmlFileName = newFile.getLocation().toOSString();

        if (getContainer().getCurrentPage() == selectRootElementPage)
        {

          generator.createXMLDocument(newFile, xmlFileName);
        }           
        else
        {
          generator.createEmptyXMLDocument(newFile);
        }
        
		newFile.refreshLocal(1, null);
		
		IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		BasicNewResourceWizard.selectAndReveal(newFile, workbenchWindow); 
        openEditor(newFile);
      }
    }
    catch (Exception e)
    {
      //e.printStackTrace();
    }
    return result;
  }  
  
  public void openEditor(IFile file)
  {  
	// Open editor on new file.
  	String editorId = null;
  	IEditorDescriptor editor = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(file.getLocation().toOSString());
  	if(editor != null){
  		editorId = editor.getId();
  	}
  	IWorkbenchWindow dw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
	try {
		if (dw != null) {
			IWorkbenchPage page = dw.getActivePage();
			if (page != null)
				page.openEditor(new FileEditorInput(file), editorId, true);
		}
	} catch (PartInitException e) {
	}
  }
  

  protected String getDefaultSystemId()
  {  
    String relativePath = "platform:/resource/" + newFilePage.getContainerFullPath().toString() + "/dummy";  //$NON-NLS-1$ //$NON-NLS-2$
    return URIHelper.getRelativeURI(generator.getGrammarURI(), relativePath);
  }                          
     

  /**
   * SelectGrammarFilePage
   */
  class SelectGrammarFilePage extends WizardPage
  {
    protected SelectFileOrXMLCatalogIdPanel panel;
  
    SelectGrammarFilePage()
    {
      super("SelectGrammarFilePage"); //$NON-NLS-1$
    }  

    public void createControl(Composite parent)
    {             
      Composite composite = new Composite(parent, SWT.NONE);
      //WorkbenchHelp.setHelp(composite, XMLBuilderContextIds.XMLC_GRAMMAR_PAGE);
      composite.setLayout(new GridLayout());
      composite.setLayoutData(new GridData(GridData.FILL_BOTH));
      setControl(composite);

      panel = new SelectFileOrXMLCatalogIdPanel(composite);
      panel.setLayoutData(new GridData(GridData.FILL_BOTH));

      SelectFileOrXMLCatalogIdPanel.Listener listener = new SelectFileOrXMLCatalogIdPanel.Listener()
      {
        public void completionStateChanged()
        {          
          updateErrorMessage();
        }
      };
      panel.setListener(listener);
    }
   
    public void setVisible(boolean visible)
    {                              
      super.setVisible(visible);                              
      if (visible)
      {                      
        if (getCreateMode() == CREATE_FROM_DTD)
        {                               
          setTitle(XMLWizardsMessages._UI_WIZARD_SELECT_DTD_FILE_TITLE);
          setDescription(XMLWizardsMessages._UI_WIZARD_SELECT_DTD_FILE_DESC);
          panel.setFilterExtensions(browseDTDFilterExtensions);
        }
        else
        { 
          setTitle(XMLWizardsMessages._UI_WIZARD_SELECT_XSD_FILE_TITLE);
          setDescription(XMLWizardsMessages._UI_WIZARD_SELECT_XSD_FILE_DESC);
          panel.setFilterExtensions(browseXSDFilterExtensions);
        } 
        generator.setGrammarURI(null);
        generator.setCMDocument(null); 
        cmDocumentErrorMessage = null;        
      }                             
      panel.setVisibleHelper(visible);
    }  

    public String getURI()
    {                      
      String uri = panel.getXMLCatalogURI();
      if (uri == null)
      {
        IFile file = panel.getFile();
        if (file != null)
        {
          uri = URIHelper.getPlatformURI(file);
        }               
      }
      return uri;
    }  

    public boolean isPageComplete()
    {                            
      return getURI() != null && getErrorMessage() == null;
    }                        

    public String getXMLCatalogId()
    {
      return panel.getXMLCatalogId();
    }                            
    
    public XMLCatalogEntry getXMLCatalogEntry()
    {
      return panel.getXMLCatalogEntry();   
    }    

    public String computeErrorMessage()
    {           
      String errorMessage = null;
      String uri = getURI();               
      if (uri != null)
      {         
        if (!URIHelper.isReadableURI(uri,false))
        {
          errorMessage = XMLWizardsMessages._UI_LABEL_ERROR_CATALOG_ENTRY_INVALID;                  
        }
      }             
      return errorMessage;
    }


    public void updateErrorMessage()
    {
      String errorMessage = computeErrorMessage();  
      setErrorMessage(errorMessage);
      setPageComplete(isPageComplete());
    }
  }


  /**
   * SelectRootElementPage
   */
  class SelectRootElementPage extends WizardPage implements SelectionListener
  {
    protected Combo combo;
    protected Button[] radioButton;
    protected PageBook pageBook;
    protected XSDOptionsPanel xsdOptionsPanel;
    protected DTDOptionsPanel dtdOptionsPanel;


    SelectRootElementPage()
    {
      super("SelectRootElementPage"); //$NON-NLS-1$
    }

    public void createControl(Composite parent)
    {
      // container group
      Composite containerGroup = new Composite(parent,SWT.NONE);
      //WorkbenchHelp.setHelp(containerGroup, XMLBuilderContextIds.XMLC_ROOT_PAGE);
      containerGroup.setLayout(new GridLayout());
      containerGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      setControl(containerGroup);

      // select root element
      Label containerLabel = new Label(containerGroup, SWT.NONE);
      containerLabel.setText(XMLWizardsMessages._UI_LABEL_ROOT_ELEMENT);
      combo = new Combo(containerGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
      combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      combo.addSelectionListener(this);
      //WorkbenchHelp.setHelp(combo, XMLBuilderContextIds.XMLC_ROOT_ROOT);

      // Options
      {
        Group group = new Group(containerGroup, SWT.NONE);
        group.setText(XMLWizardsMessages._UI_WIZARD_CONTENT_OPTIONS);
        //WorkbenchHelp.setHelp(group, XMLBuilderContextIds.XMLC_CURRENT_GROUP);
        
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;
        layout.makeColumnsEqualWidth = true;
        layout.marginWidth = 0;
        group.setLayout(layout);
        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        radioButton = new Button[4];
                
        radioButton[0] = new Button(group, SWT.CHECK);
        radioButton[0].setText(XMLWizardsMessages._UI_WIZARD_CREATE_OPTIONAL_ATTRIBUTES);
        radioButton[0].setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        radioButton[0].setSelection(false);
        //WorkbenchHelp.setHelp(radioButton[0], XMLBuilderContextIds.XMLC_CREATE_OPTIONAL_ATTRIBUTES);
        
        radioButton[1] = new Button(group, SWT.CHECK);
        radioButton[1].setText(XMLWizardsMessages._UI_WIZARD_CREATE_OPTIONAL_ELEMENTS);
        radioButton[1].setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        radioButton[1].setSelection(false);
        //WorkbenchHelp.setHelp(radioButton[1], XMLBuilderContextIds.XMLC_CREATE_OPTIONAL_ELEMENTS);
        
        radioButton[2] = new Button(group, SWT.CHECK);
        radioButton[2].setText(XMLWizardsMessages._UI_WIZARD_CREATE_FIRST_CHOICE);
        radioButton[2].setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        radioButton[2].setSelection(true);
        //WorkbenchHelp.setHelp(radioButton[2], XMLBuilderContextIds.XMLC_CREATE_FIRST_CHOICE);
        
        radioButton[3] = new Button(group, SWT.CHECK);
        radioButton[3].setText(XMLWizardsMessages._UI_WIZARD_FILL_ELEMENTS_AND_ATTRIBUTES);
        radioButton[3].setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        radioButton[3].setSelection(true);                        
        //WorkbenchHelp.setHelp(radioButton[3], XMLBuilderContextIds.XMLC_FILL_ELEMENTS_AND_ATTRIBUTES);
/*
        radioButton = new Button[2];

        radioButton[0] = new Button(group, SWT.RADIO);
        radioButton[0].setText(XMLWizardsMessages.getString("_UI_WIZARD_CREATE_REQUIRED"));
        radioButton[0].setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        radioButton[0].setSelection(true);
        WorkbenchHelp.setHelp(radioButton[0], XMLBuilderContextIds.XMLC_CREATE_REQUIRED_ONLY);

        radioButton[1] = new Button(group, SWT.RADIO);
        radioButton[1].setText(XMLWizardsMessages.getString("_UI_WIZARD_CREATE_OPTIONAL"));
        radioButton[1].setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        WorkbenchHelp.setHelp(radioButton[1], XMLBuilderContextIds.XMLC_CREATE_REQUIRED_AND_OPTION);
*/
      }

      // add the grammar specific generation options
      //
      {
        pageBook = new PageBook(containerGroup, SWT.NONE);
        pageBook.setLayoutData(new GridData(GridData.FILL_BOTH));
        xsdOptionsPanel = new XSDOptionsPanel(this, pageBook);
        dtdOptionsPanel = new DTDOptionsPanel(this, pageBook);
        pageBook.showPage(xsdOptionsPanel); 
      }
    }

    public void widgetSelected(SelectionEvent event)
    {
      int index = combo.getSelectionIndex();
      String rootElementName = (index != -1) ? combo.getItem(index) : null;
      generator.setRootElementName(rootElementName);
    }

    public void widgetDefaultSelected(SelectionEvent event)
    {
    }

    public void setVisible(boolean visible)
    {
      super.setVisible(visible);

      if (visible)
      {
        try
        {
          if (generator.getGrammarURI() == null)
          {
            generator.setGrammarURI(selectGrammarFilePage.getURI());
            generator.setXMLCatalogEntry(selectGrammarFilePage.getXMLCatalogEntry());
          }
          Assert.isNotNull(generator.getGrammarURI());    
                
          if (generator.getCMDocument() == null)
          {
            final String[] errorInfo = new String[2];
            final CMDocument[] cmdocs = new CMDocument[1];
            Runnable r = new Runnable()
              {
                public void run()
                {
                  cmdocs[0] = NewXMLGenerator.createCMDocument(generator.getGrammarURI(), errorInfo);
                }
              };
            org.eclipse.swt.custom.BusyIndicator.showWhile(Display.getCurrent(),r);

            generator.setCMDocument(cmdocs[0]);
            cmDocumentErrorMessage = errorInfo[1];     
          }    

          if (generator.getCMDocument() != null && cmDocumentErrorMessage == null)
          {
            CMNamedNodeMap nameNodeMap = generator.getCMDocument().getElements();
            Vector nameNodeVector = new Vector();

            for (int i = 0; i < nameNodeMap.getLength(); i++)
            {
              CMElementDeclaration cmElementDeclaration = (CMElementDeclaration)nameNodeMap.item(i);
              Object value =  cmElementDeclaration.getProperty("Abstract"); //$NON-NLS-1$
              if  (value !=  Boolean.TRUE)
              {
                nameNodeVector.add(cmElementDeclaration.getElementName());
              }
            }

            Object[] nameNodeArray = nameNodeVector.toArray();
            if (nameNodeArray.length > 0 )
            {
              Arrays.sort(nameNodeArray, Collator.getInstance());
            }

            String defaultRootName = (String) (generator.getCMDocument()).getProperty("http://org.eclipse.wst/cm/properties/defaultRootName"); //$NON-NLS-1$
            int defaultRootIndex = -1;
            combo.removeAll();


            for (int i = 0; i < nameNodeArray.length; i++)
            {
              String elementName = (String)nameNodeArray[i];

              combo.add(elementName);
              if (defaultRootName != null && defaultRootName.equals(elementName))
              {
                defaultRootIndex = i;
              }
            }
         
            if (nameNodeArray.length > 0)
            {
              defaultRootIndex = defaultRootIndex != -1 ? defaultRootIndex : 0;
              combo.select(defaultRootIndex);
              generator.setRootElementName(combo.getItem(defaultRootIndex));
            }
          }

          if (generator.getGrammarURI().endsWith("xsd")) //$NON-NLS-1$
          {                                       
            pageBook.showPage(xsdOptionsPanel); 
            generator.setDefaultSystemId(getDefaultSystemId());
            generator.createNamespaceInfoList();

            // Provide default namespace prefix if none
            for (int i=0; i<generator.namespaceInfoList.size(); i++)
            {
              NamespaceInfo nsinfo = 
                (NamespaceInfo)generator.namespaceInfoList.get(i);
              if ((nsinfo.prefix == null || nsinfo.prefix.trim().length() == 0)
                  && (nsinfo.uri != null && nsinfo.uri.trim().length() != 0))
              {
                nsinfo.prefix = getDefaultPrefix(generator.namespaceInfoList);
              }
            }
            xsdOptionsPanel.setNamespaceInfoList(generator.namespaceInfoList);
          }
          else if (generator.getGrammarURI().endsWith("dtd")) //$NON-NLS-1$
          {
            pageBook.showPage(dtdOptionsPanel);
            dtdOptionsPanel.update();
          }
        }   
        catch(Exception e)
        {
           //XMLBuilderPlugin.getPlugin().getMsgLogger().writeCurrentThread();
        }

        /*
        String errorMessage = computeErrorMessage();
        if (errorMessage == null) 
          super.setVisible(visible);
        */
        
        updateErrorMessage();
      }
    }
                            
    private String getDefaultPrefix(List nsInfoList)
    {
      String defaultPrefix = "p"; //$NON-NLS-1$
      if (nsInfoList == null)
        return defaultPrefix;

      Vector v = new Vector();
      for (int i=0; i<nsInfoList.size(); i++)
      {
        NamespaceInfo nsinfo = (NamespaceInfo)nsInfoList.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 boolean isPageComplete()
    {
      boolean complete = (generator.getRootElementName() != null && generator.getRootElementName().length() > 0) && getErrorMessage() == null;
      
      if (complete) {
      	/*
        int buildPolicy = radioButton[0].getSelection() ?
                          DOMContentBuilder.BUILD_ONLY_REQUIRED_CONTENT :
                          DOMContentBuilder.BUILD_ALL_CONTENT;
        */
        int buildPolicy = 0;
        if (radioButton[0].getSelection())
          buildPolicy = buildPolicy | DOMContentBuilder.BUILD_OPTIONAL_ATTRIBUTES;
        if (radioButton[1].getSelection())
          buildPolicy = buildPolicy | DOMContentBuilder.BUILD_OPTIONAL_ELEMENTS;
        if (radioButton[2].getSelection())
          buildPolicy = buildPolicy | DOMContentBuilder.BUILD_FIRST_CHOICE | DOMContentBuilder.BUILD_FIRST_SUBSTITUTION;
        if (radioButton[3].getSelection())
          buildPolicy = buildPolicy | DOMContentBuilder.BUILD_TEXT_NODES;
                    
        generator.setBuildPolicy(buildPolicy);
      }

      return complete;
    }

    public String computeErrorMessage()
    {
      String errorMessage = null;
               
      if (cmDocumentErrorMessage != null)
      {
        errorMessage = cmDocumentErrorMessage;                  
      }
      else if (generator.getRootElementName() == null || generator.getRootElementName().length() == 0)
      {
        errorMessage = XMLWizardsMessages._ERROR_ROOT_ELEMENT_MUST_BE_SPECIFIED;
      }                  

      return errorMessage;
    }


    public void updateErrorMessage()
    {
      String errorMessage = computeErrorMessage();
      if (errorMessage == null)
      { 
        if (xsdOptionsPanel.isVisible())
        {
          
          errorMessage = xsdOptionsPanel.computeErrorMessage();
        }
        else if (dtdOptionsPanel.isVisible())
        {
          errorMessage = dtdOptionsPanel.computeErrorMessage();
        }
      }
      setErrorMessage(errorMessage);
      setPageComplete(isPageComplete());
    }
  }
  ////////////////End SelectRootElementPage
  


  public static GridLayout createOptionsPanelLayout()
  {
    GridLayout gridLayout = new GridLayout();
    gridLayout.marginWidth = 0;
    gridLayout.horizontalSpacing = 0;
    return gridLayout;
  }
    

                    
  /**
   * 
   */
  class XSDOptionsPanel extends Composite
  {            
    protected String errorMessage = null;
    protected SelectRootElementPage parentPage;   
    protected CommonEditNamespacesDialog editNamespaces;

    public XSDOptionsPanel(SelectRootElementPage parentPage, Composite parent)
    {
      super(parent, SWT.NONE);
      this.parentPage = parentPage;
                                                                            
      setLayout(createOptionsPanelLayout());                                 
      setLayoutData(new GridData(GridData.FILL_BOTH));             
                                
      Composite co = new Composite(this, SWT.NONE);
      co.setLayout(new GridLayout());
	 
      if (newFilePage != null && newFilePage.getContainerFullPath() != null)
      {
        // todo... this is a nasty mess. I need to revist this code.
        //
        String resourceURI = "platform:/resource" + newFilePage.getContainerFullPath().toString() + "/dummy"; //$NON-NLS-1$ //$NON-NLS-2$
        String resolvedPath = URIHelper.normalize(resourceURI, null, null);
        if (resolvedPath.startsWith("file:/")) //$NON-NLS-1$
        {
          resolvedPath = resolvedPath.substring(6);
        }
        // end nasty messs
        String tableTitle = XMLWizardsMessages._UI_LABEL_NAMESPACE_INFORMATION;
        editNamespaces = new CommonEditNamespacesDialog(co, new Path(resolvedPath), tableTitle, true, true);
      }

      UpdateListener updateListener = new UpdateListener()
      {
        public void updateOccured(Object object, Object arg)
        { 
          updateErrorMessage((List)arg);
        }
      };
    }
    
    public void setNamespaceInfoList(List list)
    {                   
      editNamespaces.setNamespaceInfoList(list);   
      editNamespaces.updateErrorMessage(list);                      
    }    
    
    public void updateErrorMessage(List namespaceInfoList)
    {        
      NamespaceInfoErrorHelper helper = new NamespaceInfoErrorHelper();
      errorMessage = helper.computeErrorMessage(namespaceInfoList, null);
      parentPage.updateErrorMessage();
    }
  
    
    public String computeErrorMessage()
    {             
      return errorMessage;
    }   
  }    


  /**
   * 
   */
  public class DTDOptionsPanel extends Composite implements ModifyListener
  {
    protected Group group;
    protected Text systemIdField;
    protected Text publicIdField;
    protected SelectRootElementPage parentPage;

    public DTDOptionsPanel(SelectRootElementPage parentPage, Composite parent)
    {
      super(parent, SWT.NONE);
      this.parentPage = parentPage;
      setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

      setLayout(createOptionsPanelLayout());
      Group group = new Group(this, SWT.NONE);
      group.setText(XMLWizardsMessages._UI_LABEL_DOCTYPE_INFORMATION);
      //WorkbenchHelp.setHelp(group, XMLBuilderContextIds.XMLC_DOCUMENTATION_GROUP);
      
      GridLayout layout = new GridLayout();
      layout.numColumns = 2;
      group.setLayout(layout);
      group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                  
      Label publicIdLabel = new Label(group, SWT.NONE);
      publicIdLabel.setText(XMLWizardsMessages._UI_LABEL_PUBLIC_ID);
      publicIdField = new Text(group, SWT.SINGLE | SWT.BORDER);
      publicIdField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      publicIdField.addModifyListener(this);
      //WorkbenchHelp.setHelp(publicIdField, XMLBuilderContextIds.XMLC_PUBLIC);
      
      Label systemIdLabel = new Label(group, SWT.NONE);
      systemIdLabel.setText(XMLWizardsMessages._UI_LABEL_SYSTEM_ID);
      systemIdField = new Text(group, SWT.SINGLE | SWT.BORDER);
      systemIdField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      systemIdField.addModifyListener(this);
      //WorkbenchHelp.setHelp(systemIdField, XMLBuilderContextIds.XMLC_SYSTEM);      
    }
    
    public void update()
    {                           
      String thePublicId = null;                              
      String theSystemId = null;
      XMLCatalogEntry xmlCatalogEntry = generator.getXMLCatalogEntry();

      if (xmlCatalogEntry != null)
      {
        if (xmlCatalogEntry.getType() == XMLCatalogEntry.PUBLIC)
        {
          thePublicId = xmlCatalogEntry.getKey();
          theSystemId = xmlCatalogEntry.getWebAddress();
          if (theSystemId == null)
          {
            theSystemId = generator.getGrammarURI().startsWith("http:") ? generator.getGrammarURI() : URIHelper.getLastSegment(generator.getGrammarURI()); //$NON-NLS-1$
          }  
        }                                          
        else
        {
          theSystemId = xmlCatalogEntry.getKey();
        }  
      }                                     
      else
      {
        theSystemId = getDefaultSystemId();
      }                                    
                                                                    
      publicIdField.setText(thePublicId != null ? thePublicId : ""); //$NON-NLS-1$
      systemIdField.setText(theSystemId != null ? theSystemId : ""); //$NON-NLS-1$
    }      

    public void modifyText(ModifyEvent e)
    {
      generator.setSystemId(systemIdField.getText());
      generator.setPublicId(publicIdField.getText());
      parentPage.updateErrorMessage();
    }

    public String computeErrorMessage()
    {
      return null;
    }
  }


}
