/*

Copyright (c) 2008 Mrinal Wadhwa (http://www.mrinalwadhwa.com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/


package {
    import com.adobe.viewsource.ViewSource;
    
    import flash.display.Sprite;
    import flash.events.Event;
    
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.materials.special.VectorShapeMaterial;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.typography.Word3D;
    import org.papervision3d.typography.fonts.HelveticaRoman;
    import org.papervision3d.view.Viewport3D;


    [SWF(backgroundColor="#222222",frameRate="80")]
    
    public class VectorVisionExample extends Sprite{
        
        private var algorithms:Array = new Array();

        private var viewport:Viewport3D;
        private var scene:Scene3D;
        private var camera:Camera3D;
        private var renderer:BasicRenderEngine;

        private var greyColorMaterial:ColorMaterial;
        private var lightgreyVectorShapeMaterial:VectorShapeMaterial;
        
        private var plane:Plane; 
        private var word:Word3D;
        

        public function VectorVisionExample(){
            init();
        }

        private function init():void{
            
            /* add view source menu */
            ViewSource.addMenuItem(this, "srcview/index.html");
            
            preparePapervision();
            createMaterials();
            createObjects();
            addAlgorithms();
            run();
        }        

        /* prepare papervision */
        private function preparePapervision():void{
            viewport = new  Viewport3D( stage.stageWidth, stage.stageHeight, true, true );
            addChild( viewport );
            scene = new Scene3D();
            camera = new Camera3D();
            renderer = new BasicRenderEngine();
        }

        /* create materials */
        private function createMaterials():void{
            greyColorMaterial = new ColorMaterial(0x444444);
            lightgreyVectorShapeMaterial = new VectorShapeMaterial(0xcccccc);
        }        

        /* create objects */
        private function createObjects():void{
            
            plane = new Plane(greyColorMaterial,2000,800,9,9);
            plane.x = 0;
            plane.y = 0;
            scene.addChild(plane,"plane");
                 
            word = new Word3D("Papervision3D + VectorVision = Awesome 3D Text", 
                                new HelveticaRoman(), 
                                lightgreyVectorShapeMaterial);
            word.x = 0;
            word.y = 0;
            word.scale = 0.8;
            
            /* very important if you want to add 
            the text to another contatiner */
            word.useOwnContainer = true;
            
            plane.addChild(word,"text");            
        }

        private function run():void{
            addEventListener( Event.ENTER_FRAME, onEnterFrame );
        }

        /* add algos to execute on each freme */
        private function addAlgorithms():void{
            addAlgorithm(reactToMouse);
        }

        /* add an algo that that executes on each frame */
        public function addAlgorithm( algorithm:Function ):void{
            algorithms.push( algorithm );
        }

        /* remove an algo that that executes on each frame */
        public function removeAlgorithm( algorithm:Function ):void{
            algorithms.splice( algorithms.indexOf( algorithm ), 1 );
        }
            
        /* enter frame event handler */    
        private function onEnterFrame( e:Event ):void{
            for each( var algorithm:Function in algorithms ){
                algorithm();
            }
            renderer.renderScene( scene, camera, viewport );
        }    
        
        
        /* **  ALGORITHMS ** */
        
        private function reactToMouse():void{
              camera.x-=(camera.x-Math.sin((mouseX-(stage.stageWidth/2))*0.0001)*8000)/3;
            camera.z-=(camera.z-Math.cos((mouseX-(stage.stageWidth/2))*0.0001)*-1000)/3;
            camera.y-=(camera.y-viewport.containerSprite.mouseY);
            camera.lookAt(DisplayObject3D.ZERO);    
        }    
        
    }
}