package
{
    import away3d.cameras.Camera3D;
    import away3d.containers.Scene3D;
    import away3d.containers.View3D;
    import away3d.core.render.Renderer;
    import away3d.materials.BitmapMaterial;
    import away3d.primitives.Cube;
    
    import com.adobe.viewsource.ViewSource;
    import com.as3dmod.ModifierStack;
    import com.as3dmod.modifiers.Cloth;
    import com.as3dmod.plugins.away3d.LibraryAway3d;
    import com.as3dmod.util.ModConstant;
    
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    
    [SWF(width="800", height="600", frameRate="30", backgroundColor="0x000000")]
    public class as3dmod_funkycube extends Sprite
    {
        private var _modifierStack : ModifierStack;
        private var _modifier : Cloth;
        
        private var _count : Number = 0;
        
        [Embed(source="../assets/Metropolis_Rep.jpg")]
        private var _textureAsset : Class;
        
        private var _view : View3D;
        private var _camera : Camera3D;
        private var _scene : Scene3D;
        private var _renderer : Renderer;
        private var _object : Cube;
        
        public function as3dmod_funkycube()
        {
            stage.quality = "low";
            
            // init Away3D and AS3DMod
            initAway3D();
            initAS3DMod();
            addEventListener(Event.ENTER_FRAME, handleEnterFrame);
            
            ViewSource.addMenuItem(this, "srcview");
        }
        
        private function initAway3D() : void
        {
            var material : BitmapMaterial;
            var bmp : BitmapData;
            
            // create basic scene setup
            _view = new View3D({width:800, height:600});
            _view.x = stage.stageWidth*.5;
            _view.y = stage.stageHeight*.5;
            _camera = _view.camera;
            _scene = _view.scene;
            addChild(_view);
            
            // create cube and add it to the scene
            bmp = new _textureAsset().bitmapData;
            material = new BitmapMaterial(bmp);
            _object = new Cube({material: material, width:700, height:500, depth:500, segmentsH:10, segmentsW:10});
            _scene.addChild(_object);
        }
        
        private function initAS3DMod() : void
        {
            // create modifier stack
            _modifierStack = new ModifierStack(new LibraryAway3d(), _object);
            
            // create cloth modifier and add it to the stack
            _modifier = new Cloth();
            _modifierStack.addModifier(_modifier);
            
            // make the bottom of the box immobile
            _modifier.lockYMin(0);
            
            // make the top of the box keep a constant height
            _modifier.lockYMax(0, ModConstant.Y);
            
            // set gravity
            _modifier.forceY = -1;
        }
        
        private function handleEnterFrame(event : Event) : void
        {
            var halfW : Number = stage.stageWidth*.5,
                halfH : Number = stage.stageHeight*.5;
            var cameraAngle : Number = (0.1+mouseX/halfW-halfW)*1.3;
            
            // add some random wind
            _modifier.forceX = -1+Math.random()*4;
            _modifier.forceZ = -1+Math.random()*3;
            
            // update the modifier stack, applying the cloth update
            _modifierStack.apply();
            
            // adjust camera position to mouse position
            _camera.x = Math.sin(cameraAngle)*2000;
            _camera.z = Math.cos(cameraAngle)*2000;
            _camera.y = Math.sin(mouseY/halfH-halfH)*1000;
            _camera.lookAt(_object.position);
            
            // render the scene
            _view.render();
        }
    }
}