/*
 * WebRTC.js : Behaves as a wrapper for vwf/view/rtcObject
 * Maps simple 1:1 signal model to a broadcast model using target and sender ids
 */

define( [ "module", "vwf/view", "vwf/view/buzz/buzz.min" ], function( module, view, buzz ) {

    var self = this;        
    
    //a simple structure to hold the BUZZ sound reference and position data
    function SoundSource() {
        
        this.id = null;
        this.sound = null;
        this.position = null;
        this.volume = 1;
        this.endrange = 100;
        this.startrange = 1;
        this.looping = false;
        this.playing = false;
        
        this.play = function() {

            if ( !this.playing ) {
                this.sound.play();
            }

            if ( this.playing &&  this.sound.getPercent() == 100 ) {
                this.sound.stop();
                this.sound.play();
            }

            this.playing = true;
        };

        this.pause = function() {
            
            if ( this.playing ) {
                this.sound.pause();
            }
            
            this.playing = false;
        };

        this.stop = function() {

            if ( this.playing ) {
                this.sound.stop();
            }
            
            this.playing = false;
        };
    }

    SoundSource.prototype.loop = function() {
        
        if ( !this.looping ) {
            this.looping = true;
            this.sound.loop();
        }
    }

    SoundSource.prototype.unloop = function() {
        
        if ( this.looping ) {
            this.looping = false;
            this.sound.unloop();
        }
    }

    //Get the position of your source object
    //note: the 3D driver must keep track of this
    SoundSource.prototype.updateSourcePosition = function() {
        
        this.position = vwf.getProperty( this.id, 'worldPosition' );
    }

    //use inverse falloff, adjust the range parameters of the falloff curve by the "volume"
    //since HTML cant actually play it louder, but we can make it 'carry' farther
    SoundSource.prototype.updateVolume = function( camerapos ) {
        
        var x = Vec3.distance( camerapos, this.position );
        x = Math.max( 0, x );
        var v = this.volume;
        
        var vol = ( ( -x + v ) / ( v || 1 ) ) * ( ( -x + v ) / ( v || 1 ) );
        if( x > v ) { 
            vol = 0; 
        }
        this.sound.setVolume( Math.max( Math.min( vol, 1 ), 0 ) * 100 );
    }

    //the driver
    return view.load( module, {

        initialize: function( options ) {

            this.buzz = require( "buzz" );
            window._buzz = this.buzz;
            
            this.sounds = {};
            this.soundSources = {};
            //set this up as a global, so that we can play a click to indicate GUI actions
            window._SoundManager = this;
            
        },

        //simple function for gui elements to play sounds
        playSound: function( url, volume ) {

            this.calledMethod( this.kernel.application(), 'playSound', [ url, false, volume ] );
        },

        calledMethod : function( nodeID, methodName, methodParameters ) {
            //if the scene played the sound, it has no position and just plays at full volume
            
            if ( nodeID === this.kernel.application() && methodsName === "playSound" ) {
                var url = params[0];
                var loop = params[1] || false;
                
                //cache the sound - can only be played simultainously by different nodes
                if( this.sounds[ url ] ) {
                    
                    if( this.sounds[ url ].getPercent() == 100 ) {
                        this.sounds[ url ].stop();    
                    }
                    this.sounds[ url ].play();
                    if ( loop ) {
                        this.sounds[ url ].loop();
                    } else {
                        this.sounds[ url ].unloop();
                    }
                } else {
                    
                    var mySound = new this.buzz.sound( url, {
                        autoplay: false,
                        loop: false
                    } );
                    this.sounds[ url ] = mySound;
                    mySound.play();
                }
            
            } else {

                var url, loop, vol, soundID, soundSrc;

                switch ( methodName ) {
                    
                    case 'playSound':
                        url = params[0];
                        loop = params[1] || false;
                        vol =  params[2] || 1;
                        soundID = id + url;
                        soundSrc = this.soundSources[ soundID ];
                        //cache the sound - can only be played simultainously by different nodes
                        if ( !soundSrc ) {
                            soundSrc = this.soundSources[ soundID ] = new SoundSource();
                            soundSrc.id = id;
                            soundSrc.url = url;
                            
                            soundSrc.volume = vol;
                            soundSrc.sound = new this.buzz.sound( url, {
                                    autoplay: true,
                                    loop: loop
                                    
                            } );
                            soundSrc.looping = loop;
                            soundSrc.position = [ 0, 0, 0 ];
                            window._dSound = Sound;
                        } else {
                            
                            if( soundSrc.sound.getPercent() == 100 ) {
                                soundSrc.stop();
                            }

                            soundSrc.sound.setPercent( 0 );
                            soundSrc.play();

                            if( loop ) {
                                soundSrc.loop();
                            } else {
                                soundSrc.unloop();
                            }
                            soundSrc.volume = vol;
                        }
                        break;

                    case 'pauseSound':
                        url = params[ 0 ];
                        soundID = id + url;
                        soundSrc = this.soundSources[ soundID ];
                        if ( soundSrc ) {
                            soundSrc.pause();
                        }
                        break;

                    case 'stopSound':
                        url = params[0];
                        soundID = id + url;
                        soundSrc = this.soundSources[ soundID ];
                        if ( soundSrc ) {
                            soundSrc.stop();
                        }
                        break;

                    case 'deleteSound':
                        url = params[0];
                        soundID = id + url;
                        soundSrc = this.soundSources[ soundID ];
                        if ( soundSrc ) {
                            soundSrc.stop();
                            soundSrc.sound = null;
                        }
                        delete this.soundSources[ soundID ];
                        break;

                }



            }
        },
        //Update the sound volume based on the position of the camera and the position of the object
        ticked : function()
        {
            try { 
                var campos = [
                    _dView.getCamera().matrixWorld.elements[12],
                    _dView.getCamera().matrixWorld.elements[13],
                    _dView.getCamera().matrixWorld.elements[14]
                ];
                for ( var i in this.soundSources )
                {
                    this.soundSources[ i ].updateSourcePosition();
                    this.soundSources[ i ].updateVolume( campos );
                }
            } catch( e ) {
            
            }
        
        },
        deletedNode: function( nodeID ) {
            for ( var id in this.soundSources ) {

                if( this.soundSources[ id ].id === nodeID )
                    delete this.soundSources[ id ];
            
            }
        }
    } )
} );