////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////


package mx.olap
{

import flash.utils.Dictionary;

import mx.collections.IList;

/**
* @private
*/
public class CubeNodeBuilder
{
    include "../core/Version.as";
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    
    private var prevNodeAtLevel:Array; // of CubeNodes
    private var allNodeAtLevel:Array;  // of CubeNodes
    private var prevValueAtLevel:Array;
    
    // the level at which the new property is going to be placed
    private var currentLevel:int; 
    
    private var prevLevel:int;
    private var nextLevel:int;
    
    //the nodes whose values are going to be aggregated as the above node
    //value has changed.
    private var closingNodesBelow:Array;
    private var closingValues:Array;
    
    //list of measures in the cube
    private var measureMembers:IList;
    private var measuresLength:int ;
    
    /**
    *  @private
    *  Maps containing nodes which need to be passed to the aggrgator
    *  to compute the final result. The measure object is used as a key. 
    *  
    */
    // simple aggregation map 
    private var computeEndMap:Dictionary = new Dictionary(false);
	
	//aggregation of aggregations map
    private var computeObjEndMap:Dictionary = new Dictionary(false);

	private var measureMap:Object = {};
	
	/**
	 *  @private
	 *  An array of properites in the rootNode.
	 *  This is used to aggregate each property asychronously
	 *  to avoid player time out.
	 *  
	 */
	private var rootCellValues:Array;
    
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
    
    private var _cube:OLAPCube;
    
    public function set cube(c:IOLAPCube):void
    {
        _cube = c as OLAPCube;
    }
    
    /**
    * The top most node of the cube. 
    * All navigations begin from this node.  
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    public var rootNode:CubeNode;
    
    /**
    * The property name used to refer to the property
    * pointing at the aggregation of nodes below a CubeNode  
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    public var allNodePropertyName:String ="(All)";

    /**
    * Indicates the last level of data other than measures.
    * This is used to read the measure values from the data item
    * when processing reaches this level.
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */ 
    public var levelPreviousToMeasuresIndex:int;

	//total number of nodes in the cube. (used for perf improvement analysis)
    //private var totalNodes:int;
    
    //count of cubes collapsed (used for perf improvement analysis)
    //private var nodesUpdated:int;
    
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------
    
    /**
    * Starts the process of building the cube by initializing
    * the members.
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    public function initNodeBuilding():void
    {
        prevNodeAtLevel = [];
        allNodeAtLevel = [];
        prevValueAtLevel = [];
        
        //compute for all the measures
        measureMembers = _cube.findDimension("Measures").members;
        
        measuresLength = measureMembers.length; 
        for each (var measure:OLAPMeasure in measureMembers)
        {
            computeEndMap[measure] = [];
            computeObjEndMap[measure] = [];
            measureMap[measure.name] = measure;
        }
    }

	/**
	 * Instructs the builder to start processing the next data item. 
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
    public function moveToNextRound():void
    {
        currentLevel = 0;
        prevLevel = -1;
        nextLevel = 1;
    }
    
    /**
    * Finalizes building the cube by computing aggregations at all nodes. 
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    public function completeNodeBuilding():Boolean
    {
    	if (prevNodeAtLevel && prevValueAtLevel)
	    {
	    	// close all nodes pending
	        //TODO initializing rootNode twice
	        rootNode = prevNodeAtLevel[0];
	        closingNodesBelow = prevNodeAtLevel.reverse();
	        closingValues = prevValueAtLevel.reverse();
	        
	        var tempLevel:int = closingNodesBelow.length - 1;
	        var n:int = closingNodesBelow.length;
	        for (var i:int = 0; i < n; ++i)
	        {
	            if (tempLevel < 1)
	                continue;
	            var closingValue:Object = closingValues[i];
	            //OLAPTrace.traceMsg("Closing value:" + closingValues[i], //OLAPTrace.TRACE_LEVEL_2);
	            var closingNode:Object = closingNodesBelow[i];
	            if (closingNode[closingValue] is CubeNode)
	            {
	                if (closingNode[allNodePropertyName] is CubeNode)
	                {
	                	//if there are is only one property (other than (all) ) we short circuit
	                	if (closingNode.numCells == 2)
	                		closingNode[allNodePropertyName] = closingNode[closingValue];
	                	else
		                	accumValuesFromNode(closingNode[allNodePropertyName], closingNode[closingValue]);
	                }
	            }
	
	            --tempLevel;
	        }
	        
			prevNodeAtLevel = null;
			prevValueAtLevel = null;
			allNodeAtLevel = null;
			
			rootCellValues = [];
	        for (var rootCell:String in rootNode)
    	    {
        	    if (rootCell == allNodePropertyName)
            	    continue;
            	rootCellValues.push(rootCell);	 
         	}
         	return false;
    	}
        
        //aggregate the top node
        while(rootCellValues.length)
        {
        	rootCell = rootCellValues.pop();
            // can we accumulate everything from the tree to the all tree here?
            accumValuesFromNode(rootNode[allNodePropertyName], rootNode[rootCell]);
            return false;
        }

		//finalize all aggregation computation
        var temp:Array;
        var y:Object;
		var measure:OLAPMeasure;
		var aggregator:IOLAPCustomAggregator;
        for (var x:Object in computeEndMap)
        {
			measure = x as OLAPMeasure;
        	aggregator = measure.aggregator as IOLAPCustomAggregator;
            temp = computeEndMap[x];
            for each (y in temp)
            {
                y["saved_" + measure.name] = y[measure.name];
                y[measure.name] = aggregator.computeEnd(y[measure.name], measure.dataField);
            }
			delete computeEndMap[x];
        }

        for (x in computeObjEndMap)
        {
			measure = x as OLAPMeasure;
        	aggregator = measure.aggregator as IOLAPCustomAggregator;
            temp = computeObjEndMap[x];
            for each (y in temp)
            {
                y["saved_"+measure.name] = y[measure.name];
                y[measure.name] = aggregator.computeObjectEnd(y[measure.name], measure.dataField);
            }
			delete computeObjEndMap[x];
        }

		computeEndMap = new Dictionary(false);
		computeObjEndMap = new Dictionary(false);
		
		//collapse CubeNodes which have only one property
		//The aggregation property would point to the single property itself
		optimizeCube();
		
		return true;
    }
    
    /**
    * Adds a new value to the cube. If the value is different from the previous value
    * at the current level adds the new value as a property to the CubeNode and creates
    * a new CubeNode below. Also creates a CubeNode for aggregating the properties in the
    * new CubeNode. 
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    public function addValueToNodeBuilder(values:Object, currentData:Object):void
    {
    	var i:int = 0;
    	for each(var value:Object in values) 
        {
	        // decide whether to create a new node or use the previous node
	        var prevNode:CubeNode = prevNodeAtLevel[currentLevel];
	        var prevValue:Object = prevValueAtLevel[currentLevel];
	        var closingValue:Object;
	        var closingNode:Object
	        
	        if (prevValue)
	        {
	            if (prevValue == value)
	            {
	                // continue to process the same value
	                // update nodes
	                //OLAPTrace.traceMsg("Continue with value:" + prevValue, OLAPTrace.TRACE_LEVEL_2);
	            }
	            else
	            {
	                // no more processing of this value.
	                // time to compute update all nodes etc
	                
	                // close all nodes below this node
	                closingNodesBelow = prevNodeAtLevel.splice(nextLevel).reverse();
	                closingValues = prevValueAtLevel.splice(nextLevel).reverse();
	                var tempLevel:int = currentLevel + closingNodesBelow.length;
	                var closingNodeLength:int = closingNodesBelow.length;
	                for (i= 0; i < closingNodeLength; ++i)
	                {
	                	if (tempLevel != 0)
	                    {
		                    closingValue = closingValues[i];
	    	                //OLAPTrace.traceMsg("Closing value:" + closingValues[tempIndex], OLAPTrace.TRACE_LEVEL_2);
	        	            closingNode = closingNodesBelow[i];
	            	        if (closingNode[closingValue] is CubeNode)
	                	    {
	                        	if (closingNode[allNodePropertyName] is CubeNode)
	                            {
	                            	if (tempLevel > currentLevel && closingNode.numCells == 2)
	                            		closingNode[allNodePropertyName] = closingNode[closingValue];
	                            	else
	                           	 		accumValuesFromNode(closingNode[allNodePropertyName], closingNode[closingValue]);
	                            }
	    	                }
	    	           	}
	                    
	                    --tempLevel;
	                }
	                
	                //OLAPTrace.traceMsg("Closing value:" + prevValue, //OLAPTrace.TRACE_LEVEL_2);
	                closingValue = prevValue;
	                closingNode = prevNode;
	                if (currentLevel != 0 && closingNode[closingValue] is CubeNode)
	                {
	                    if (closingNode[allNodePropertyName] is CubeNode)
	                        accumValuesFromNode(closingNode[allNodePropertyName], closingNode[closingValue]);
	                }
	                
	                //OLAPTrace.traceMsg("New value:" + value, //OLAPTrace.TRACE_LEVEL_2);
	            }
	        }
	        
	        
	        if (!prevNode)
	        {   
	            //OLAPTrace.traceMsg("Creating new node: " + value, //OLAPTrace.TRACE_LEVEL_2);
	            // - create a new node, put the pointer to the ALL node, add new key to the ALL node
	            var newNode:CubeNode = new CubeNode(currentLevel);
	            
	            // create a all node to summaries the cells of this node
	            newNode[allNodePropertyName] = new CubeNode(currentLevel+1);
	            ++newNode.numCells; 
	            
	            //TODO initializing rootNode twice
	            if (currentLevel == 0 && prevNodeAtLevel.length == 0)
	                rootNode = newNode;
	            
	            prevNodeAtLevel[currentLevel] = newNode;
		
		        var allNode:CubeNode = allNodeAtLevel[currentLevel];
	            if (!allNode)
	            {
	                // for the top most level we would have only one node
	                // which is also the all node
	                // for other levels we have one node which is a all node
	                // containing aggr value of all cells in the nodes at that level
	                if (currentLevel > 0)
	                {
	                    allNodeAtLevel[currentLevel] = allNode = new CubeNode(currentLevel);
	                    allNode[allNodePropertyName] = {};
	                    allNodeAtLevel[prevLevel][allNodePropertyName] = allNode;
	                    ++allNode.numCells;
	                }
	                else
	                {   
	                    // special case of zero level
	                    allNodeAtLevel[currentLevel] = newNode;
	                }
	            }
	
	            prevNode = newNode;                     
	        }
	        else
	        {
	            // add a new cell/property to the previous node if it doesn't exist
	            if (!prevNode.hasOwnProperty(value))
	            {   
	                prevNodeAtLevel.splice(nextLevel);
	                prevValueAtLevel.splice(nextLevel);
	            }
	        }
	
	        // are we at the last level?
	        // if so we take up measures computation
	        if (currentLevel == levelPreviousToMeasuresIndex)
	        {
	            if (!prevNode.hasOwnProperty(value))
	            {
	            	prevNode[value] = new SummaryNode;
	            	++prevNode.numCells;
	            }
	            var temp:Object;
	            if (prevNode[allNodePropertyName] is CubeNode || prevNode[allNodePropertyName] is Number)
	            {
	            	temp = prevNode[allNodePropertyName] = new SummaryNode;
	            }
	            else
	            {
	                temp = prevNode[allNodePropertyName];
	            }
	            
				for (i = 0; i < measuresLength; ++i)
	            {   
					var measureMember:OLAPMember = measureMembers.getItemAt(i) as OLAPMember;
	                var newDataValue:Object = currentData[measureMember.dataField];
					
					//force convertion of measure value to a number.
					//xml dataType runs into problems with value of 0
					if (typeof(newDataValue) == "xml")
						newDataValue = Number(newDataValue.toString());
					newDataValue = Number(newDataValue);
	                addValueToNode(prevNode[value], measureMember.name, newDataValue, measureMember as OLAPMeasure, currentData);
	                addValueToNode(temp, measureMember.name, newDataValue, measureMember as OLAPMeasure, currentData);
	            }
	        }
	        
	        // make the node at previous level point to the node
	        if (currentLevel > 0)
	        {
	            var prevLevelNode:Object = prevNodeAtLevel[prevLevel];
	            if (!prevLevelNode.hasOwnProperty(prevValueAtLevel[prevLevel]))
	            {   
	                var prevLevelValue:Object = prevValueAtLevel[prevLevel];
	                prevLevelNode[prevLevelValue] = newNode;
					++prevLevelNode.numCells;
	            }
	        }
	
	        prevValueAtLevel[currentLevel] = value;
	        ++prevLevel;
	        ++currentLevel;
	        ++nextLevel;
	    }
    }
    
    /**
     *  @private
     */
    private function optimizeCube():void
    {
    	var total:int =0;
    	//totalNodes = 0;
    	//nodesUpdated = 0;
    	//start from root node and count the number of nodes which have only one cell.
    	//skip the allValue because we are not updating the numCells there.
    	if (rootNode)
	    	total = findNodeWithOneCell(rootNode);
    	//trace(nodesUpdated + "/" + total + "/" + totalNodes);
    }
    
    /**
    *  @private
    *  Recursively collapses CubeNodes
    *  
    */
    private function findNodeWithOneCell(node:CubeNode):int
    {
    	//++totalNodes;
    	var total:int = 0;
    	if (node.numCells == 2)
    		++total;
    	for (var p:String in node)
    	{
    		//if (x == allNodePropertyName)
    		//	continue;
    		if (node.numCells == 2)
    		{
    			if (node[allNodePropertyName] != node[p])
    			{
    				delete node[allNodePropertyName];
	    			node[allNodePropertyName] = node[p];
    				//++nodesUpdated;
    			}
    		}
    			
    		var cNode:CubeNode = node[p] as CubeNode;
    		if (cNode)
    		{
    			total += findNodeWithOneCell(cNode);
    		}
    	}
		return total;
    }
    
    /**
    *  @private
    *  Adds a measure value to the node. 
    *  Invokes aggregator functions to compute the value.
    *  
    */
    private function addValueToNode(node:Object, name:String, 
                        value:Object, measure:OLAPMeasure, rowData:Object):void
    {
    	var aggregator:IOLAPCustomAggregator;
        
        //if the value is a number we need to compute the summary.
        if (value is Number)
        {
        	aggregator = measure.aggregator as IOLAPCustomAggregator;
            if (!node.hasOwnProperty(name))
            {
                node[name] = aggregator.computeBegin(measure.dataField);
                computeEndMap[measure].push(node);
                aggregator.computeLoop(node[name], measure.dataField, /*value,*/ rowData);
            }
            else
            {
                aggregator.computeLoop(node[name], measure.dataField, /*value,*/ rowData);
            }
        }
        else
        {
            var temp:Object;
            if (!node.hasOwnProperty(name))
            {
                node[name] = temp = new SummaryNode;
                ++node.numCells;
                for (var p:String in value)
                {
                    measure = measureMap[p];
	            	aggregator = measure.aggregator as IOLAPCustomAggregator;
                    if (temp.hasOwnProperty(p))
                    {
                        aggregator.computeObjectLoop(temp[p], value[p]);
                    }
                    else
                    {
                        temp[p] = aggregator.computeObjectBegin(value[p]);
                        computeObjEndMap[measure].push(temp);
                    }
                }
            }
            else
            {
                if (value is SummaryNode && !(node[name] is SummaryNode))
                {
                	var incr:Boolean = false;
                	if (!node.hasOwnProperty(name))
	                	incr = true;
                	temp = node[name] = new SummaryNode;
                	if (incr)
                		++node.numCells;
                }
                else
                {
                    temp = node[name];
                }

                for (p in value)
                {
                    measure = measureMap[p];
	            	aggregator = measure.aggregator as IOLAPCustomAggregator;
                    if (temp.hasOwnProperty(p))
                    {
                        aggregator.computeObjectLoop(temp[p], value[p]);
                    }
                    else
                    {   
                        temp[p] = aggregator.computeObjectBegin(value[p]);
                        computeObjEndMap[measure].push(temp);
                    }
                }
            }
        }
    }
    
    /**
    *  @private
    *  Aggregates all property values from source to target objects recursively.
    *  
    */
    private function accumValuesFromNode(target:Object, 
                                source:Object):void
    {
        for (var p:String in source)
	    {
	    	if (p == allNodePropertyName)
	    	{
				continue;
	    	}
            var value:Object = source[p];
        	if (value is CubeNode)
        	{
                var newNode:CubeNode;
                if (target[p] is CubeNode)
                {
                    newNode = target[p];
                }
                else
                {
                	target[p] = newNode = new CubeNode(value.level);
                	++target.numCells;
                }    
                accumValuesFromNode(newNode, value);
            }
            else
            {
            	addValueToNode(target, p, value, null, null);
            }  
        }

        if (target.numCells == 1)
        {
        	for (p in target)
	        {
	        	target[allNodePropertyName] = target[p];
	        	break;
	        }
	        ++target.numCells;
        }
        else if (target.numCells == 2 && target.hasOwnProperty(allNodePropertyName))
        {
        	for (p in target)
	        {
	        	if (p == allNodePropertyName)
	        		continue;
	        	if (target[allNodePropertyName] != target[p])
	        		target[allNodePropertyName] = target[p];
	        	break;
	        }
        }
        else
        {
        	var done:Boolean = false;
        	var q:String;
        	for (p in target)
	        {
	        	if (p == allNodePropertyName)
	        		continue;
	        	if (target[allNodePropertyName] == target[p])
	        	{
	        		value = target[p];
	        		if (value is CubeNode)
                	{
                		target[allNodePropertyName] = newNode = new CubeNode(/*value.level*/);
	        			accumValuesFromNode(newNode, value);
						for (q in target)
                		{
                			if (q == allNodePropertyName ||
                				q == p)
                				continue;
                			//now we have the other property.
			            	accumValuesFromNode(newNode, source[q]);
                		}
                		done = true;
                	}
                	else
                	{
                		target[allNodePropertyName] = null;
		            	addValueToNode(target, allNodePropertyName, value, null, null);
						for (q in target)
                		{
                			if (q == allNodePropertyName ||
                				q == p)
                				continue;
                			//now we have the other property.
			            	addValueToNode(target, allNodePropertyName, target[q], null, null);
                		}
                		done = true;
                	}
	        		break;
	        	}
	        }
	        
	        if (!done)
        	{
	        	p = allNodePropertyName;
	            value = source[p];
	        	if (value is CubeNode)
	        	{
	                if (target[p] is CubeNode)
	                    newNode = target[p];
	                else
	                {
	                	target[p] = newNode = new CubeNode(value.level);
	                	++target.numCells;
	                }    
	                accumValuesFromNode(newNode, value);
	            }
	            else
	            {
	            	addValueToNode(target, p, value, null, null);
	            }
	        } 
        }
    }
    
}
}
