/*******************************************************************************
 * Copyright (c) 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.xsd.ui.internal.dialogs.types.xsd;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.wst.xsd.ui.internal.XSDEditorPlugin;
import org.eclipse.wst.xsd.ui.internal.dialogs.types.common.IComponentList;
import org.eclipse.wst.xsd.ui.internal.dialogs.types.xml.XMLComponentFinder;
import org.eclipse.wst.xsd.ui.internal.dialogs.types.xml.XMLComponentSelectionProvider;
import org.eclipse.wst.xsd.ui.internal.dialogs.types.xml.XMLComponentSpecification;
import org.eclipse.wst.xsd.ui.internal.util.TypesHelper;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDInclude;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.XSDRedefine;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaContent;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.impl.XSDImportImpl;
import org.eclipse.xsd.util.XSDConstants;

/*
 *
 */
public class XSDComponentSelectionProvider extends XMLComponentSelectionProvider {
    private XSDComponentFinder xsdComponentFinder;
    private XSDComponentSelectionDialog dialog;
    private XSDSchema schema;
    private XSDComponentLabelProvider labelProvider;
    
    private boolean showComplexTypes = true;
    
    /*
     * Takes in the IFile we are currently editing.
     */
    public XSDComponentSelectionProvider(IFile file, XSDSchema schema) {
        xsdComponentFinder = new XSDComponentFinder();
        xsdComponentFinder.setFile(file);
        this.schema = schema;
        labelProvider = new XSDComponentLabelProvider();
    }
    
    public void setDialog(XSDComponentSelectionDialog dialog) {
        this.dialog = dialog;
    }
    
    public void showComplexTypes(boolean show) {
        showComplexTypes = show;
    }
    
    public String getType(Object element) {
        return null;
    }
        
    /*
     * The return value is a List of XMLComponentTreeObjects.
     * 
     */
	public void getComponents(IComponentList list, boolean quick) {
	    if (quick) {
            // Populate IComponentList list with components most easily accessible (fastest)
            // Grab Built-In types
            Iterator builtInIt = getBuiltInTypes().iterator();
            while (builtInIt.hasNext()) {
                XMLComponentSpecification tagItem = (XMLComponentSpecification) builtInIt.next();
                addDataItemToTreeNode(list, tagItem);
            }
            
            // Create current Schema's complex and simple types
            createComplexTypes(list);
            createSimpleTypes(list);
        }
        else {
            getComponents(list);
        }
	}
    
    /*
     * TODO: Need to revisit how we build up our treeObject list.... 
     * And it's somewhat messy, clean this up.
     */
    private void getComponents(IComponentList list) {
        List extensions = new ArrayList();
        extensions.add("xsd");
        
        String scope = "";
        if (dialog != null) {
            scope = dialog.getSearchScope();
        }
        
        List comps = new ArrayList();
        if (scope.equals(XSDComponentSelectionDialog.SCOPE_ENCLOSING_PROJECT)) {
            comps = xsdComponentFinder.getWorkbenchResourceComponents(XMLComponentFinder.ENCLOSING_PROJECT_SCOPE);
        }
        else if (scope.equals(XSDComponentSelectionDialog.SCOPE_WORKSPACE)) {
            comps = xsdComponentFinder.getWorkbenchResourceComponents(XMLComponentFinder.ENTIRE_WORKSPACE_SCOPE);            
        }
        
//      Group same item types together (simple/complex)
        List complex = new ArrayList();
        List simple = new ArrayList();
        Iterator itemsIterator = comps.iterator();
        while (itemsIterator.hasNext()) {
            XMLComponentSpecification tagItem = (XMLComponentSpecification) itemsIterator.next();
            if (tagItem.getTagPath().equals("/schema/complexType")) {
                complex.add(tagItem);
            }               
            else if (tagItem.getTagPath().equals("/schema/simpleType")) {
                simple.add(tagItem);
            }
        }
        
        Iterator complexIt = complex.iterator();
        Iterator simpleIt = simple.iterator();
        if (showComplexTypes) {
            while (complexIt.hasNext()) {
                XMLComponentSpecification item = (XMLComponentSpecification) complexIt.next();
                addDataItemToTreeNode(list, item);
            }
        }
        
        while (simpleIt.hasNext()) {
            XMLComponentSpecification item = (XMLComponentSpecification) simpleIt.next();
            addDataItemToTreeNode(list, item);
        }
        
        // Create from imports, includes, and redefines
        createFromImport(list);
        createFromInclude(list);
        createFromRedefine(list);
    }
    
////////////////////////////////////////////////////////////////////////////////    
    private List getBuiltInTypes() {
        TypesHelper helper = new TypesHelper(schema);
        Iterator it = helper.getBuiltInTypeNamesList().iterator();
        
        List builtInComponentSpecs = new ArrayList();
        while (it.hasNext()) {
            Object item = it.next();
            String itemString = item.toString();
            
            XMLComponentSpecification builtInTypeItem = new XMLComponentSpecification("BUILT_IN_SIMPLE_TYPE");
            builtInTypeItem.addAttributeInfo("name", itemString);
            builtInTypeItem.setTargetNamespace(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001);
//            String normalizedFile = getNormalizedLocation(schema.getSchemaLocation());
//            builtInTypeItem.setFileLocation(normalizedFile);
            builtInTypeItem.setFileLocation("Built-In");
            
            builtInComponentSpecs.add(builtInTypeItem);
        }
        
        return builtInComponentSpecs;
    }

    private void createComplexTypes(IComponentList treeObjectList) {
        TypesHelper typesHelper = new TypesHelper(schema);
        List complexTypes = typesHelper.getUserComplexTypes();
        createComplexSimpleTreeObject(treeObjectList, complexTypes, true);
    }
    
    private void createSimpleTypes(IComponentList treeObjectList) {
        TypesHelper typesHelper = new TypesHelper(schema);
        List complexTypes = typesHelper.getUserSimpleTypes();
        createComplexSimpleTreeObject(treeObjectList, complexTypes, true);
    }

    
    private void createFromImport(IComponentList treeObjectList) {
        Iterator imports = getXSDImports().iterator();
        while (imports.hasNext()) {
            XSDImport importItem = (XSDImport) imports.next();
            if (importItem.getSchemaLocation() != null) {
                ((XSDImportImpl) importItem).importSchema();
                TypesHelper helper = new TypesHelper(importItem.getResolvedSchema());
                
                List types = helper.getUserComplexTypes();
                types.addAll(helper.getUserSimpleTypes());
                createComplexSimpleTreeObject(treeObjectList, types, false);
            }
        }
    }
    
        private void createFromInclude(IComponentList treeObjectList) {
        Iterator imports = getXSDIncludes().iterator();
        while (imports.hasNext()) {
            XSDInclude includeItem = (XSDInclude) imports.next();
            if (includeItem.getSchemaLocation() != null) {
                TypesHelper helper = new TypesHelper(includeItem.getResolvedSchema());  
                
                List types = helper.getUserComplexTypes();
                types.addAll(helper.getUserSimpleTypes());
                createComplexSimpleTreeObject(treeObjectList, types, false);
            }
        }
    }
    
    private void createFromRedefine(IComponentList treeObjectList) {
        Iterator redefines = getXSDRedefines().iterator();
        while (redefines.hasNext()) {
            XSDRedefine redefineItem = (XSDRedefine) redefines.next();
            if (redefineItem.getSchemaLocation() != null) {
                TypesHelper helper = new TypesHelper(redefineItem.getResolvedSchema());
                
                List types = helper.getUserComplexTypes();
                types.addAll(helper.getUserSimpleTypes());
                createComplexSimpleTreeObject(treeObjectList, types, false);
            }
        }
    }
    
        protected List getXSDImports() {
        List imports = new ArrayList();
        
        Iterator contents = schema.getContents().iterator();
        while (contents.hasNext()) {
            XSDSchemaContent content = (XSDSchemaContent) contents.next();
            if (content instanceof XSDImport) {
                imports.add(content);             
            }
        }
        
        return imports;
    }
    
    protected List getXSDIncludes() {
        List includes = new ArrayList();
        
        Iterator contents = schema.getContents().iterator();
        while (contents.hasNext()) {
            XSDSchemaContent content = (XSDSchemaContent) contents.next();
            if (content instanceof XSDInclude) {
                includes.add(content);            
            }
        }
        
        return includes;
    }

    protected List getXSDRedefines() {
        List includes = new ArrayList();
        
        Iterator contents = schema.getContents().iterator();
        while (contents.hasNext()) {
            XSDSchemaContent content = (XSDSchemaContent) contents.next();
            if (content instanceof XSDRedefine) {
                includes.add(content);            
            }
        }
        
        return includes;
    }

    private void createComplexSimpleTreeObject(IComponentList treeObjectList, List complexTypes, boolean sameNS) {
        boolean proceed = true;
        
        for (int i = 0; i < complexTypes.size(); i++) {
            XSDNamedComponent item = (XSDNamedComponent) complexTypes.get(i); 
        
            if (sameNS) {
                // We do this check because Types from Includes might show up.  However, we don't want to show them
                String itemLocation = item.getSchema().getSchemaLocation();
                String currentSchemaLocation = schema.getSchemaLocation();
                if (itemLocation != null) {
                    proceed = itemLocation.equals(currentSchemaLocation);
                }
                else {
                    proceed = false;
                }
            }
            
            if (proceed) {
                XMLComponentSpecification typeItem =  null;
                if (showComplexTypes && item instanceof XSDComplexTypeDefinition) {
                    typeItem = new XMLComponentSpecification("/schema/complexType");
                    typeItem.addAttributeInfo("name", ((XSDComplexTypeDefinition) item).getName());
                }
                else if (item instanceof XSDSimpleTypeDefinition) {
                    typeItem = new XMLComponentSpecification("/schema/simpleType");
                    typeItem.addAttributeInfo("name", ((XSDSimpleTypeDefinition) item).getName());
                }
                
                if (typeItem != null) {
                    typeItem.setTargetNamespace(item.getTargetNamespace());
                    String normalizedFile = getNormalizedLocation(schema.getSchemaLocation());
                    typeItem.setFileLocation(normalizedFile);
    
                    addDataItemToTreeNode(treeObjectList, typeItem);
                }
            }
        }
    }

    
	public ILabelProvider getLabelProvider() {
		return labelProvider;
	}

    
    public class XSDComponentLabelProvider extends XMLComponentSelectionLabelProvider {
        public Image getImage(Object element) {
            XMLComponentTreeObject specification = (XMLComponentTreeObject) element;
            XMLComponentSpecification spec = (XMLComponentSpecification) specification.getXMLComponentSpecification().get(0);
            if (spec.getTagPath().equals("/schema/complexType")) {
                return XSDEditorPlugin.getXSDImage("icons/XSDComplexType.gif");
            }
            else if (spec.getTagPath().equals("/schema/simpleType")) {
                return XSDEditorPlugin.getXSDImage("icons/XSDSimpleType.gif");
            }
            else if (spec.getTagPath().equals("BUILT_IN_SIMPLE_TYPE")) {
                return XSDEditorPlugin.getXSDImage("icons/XSDSimpleType.gif");
            }
    
            return null;
        }
    }
    
    

	public String getListTitle() {
		return "Matching Types:";
	}

	public String getNameFieldTitle() {
		return "Type Name:";
	}
}
