<?xml version="1.0" encoding="utf-8"?>
<!--
    /*
     * Copyright 2007 Philip Flip Kromer
     * 
     * Licensed under the "Attribution-Open" Vizsage Public License (the
     * "License"). You may not use this file except in compliance with 
     * the License. Roughly speaking, anyone may share and modify this 
     * code, but must give credit. However, for proper details please 
     * read the full License, available at
     *      http://vizsage.com/license/Vizsage-License-BY.html 
     * and the handy reference for understanding the full license at 
     *      http://vizsage.com/license/Vizsage-Deed-BY.html
     * 
     * Unless required by applicable law or agreed to in writing, any
     * 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.
     */
-->
<mx:Application 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:vgzdemo="com.vizsage.demos.controls.*" 
    viewSourceURL="srcview/index.html"
    layout="absolute"  backgroundGradientColors="[#d0dcdc, #d4cbd0]"  
    creationComplete="{onCreationComplete()}"
    >
    
    <mx:Script><![CDATA[
        import mx.core.FontAsset;
        import mx.core.BitmapAsset;
        import flash.geom.Matrix;
        import flash.geom.Point;
        import com.vizsage.demos.utils.MatrixMathUtil; 
        
        // Original
        private var mA:Matrix = new Matrix();            
        private var mB:Matrix = new Matrix();        
        private var pt:Point;
        // Results of Multiply
        private var mASAB:Matrix;        private var mASBA:Matrix;        
        private var mMyAB:Matrix;        private var mMyBA:Matrix;    
        // Results of Invert
        private var mASAInv:Matrix;        private var mASBInv:Matrix;    
        private var mMyAInv:Matrix;        private var mMyBInv:Matrix;    
        // Results of Point Transformations
        private var ptASATr   :Point;    private var ptASADelTr:Point;
        private var ptMyATr   :Point;    private var ptMyADelTr:Point;
        
        /**
         * <p>Calls Routines to demonstrate Matrices in Actionscript/Flex
         * Uses actionscript matrix routines, then calls 
         * functions to do Matrix math explicitly.</p>
         * 
         * <p>Since data binding to a Matrix doesn't work (or quite possibly,
         * since I'm not smart enough to get it to work) we also push
         * across the new values.</p>
         * 
         */
        public function doMath():void {
            mA = inputA.getMatrix();
            mB = inputB.getMatrix();
            pt = inputV.value;
            
            // Multiply
            // Note that since concat means applyT(applyS(_slot_)) for S.T we want (T.clone), then concat(S)
            mASAB   = mB.clone() as Matrix; mASAB.concat(mA);              mASBA   = mA.clone(); mASBA.concat(mB);
              mMyAB   = MatrixMathUtil.multExplicit(mA, mB);                mMyBA   = MatrixMathUtil.multExplicit(mB, mA);            

            // Inverse
            mASAInv = mA.clone(); mASAInv.invert();                        mASBInv = mB.clone(); mASBInv.invert();    
            mMyAInv = MatrixMathUtil.invertExplicit(mA);                mMyBInv = MatrixMathUtil.invertExplicit(mB);    

            // Normal and Delta Point Transform
              ptASATr    = mA.transformPoint(pt);                            ptASADelTr = mA.deltaTransformPoint(pt);
              ptMyATr    = MatrixMathUtil.pointTransformExplicit(mA, pt); ptMyADelTr = MatrixMathUtil.deltaPointTransformExplicit(mA, pt);

            // Force values (no data binding for Matrix)
            showASAB.showMatrix   (mASAB);        showMyAB.showCompMatrix   (mMyAB,   mASAB);
            showASBA.showMatrix   (mASBA);        showMyBA.showCompMatrix   (mMyBA,   mASBA);
            showASAInv.showMatrix (mASAInv);    showMyAInv.showCompMatrix (mMyAInv, mASAInv);
            showASBInv.showMatrix (mASBInv);    showMyBInv.showCompMatrix (mMyBInv, mASBInv);
            showASPtTr.showVector (ptASATr);    showMyPtTr.showCompVector (ptMyATr,    ptASATr);
            showASDelPT.showVector(ptASADelTr);    showMyDelPT.showCompVector(ptMyADelTr, ptASADelTr);
            /* showA.showMatrix      (mA);         showB.showCompMatrix      (mB,      mA); */
        }

        /**
         * Push out initial calculations, and set the bitmap for the drawer.
         *
         */       
        private function onCreationComplete():void {  
            setCurrBitmap(BitmapChooser.selectedItem);
            doStuff();     
        }
        /**
         * Recalculate all the matrices, and push out the results.
         */   
        public  function doStuff():void {
            doMath();
            // Don't redraw if drawing not visible
            if (mainDrawing.visible == true) {
                mainDrawing.mat = mA;
                mainDrawing.invalidateDisplayList();
            }
        }
        /** @private */
        private function onInputChanged(event:Event):void {
            doStuff();
        }
        

        /*
         * Set up images.
         */
        [Embed(source="assets/images/Sunflower.jpg")] [Bindable] private var sunflowerBitmapClass:Class;
        [Embed(source="assets/images/Doggie.jpg"   )] [Bindable] private var doggieBitmapClass:Class;
        private var sunflowerBitmap:BitmapAsset = new sunflowerBitmapClass() as BitmapAsset;
        private var doggieBitmap:BitmapAsset    = new doggieBitmapClass()    as BitmapAsset;
         [Bindable] private var currBitmap:BitmapAsset      = doggieBitmap;    
        [Bindable] private var bitmapDictionary:Array     = [ 
                { label:"Doggie",    bitmap:doggieBitmap,    credits:"Doggie Photo by <a href='http://www.flickr.com/photos/nao-cha/21803202/'><font color='blue'><u>Nao-Cha</u></font></a>" },
                { label:"Sunflower", bitmap:sunflowerBitmap, credits:"Sunflower photo by <a href='http://kromer.net/'><font color='blue'><u>Matt Kromer</u></font></a>" }, 
           ];
        
        /**
         * Sets a new drawing Bitmap -- takes an object whose "bitmap" field is the BitmapAsset to use
         *
         */
        public  function setCurrBitmap(choice:Object):void {
            mainDrawing.setCurrBitmap(choice.bitmap);
            creditsLink.htmlText = choice.credits;
        }
    ]]></mx:Script>
    

    <mx:VBox top="10" left="10" right="10" bottom="10">
    
        <mx:HBox width="100%" backgroundColor="0xFFFFFF">
            <vgzdemo:MatrixInput id="inputA" label="Matrix A"                     creationComplete="inputA.addEventListener(Event.CHANGE, onInputChanged)"/>
            <vgzdemo:MatrixInput id="inputB" label="Matrix B"                     creationComplete="inputB.addEventListener(Event.CHANGE, onInputChanged)"/>
        </mx:HBox> <!-- Inputs  -->
        
        <!--
        <mx:HBox width="100%">
            <vgzdemo:MatrixView     id="showA"    label="A"/>
            <vgzdemo:MatrixViewComp id="showB"    label="B"/>        
        </mx:HBox>
         -->
         
        <mx:HBox width="100%">
            <mx:Button label="A =&gt; Identity" click="inputA.setMatrix(new Matrix()); doStuff()"/>
            <mx:Button label="A =&gt; Random"     click="inputA.setMatrix(MatrixMathUtil.randomMatrix()); doStuff()"/>
            <mx:Button label="B =&gt; Identity" click="inputB.setMatrix(new Matrix()); doStuff()"/>
            <mx:Button label="B =&gt; Random"     click="inputB.setMatrix(MatrixMathUtil.randomMatrix()); doStuff()"/>
        </mx:HBox> <!-- Convenient Value Setters -->
        
        <!-- ************** Output Results **************   -->
        
        <!--<mx:Accordion resizeToContent="true" creationPolicy="all" width="100%" height="100%"> -->
        <mx:TabNavigator creationPolicy="all" width="100%" height="100%" backgroundAlpha="0.0"> 
        <mx:VBox label="Matrix A on a Canvas" width="100%" height="100%">
            <mx:HBox right="0" width="100%">
                <mx:Spacer width="100%"/>
                <mx:Text bottom="0" id="creditsLink" htmlText="{bitmapDictionary[0].credits}"/>
                <mx:ComboBox id="BitmapChooser"  dataProvider="{bitmapDictionary}" change="setCurrBitmap(BitmapChooser.selectedItem)"></mx:ComboBox>
            </mx:HBox>
            <mx:Canvas width="100%" height="100%" backgroundAlpha="0.0">
            <!-- Show the effect of the matrix on a canvas.  -->
            <vgzdemo:GridMatrixWidget id="mainDrawing"  nCells="10" 
                minHeight="300" minWidth="300" top="0" left="0" bottom="0" right="0"/>
                
            </mx:Canvas>
        </mx:VBox><!-- /Demo -->
        
        <mx:VBox label="Multiply/concat()"     width="100%" height="270">
            <mx:HBox width="100%" height="100%">
                <vgzdemo:MatrixView     id="showASAB"    label="A times B (B.concat(A))"/>
                <vgzdemo:MatrixViewComp id="showMyAB"    label="A times B (Calculated Explicitly)"/>        
            </mx:HBox>
            <mx:HBox width="100%" height="100%">
                <vgzdemo:MatrixView     id="showASBA"    label="B times A (B.concat(A))"/>
                <vgzdemo:MatrixViewComp id="showMyBA"    label="B times A (Calculated Explicitly)"/>        
            </mx:HBox>
        </mx:VBox><!-- /Multiplied -->
        
        <mx:VBox label="Matrix invert()"                 width="100%" height="270">
            <mx:HBox width="100%" height="100%">
                <vgzdemo:MatrixView     id="showASAInv"  label="A.invert()"/>
                <vgzdemo:MatrixViewComp id="showMyAInv"  label="A Inverse (Calculated Explicitly)"/>        
            </mx:HBox>
            <mx:HBox width="100%" height="100%">
                <vgzdemo:MatrixView     id="showASBInv"  label="B.invert()"/>
                <vgzdemo:MatrixViewComp id="showMyBInv"  label="B Inverse (Calculated Explicitly)"/>    
            </mx:HBox>
        </mx:VBox><!-- /Inverted -->
        
        <mx:VBox label="Point Transformations"     width="100%" height="370">
            <vgzdemo:VectorInput id="inputV" label="What's your Vector, Victor?" creationComplete="inputV.addEventListener(Event.CHANGE, onInputChanged)"/>
            <mx:HBox width="100%" height="100%">
                <vgzdemo:VectorView     id="showASPtTr"  label="A.pointTransform(v)"/>
                <vgzdemo:VectorViewComp id="showMyPtTr"  label="ptTr Calculated Explicitly"/>
            </mx:HBox>
            <mx:HBox width="100%" height="100%">
                <vgzdemo:VectorView     id="showASDelPT" label="A.deltaPointTransform(v)"/>
                <vgzdemo:VectorViewComp id="showMyDelPT" label="dPtTr Calculated Explicitly"/>
            </mx:HBox>
        </mx:VBox><!-- /Point Transform -->
        </mx:TabNavigator>
        <!--</mx:Accordion> --><!-- Results Panes -->
    
    </mx:VBox><!-- Main VBox -->
    
    <!-- Make gridlines -->
    <mx:Style>
        Grid                     { horizontalGap: 0; verticalGap: 0; }
        GridRow                 {background-color:#ffffff            } 
        Grid, GridRow, GridItem {    border-thickness:"1"; border-style:"solid"; border-color:#a0a0a0;     }
        Grid                     {  border-sides:"right top";}
        GridRow                 {  border-sides:"bottom";     }
        GridItem                 {  border-sides:"left";        }
    </mx:Style>

</mx:Application>