<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:xx="com.tartiflop.*" 
    applicationComplete="startup()"
    backgroundGradientColors="[#101010, #101010]"
    backgroundAlpha="1" width="100%" height="100%" paddingLeft="5" paddingRight="5" paddingTop="5" shadowDirection="left" paddingBottom="5" backgroundGradientAlphas="[1.0, 1.0]" verticalAlign="middle"
    viewSourceURL="srcview/index.html">
    

    <mx:Grid width="640" height="384" backgroundColor="#000000">
        <mx:GridRow width="100%" height="100%">
            <mx:GridItem width="100%" height="100%" borderStyle="solid" paddingLeft="5" paddingBottom="5" paddingRight="5" paddingTop="5">
                <mx:Grid width="100%" height="100%">
                    <mx:GridRow width="100%" height="25">
                        <mx:GridItem width="100%" height="100%">
                            <mx:Label width="190" height="23" paddingTop="3" fontWeight="bold" text="Displacement map" color="#FFFFFF"/>
                        </mx:GridItem>
                    </mx:GridRow>
                    <mx:GridRow width="100%" height="55">
                        <mx:GridItem width="100%" height="100%">
                            <mx:Button label="Select file" click="selectFile();" color="#BBBBBB" fillAlphas="[0.52, 0.49, 0.52, 0.52]" fillColors="[#3A3737, #1C1A1A]" borderColor="#FFFFFF" alpha="1.0" textRollOverColor="#FFFFFF"/>
                        </mx:GridItem>
                    </mx:GridRow>
                    <mx:GridRow width="100%" height="100%">
                        <mx:GridItem width="100%" height="100%">
                            <xx:Viewer width="100%" height="100%" id="dispMapViewer">
                            </xx:Viewer>
                        </mx:GridItem>
                    </mx:GridRow>
                </mx:Grid>
            </mx:GridItem>
            <mx:GridItem width="100%" height="100%" borderStyle="solid" paddingLeft="5" paddingRight="5" paddingTop="5" paddingBottom="5">
                <mx:Grid width="100%" height="100%">
                    <mx:GridRow width="100%" height="25">
                        <mx:GridItem width="100%" height="100%">
                            <mx:Label width="145" height="23" paddingTop="3" fontWeight="bold" text="Normal map" color="#FFFFFF"/>
                            <mx:RadioButtonGroup id="radioGroup"/>
                            <mx:RadioButton label="Planar" groupName="radioGroup" color="#BBBBBB"  textRollOverColor="#FFFFFF" selected="true" click="setPlanar()"/>
                            <mx:RadioButton label="Spherical" groupName="radioGroup" color="#BBBBBB"  textRollOverColor="#FFFFFF"  click="setSpherical()"/>
                        </mx:GridItem>
                    </mx:GridRow>
                    <mx:GridRow width="100%" height="25">
                        <mx:GridItem width="100%" height="100%">
                            <mx:Label text="Displacement direction : " color="#FFFFFF" height="23" paddingTop="3" id="directionLabel" width="146"/>
                            <mx:ComboBox dataProvider="{directions}" close="selectDirection()" color="#BBBBBB" alternatingItemColors="[#1C1A1A, #1C1A1A]" rollOverColor="#3A3737" textRollOverColor="#FFFFFF" textSelectedColor="#111111" selectionColor="#BBBBBB" fillAlphas="[0.52, 0.49, 0.52, 0.52]" fillColors="[#3A3737, #1C1A1A]" borderColor="#FFFFFF" alpha="1.0" id="directionCombo" fontWeight="bold" selectedIndex="1"></mx:ComboBox>
                            <mx:Button label="Save png" click="saveNormalMap()" color="#BBBBBB" fillAlphas="[0.52, 0.49, 0.52, 0.52]" fillColors="[#3A3737, #1C1A1A]" borderColor="#FFFFFF" alpha="1.0" textRollOverColor="#FFFFFF"/>
                        </mx:GridItem>
                    </mx:GridRow>
                    <mx:GridRow width="100%" height="25">
                        <mx:GridItem width="100%" height="100%">
                            <mx:Label text="Amplitude : " color="#FFFFFF"/>
                            <mx:HSlider width="100%" minimum="1" maximum="20" id="ampSlider" value="8" change="selectAmplitude()"/>
                        </mx:GridItem>
                    </mx:GridRow>
                    <mx:GridRow width="100%" height="100%">
                        <mx:GridItem width="100%" height="100%">
                            <xx:Viewer width="100%" height="100%" id="normalMapViewer">
                            </xx:Viewer>
                        </mx:GridItem>
                    </mx:GridRow>
                </mx:Grid>
            </mx:GridItem>
        </mx:GridRow>
        <mx:GridRow width="100%" height="20">
            <mx:GridItem width="100%" height="100%" borderStyle="solid" paddingLeft="5" paddingBottom="2" paddingRight="5" paddingTop="1" colSpan="2">
                    <mx:Label width="100%" id="fileNameLabel" color="#FFFFFF"/>
            </mx:GridItem>
        </mx:GridRow>
    </mx:Grid>

    <mx:Script>
    <![CDATA[
        import com.tartiflop.DispToNormConverter;
        import com.tartiflop.SphericalDispToNormConverter;
        import com.tartiflop.ImageSaverEvent;
        import com.tartiflop.ImageSaver;
        import com.tartiflop.PlanarDispToNormConverter;
        import com.tartiflop.ImageLoaderEvent;
        import com.tartiflop.ImageLoader;
        
        import mx.events.MenuEvent;
        import mx.controls.Alert;
        import mx.collections.*;
    
        [Bindable]
        private var directions:ArrayCollection = new ArrayCollection(
            [ {label:"x", data:"x"}, 
            {label:"y", data:"y"}, 
            {label:"z", data:"z"} ]
        );
    
        private var converter:DispToNormConverter; 
        private var imageLoader:ImageLoader; 
        private var imageSaver:ImageSaver; 
    
        /**
         * Initialise objects and listeners
         */
        private function startup():void {
            converter = new PlanarDispToNormConverter();
    
            imageLoader = new ImageLoader();
            imageLoader.addEventListener(ImageLoaderEvent.IMAGE_SELECTED, onImageSelected);
            imageLoader.addEventListener(ImageLoaderEvent.LOAD_SUCCESS, onLoadSuccess);
            imageLoader.addEventListener(ImageLoaderEvent.LOAD_ERROR, onLoadError);
    
            imageSaver = new ImageSaver();
            imageSaver.addEventListener(ImageSaverEvent.SAVE_SUCCESS, onSaveSuccess);
            imageSaver.addEventListener(ImageSaverEvent.SAVE_ERROR, onSaveError);
        }
    
        /**
         * Called when an image is successfully loaded. Starts the conversion routine
         * to create a normal map. Both displacement and normal map are displayed.
         */
        private function onLoadSuccess(event:ImageLoaderEvent):void {
            fileNameLabel.text = "File loaded: " + event.loader.getFileName();
            
            dispMapViewer.setBitmap(event.loader.getBitmap());
            
            converter.setDisplacementMapData(event.loader.getBitmap().bitmapData);
            normalMapViewer.setBitmap(converter.convertToNormalMap());
        }
        
        /**
         * Displays an error message if an file is not loaded.
         */
        private function onLoadError(event:ImageLoaderEvent):void {
            fileNameLabel.text = "Error loading file: " + event.loader.getFileName();
        }
        
        /**
         * Displays message when a file has been selected.
         */
        private function onImageSelected(event:ImageLoaderEvent):void {
            fileNameLabel.text = "File selected: " + event.loader.getFileName();
        }
        
        /**
         * Displays saved file name when successfully saved.
         */
        private function onSaveSuccess(event:ImageSaverEvent):void {
            fileNameLabel.text = "File saved : " + event.saver.getFileName();
        }
        
        /**
         * Displays error message if file not saved correctly.
         */
        private function onSaveError(event:ImageSaverEvent):void {
            fileNameLabel.text = "Error saving file: " + event.saver.getFileName();
        }
        
        /**
         * Called when the "Select file" button is pressed. Initiates file load sequence.
         */
        private function selectFile():void {
            imageLoader.getFile();
        }

        /**
         * Sets the state to perform "planar" calculations. Copies all relevant data from previous converter.
         */
        private function setPlanar():void {
            var newConverter:PlanarDispToNormConverter = new PlanarDispToNormConverter();
            newConverter.setDirection(directionCombo.selectedItem.data);
            newConverter.setAmplitude(ampSlider.value);
            
            if (imageLoader.getBitmap() != null) {
                newConverter.setDisplacementMapData(imageLoader.getBitmap().bitmapData);
            }
            converter = newConverter;
            
            directionLabel.text = "Displacement direction : "
            
            normalMapViewer.setBitmap(converter.convertToNormalMap());
        }

        /**
         * Sets the state to perform "spherical" calculations. Copies all relevant data from previous converter.
         */
        private function setSpherical():void {
            var newConverter:SphericalDispToNormConverter = new SphericalDispToNormConverter();
            newConverter.setDirection(directionCombo.selectedItem.data);
            newConverter.setAmplitude(ampSlider.value);

            if (imageLoader.getBitmap() != null) {
                newConverter.setDisplacementMapData(imageLoader.getBitmap().bitmapData);
            }

            directionLabel.text = "Phi axis : "
            
            converter = newConverter;
            
            normalMapViewer.setBitmap(converter.convertToNormalMap());
        }

        /**
         * Called when the displacement direction combo changes value. Recalculates the normal map.
         */
        private function selectDirection():void {
            converter.setDirection(directionCombo.selectedItem.data);
            normalMapViewer.setBitmap(converter.convertToNormalMap());
        }
        
        /**
         * Called when the amplitude of the displacement is changed. Recalculates the normal map.
         */
        private function selectAmplitude():void {
            converter.setAmplitude(ampSlider.value);
            normalMapViewer.setBitmap(converter.convertToNormalMap());
        }
        
        /**
         * Called when the "Save png" button is pressed. Saves normal map.
         */
        private function saveNormalMap():void {
            imageSaver.saveBitmapAsPng(converter.getNormalMap());
        }
    
    ]]>
    </mx:Script>

</mx:Application>