/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Denise Smith - 2.5.1 - Initial Implementation
 ******************************************************************************/
package org.eclipse.persistence.internal.oxm;

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

import org.eclipse.persistence.internal.core.queries.CoreContainerPolicy;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.VariableXPathCollectionMapping;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;

import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType;

public class XMLVariableXPathCollectionMappingNodeValue extends XMLVariableXPathMappingNodeValue implements ContainerValue{

	VariableXPathCollectionMapping mapping;
	private int index = -1;


    public XMLVariableXPathCollectionMappingNodeValue(VariableXPathCollectionMapping variableXPathCollectionMapping) {
    	mapping= variableXPathCollectionMapping;
    }

	@Override
	protected void setOrAddAttributeValue(UnmarshalRecord unmarshalRecord,
			Object value, XPathFragment xPathFragment, Object collection) {	    
            unmarshalRecord.addAttributeValue(this, value);       	     		              
	}

	@Override
	public VariableXPathCollectionMapping getMapping() {
		return mapping;
	}

	@Override
	public boolean marshal(XPathFragment xPathFragment,
			MarshalRecord marshalRecord, Object object,
			CoreAbstractSession session, NamespaceResolver namespaceResolver) {
		if (mapping.isReadOnly()) {
            return false;
        }
        CoreContainerPolicy cp = mapping.getContainerPolicy();
        Object collection = mapping.getAttributeAccessor().getAttributeValueFromObject(object);
        if (null == collection) {
            AbstractNullPolicy wrapperNP = mapping.getWrapperNullPolicy();
            if (wrapperNP != null && wrapperNP.getMarshalNullRepresentation().equals(XMLNullRepresentationType.XSI_NIL)) {
                marshalRecord.nilSimple(namespaceResolver);
                return true;
            } else {
                return false;
            }
        }
        
        
        Object iterator = cp.iteratorFor(collection);
        if (null != iterator && cp.hasNext(iterator)) {
            XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
            marshalRecord.closeStartGroupingElements(groupingFragment);
        } else {
        	return marshalRecord.emptyCollection(xPathFragment, namespaceResolver, mapping.getWrapperNullPolicy() != null);
        }
        
        
        if(marshalRecord.getMarshaller().getMediaType().isApplicationJSON()){
            List<XPathFragment> frags = new ArrayList();
            List<List> values = new ArrayList<List>();
            List mixedValues = new ArrayList();
            
            //sort the elements. Results will be a list of xpathfragments and a corresponding list of 
            //collections associated with those xpathfragments
            XPathFragment xmlRootFragment;
            while(cp.hasNext(iterator)) {        	    
        	    
                Object nextValue = cp.next(iterator, session);
                nextValue = mapping.convertObjectValueToDataValue(nextValue, session, marshalRecord.getMarshaller());
                XPathFragment frag = mapping.getXPathFragmentForValue(nextValue, marshalRecord.getNamespaceResolver(), marshalRecord.isNamespaceAware(), marshalRecord.getNamespaceSeparator());
                if(frag != null){    
                	
                        int index = frags.indexOf(frag);
        	            if(index > -1){
        	    	        values.get(index).add(nextValue);
        	            }else{
                            frags.add(frag);
        	    	        List valuesList = new ArrayList();
        	    	        valuesList.add(nextValue);
        	    	        values.add(valuesList);
        	            }
                    }
        	     
            }
           
            for(int i =0;i < frags.size(); i++){
            	XPathFragment nextFragment = frags.get(i);            	
            	List listValue = values.get(i);            	
            	
                if(nextFragment != null){
                   int valueSize = listValue.size();
                   if(valueSize > 1 ){
                        marshalRecord.startCollection();
                   }
                 
                    for(int j=0;j<valueSize; j++){              	          
                    	marshalSingleValue(nextFragment, marshalRecord, object, listValue.get(j), session, namespaceResolver, ObjectMarshalContext.getInstance());
                    }
                
                    if(valueSize > 1 ){
                        marshalRecord.endCollection();
                    }
                }            
            } 
        } else{
        

	   Object objectValue;	      
	   while (cp.hasNext(iterator)) {
	        objectValue = cp.next(iterator, session);
	        objectValue = mapping.convertObjectValueToDataValue(objectValue, session, marshalRecord.getMarshaller());
	        marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, ObjectMarshalContext.getInstance());
	    }
       } 

	    return true;
	}
    
	public Object getContainerInstance() {
        return getContainerPolicy().containerInstance();
    }

    public void setContainerInstance(Object object, Object containerInstance) {
        mapping.setAttributeValueInObject(object, containerInstance);
    }

    public CoreContainerPolicy getContainerPolicy() {
        return mapping.getContainerPolicy();
    }

    public boolean isContainerValue() {
        return true;
    }

	@Override
	public boolean getReuseContainer() {
		return mapping.getReuseContainer();	}

	@Override
	public int getIndex() {
		return index;
	}

	@Override
	public boolean isDefaultEmptyContainer() {
		return mapping.isDefaultEmptyContainer();
	}

	@Override
	public boolean isWrapperAllowedAsCollectionName() {
		return false;
	}

	@Override
	public void setIndex(int index) {
		this.index = index;
		
	}
	
	@Override
    public boolean isMixedContentNodeValue() {
	     return true;
	}
    
}
