/**
 * Example application of the NoncontiguousCartogram class.
 * Shows how to use WKT strings to set the centers of cartogram features.
 * 
 * By Zachary Forest Johnson
 * indiemaps.com/blog
 * 
 */
package
{
    import com.bit101.components.HUISlider;
    import com.bit101.components.Label;
    import com.bit101.components.Text;
    import com.indiemaps.mapping.cartograms.noncontiguous.NoncontiguousCartogram;
    import com.indiemaps.mapping.cartograms.utils.CartogramUtils;
    import com.indiemaps.mapping.projections.LambertConformalConic;
    import com.indiemaps.mapping.utils.ShpDbfLoader;
    import com.indiemaps.mapping.utils.WKTUtils;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.utils.Dictionary;
    [SWF(backgroundColor='#cccccc', width='800', height='450')]
    public class ManualCartogramTest extends Sprite
    {
        protected var shapefileLocation:String = 'data/shp/STATES2';
        protected var attributeField:String = 'AGE_65_UP';
        protected var anchorPercentile:Number = .85;        
        protected var maxWidthOfCartogram:Number = 350;
        protected var maxHeightOfCartogram:Number = 400;
        protected var combinedArrayForCartogram:Array = []; 
        protected var interactiveCartogram:NoncontiguousCartogram;
        protected var tweeningCartogram:NoncontiguousCartogram;
        protected var cartogramContainer:Sprite = new Sprite();
        protected var interfaceContainer:Sprite = new Sprite();
        protected var dragginFeature:Sprite = null;
        protected var wktTextDisplay:Text;
        protected var hingeDensitySlider:HUISlider;
        public function ManualCartogramTest()
        {
            var shpDbfLoader:ShpDbfLoader = new ShpDbfLoader(shapefileLocation + '.shp', shapefileLocation + '.dbf');    
            shpDbfLoader.addEventListener(ShpDbfLoader.DATA_LOADED, onShpDbfDataLoaded);
            cartogramContainer.y = 150;        
            cartogramContainer.x = 10;                
            addChild(cartogramContainer);
            createInterface();
            addChild(interfaceContainer);
        }
        protected function createInterface():void {            
            new Label(interfaceContainer, 10, 5, "State centers Well Known Text representation:");
            wktTextDisplay = new Text(interfaceContainer, 10, 30);
            wktTextDisplay.width = 780;
            wktTextDisplay.height = 70;
            hingeDensitySlider = new HUISlider(interfaceContainer, 200, 420, "Anchor density percentile", onSliderChange);
            hingeDensitySlider.width = 400;
            new Label(interfaceContainer, 140, 125, "move these states around");
        }
        protected function onSliderChange(event:Event):void {
            interactiveCartogram.anchorPercentile = (event.target as HUISlider).value;
            tweeningCartogram.anchorPercentile = (event.target as HUISlider).value;
        }
        public function getFeatureCentersArray():Array {
            var featureCenters:Array = [];
            for each (var featureObject:Object in combinedArrayForCartogram) {
                //get the new feature center off the featureGraphics dictionary of the NoncontiguousCartogram
                featureCenters.push(new Point((interactiveCartogram.featureGraphics[featureObject] as Sprite).x, (interactiveCartogram.featureGraphics[featureObject] as Sprite).y));
            }
            return featureCenters;
        }
        protected function onShpDbfDataLoaded(e:Event):void {
            var shpDbfLoader:ShpDbfLoader = e.target as ShpDbfLoader;
            combinedArrayForCartogram = CartogramUtils.createCombinedArrayFromShpDbf(shpDbfLoader.shpRecords, shpDbfLoader.dbfRecords, multiPolygonConversionFunction);
            CartogramUtils.removeObjectsFromCombinedArray(combinedArrayForCartogram, 'STATE_NAME', 'Hawaii', 'attributes');
            CartogramUtils.removeObjectsFromCombinedArray(combinedArrayForCartogram, 'STATE_NAME', 'Alaska', 'attributes');
            createCartogram();
            makeCartogramInteractive();
            wktTextDisplay.text = WKTUtils.createWKTMultiPointFromArray(getFeatureCentersArray());
        }
        protected function makeCartogramInteractive():void {
            for each (var featureObject:Object in combinedArrayForCartogram) {
                (interactiveCartogram.featureGraphics[featureObject] as Sprite).buttonMode = true;
                (interactiveCartogram.featureGraphics[featureObject] as Sprite).addEventListener(MouseEvent.MOUSE_DOWN, onFeatureMouseDown);
            }
        }
        protected function onFeatureMouseDown(e:MouseEvent):void {
            (e.currentTarget as Sprite).startDrag();
            dragginFeature = e.currentTarget as Sprite;
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        }
        protected function onMouseUp(e:MouseEvent):void {
            dragginFeature.stopDrag();
            dragginFeature = null;
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            updateCenters();
        }
        protected function updateCenters():void {
            wktTextDisplay.text = WKTUtils.createWKTMultiPointFromArray(getFeatureCentersArray());
            tweeningCartogram.featureCenters = getFeatureCentersDictionary();
        }
        protected function getFeatureCentersDictionary():Dictionary {
            var featureCentersArray:Array = WKTUtils.createArrayFromWKTMultiPoint(wktTextDisplay.text);
            var featureCentersDictionary:Dictionary = new Dictionary();
            for (var featureNum:Object in combinedArrayForCartogram) {
                featureCentersDictionary[combinedArrayForCartogram[featureNum]] = featureCentersArray[featureNum];
            }
            return featureCentersDictionary;
        }
        protected function createCartogram():void {
            interactiveCartogram = new NoncontiguousCartogram(combinedArrayForCartogram, maxWidthOfCartogram, maxHeightOfCartogram, attributeField, anchorPercentile, { fillColor : 0x0099cc, strokeColor : 0xffffff }, false);
            tweeningCartogram = new NoncontiguousCartogram(combinedArrayForCartogram, maxWidthOfCartogram, maxHeightOfCartogram, attributeField, anchorPercentile, { fillColor : 0, strokeColor : 0xffffff }, true);
            cartogramContainer.addChild(interactiveCartogram);
            cartogramContainer.addChild(tweeningCartogram);
            tweeningCartogram.x = 400;
            tweeningCartogram.tweenDuration = .5;
            initializeHingeDensitySlider();
        }
        protected function multiPolygonConversionFunction(multiPolygon:Array):Array {
            var standardParallel1_degrees:Number = 33;
            var standardParallel2_degrees:Number = 45;
            var latitudeOrigin_degrees:Number = 23;
            var longitudeOrigin_degrees:Number = -96;
            var geometry:Array = LambertConformalConic.projectMultiPolygon(multiPolygon, NaN, NaN, NaN, NaN, standardParallel1_degrees, standardParallel2_degrees, latitudeOrigin_degrees, longitudeOrigin_degrees);
            return geometry;
        }
        protected function initializeHingeDensitySlider():void {
            hingeDensitySlider.maximum = 1;
            hingeDensitySlider.minimum = 0;
            hingeDensitySlider.value = interactiveCartogram.anchorPercentile;
        }
    }
}