 /*
-Weave (Web-based Analysis and Visualization Environment)
-Copyright (C) 2008-2011 University of Massachusetts Lowell
-
-This file is a part of Weave.
-
-Weave is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License, Version 3,
-as published by the Free Software Foundation.
-
-Weave is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Weave.  If not, see <http://www.gnu.org/licenses/>.
+	Weave (Web-based Analysis and Visualization Environment)
+	Copyright (C) 2008-2011 University of Massachusetts Lowell
+	
+	This file is a part of Weave.
+	
+	Weave is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License, Version 3,
+	as published by the Free Software Foundation.
+	
+	Weave is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+	
+	You should have received a copy of the GNU General Public License
+	along with Weave.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 package weave.data.BinningDefinitions
 {
+	import flash.utils.getTimer;
+	
 	import mx.utils.ObjectUtil;
 	
+	import weave.api.WeaveAPI;
+	import weave.api.registerLinkableChild;
+	import weave.api.reportError;
+	import weave.api.core.ILinkableHashMap;
 	import weave.api.data.IAttributeColumn;
 	import weave.api.data.IPrimitiveColumn;
 	import weave.api.data.IQualifiedKey;
-	import weave.api.registerLinkableChild;
-	import weave.api.reportError;
 	import weave.core.LinkableNumber;
 	import weave.data.BinClassifiers.NumberClassifier;
 	import weave.utils.AsyncSort;
-	import weave.utils.VectorUtils;
+	import weave.utils.VectorUtils;
 	
 	/**
 	 * Implemented from Doug Curl (javascript) and Daniel J Lewis (python implementation) and  Simon Georget (Geostats)

		// reusable temporary object
		private static const _tempNumberClassifier:NumberClassifier = new NumberClassifier();
		
		
		override public function generateBinClassifiersForColumn(column:IAttributeColumn):void
		{
			var name:String;
			// clear any existing bin classifiers
			output.removeAllObjects();
			
			var breaks:Array = getJenksBreak(column);
			
			var binMin:Number;
			var binMax:Number; 
			
			
			for (var iBin:int = 0; iBin < numOfBins.value; iBin++)
			{
				var minIndex:Number;
				if(iBin == 0)
				{
					minIndex = 0;
				}
				else
				{
					minIndex = _previousSortedValues.lastIndexOf(_previousBreaks[iBin]);
					minIndex = minIndex +1;
				}
				
				_tempNumberClassifier.min.value = _previousSortedValues[minIndex];
				
				var maxIndex:Number;
				if(iBin == numOfBins.value -1)
				{
					maxIndex = _previousSortedValues.length -1;
				}
				else
				{
					/* Get the index of the next break */
					maxIndex = _previousSortedValues.lastIndexOf(_previousBreaks[iBin+1]);
				}
				_tempNumberClassifier.max.value = _previousSortedValues[maxIndex];
				_tempNumberClassifier.minInclusive.value = true;
				_tempNumberClassifier.maxInclusive.value = true;
				
				//first get name from overrideBinNames
				name = getOverrideNames()[iBin];
				//if it is empty string set it from generateBinLabel
				if(!name)
					name = _tempNumberClassifier.generateBinLabel(column as IPrimitiveColumn);
				output.requestObjectCopy(name, _tempNumberClassifier);
			}
				
			// trigger callbacks now because we're done updating the output
			asyncResultCallbacks.triggerCallbacks();
		}
		
		/* This function returns the Good Fit Value for the breaks. Not used but just in case*/
		private function getGVF(column:IAttributeColumn):Number
		{
			var listMean:Number = getSumOfNumbers(_previousSortedValues);
			
			var SDAM:Number = 0;
			var sqDev:Number = 0;
			
			for(var i:int =0; i < _previousSortedValues.length; i++)
			{
				sqDev = Math.pow((_previousSortedValues[i]- listMean), 2);
				SDAM += sqDev;
			}
			
			
			var SDCM:Number = 0;
			var preSDCM:Number;
			var classStart:Number;
			var classEnd:Number;
			var classValues:Array;
			var classMean:Number;
			var sqDev2:Number;
			
			for(var j:int =0; j < numOfBins.value; j++)
			{
				if(_previousBreaks[j] ==0)
				{
					classStart = 0;
				}
				else
				{
					classStart = _previousSortedValues.indexOf(_previousBreaks[j]);
					classStart += 1;
				}
				
				classEnd = _previousSortedValues.indexOf(_previousBreaks[j+1]);
				
				classValues = _previousSortedValues.slice(classStart,classEnd);
				
				classMean = getSumOfNumbers(classValues)/classValues.length;
				
				for(var k:int =0; k < classValues.length; k++)
				{
					sqDev2 = Math.pow((classValues[k] - classMean),2);
					preSDCM += sqDev2;
				}
				
				SDCM += preSDCM;
			}
			
			return (SDAM - SDCM)/SDAM;
			
		}
		
		private var _previousSortedValues:Array = [];
		private var _previousBreaks:Array = [];
		
		private function getJenksBreak(column:IAttributeColumn):Array
		{	
			_previousBreaks.length = 0;
			_previousSortedValues.length = 0;
			
			var sortedValues:Array = getSortedNumbersFromColumn(column);
			
			VectorUtils.copy(sortedValues,_previousSortedValues);
			
			var mat1:Array = [];
			var mat2:Array = [];
			for (var i:int = 0; i < sortedValues.length+1; i++)
			{
				var temp1:Array = [];
				var temp2:Array = [];

			return sortedColumn;
		}
		
		/* This function returns the Good Fit Value for the breaks. Not used but just in case*/
//		private function getGVF(column:IAttributeColumn):Number
//		{
//			var listMean:Number = getSumOfNumbers(_previousSortedValues);
//			
//			var SDAM:Number = 0;
//			var sqDev:Number = 0;
//			
//			for(var i:int =0; i < _previousSortedValues.length; i++)
//			{
//				sqDev = Math.pow((_previousSortedValues[i]- listMean), 2);
//				SDAM += sqDev;
//			}
//			
//			
//			var SDCM:Number = 0;
//			var preSDCM:Number;
//			var classStart:Number;
//			var classEnd:Number;
//			var classValues:Array;
//			var classMean:Number;
//			var sqDev2:Number;
//			
//			for(var j:int =0; j < numOfBins.value; j++)
//			{
//				if(_previousBreaks[j] ==0)
//				{
//					classStart = 0;
//				}
//				else
//				{
//					classStart = _previousSortedValues.indexOf(_previousBreaks[j]);
//					classStart += 1;
//				}
//				
//				classEnd = _previousSortedValues.indexOf(_previousBreaks[j+1]);
//				
//				classValues = _previousSortedValues.slice(classStart,classEnd);
//				
//				classMean = getSumOfNumbers(classValues)/classValues.length;
//				
//				for(var k:int =0; k < classValues.length; k++)
//				{
//					sqDev2 = Math.pow((classValues[k] - classMean),2);
//					preSDCM += sqDev2;
//				}
//				
//				SDCM += preSDCM;
//			}
//			
//			return (SDAM - SDCM)/SDAM;
//			
//		}
		
	}
}