
var FlashBridge = {

    ___flash_objects: {},
    ___flash_uid: 0,

    __flash_add_flash_event_listener: function(obj, name, callback){

        var evts = obj.__flash_event_listeners[name];
        if(!evts){
            evts = [];
            obj.__flash_event_listeners[name] = evts;
        }

        //yeh i know this is evil
        if( !eval( obj.flash_elem.CallFunction('<invoke name="addFlashEventListener" returntype="javascript">' + __flash__argumentsToXML([obj.__flash_obj_id, name], 0) + '</invoke>') )) 
        {
            return;
        }
        evts.include(callback);
    },

    __flash_remove_flash_event_listener: function(obj, name, callback) {
        var evts = obj.__flash_event_listeners[name];
        if(!evts){ return; }
        var index = evts.indexOf(callback);
        if(index == -1){ return; }

        evts.remove(callback);
        if(!evts || evts.length === 0){
            obj.flash_elem.CallFunction(
                        '<invoke name="removeFlashEventListener" returntype="javascript">' + 
                            __flash__argumentsToXML([obj.__flash_obj_id, name]) + 
                        '</invoke>');
        }
    },

    mk_flash: function (src, id, width, height, flashVars, params, attributes, onloadCallback){
        var flash_obj_id = "__FLASH_OBJ_ID_" + this.___flash_uid++,
        vars = $extend(flashVars, {_obj_id:  flash_obj_id});

        var obj = { __flash_obj_id: flash_obj_id,
                    __flash_elem_id: id,
                __flash_event_listeners: {},
                addFlashEventListener: function(name, callback){ FlashBridge.__flash_add_flash_event_listener(obj, name, callback); },
                removeFlashEventListener: function(name, callback){ FlashBridge.__flash_remove_flash_event_listener(obj, name, callback); },
                __onload: onloadCallback
              };
        FlashBridge.___flash_objects[obj.__flash_obj_id] = obj;

        swfobject.embedSWF(src, id, width, height, "9.0.0", "expressInstall.swf", vars, params, attributes);
        //$extend(obj, { flash_elem: $(id) });

        return obj;
    },

    rm_flash_object: function(obj) {
        delete FlashBridge.___flash_objects[obj.__flash_obj_id];
    },

    mk_flash_proxy_function_with_name: function(obj, obj_fn_name, name) {
        obj[obj_fn_name] = function(){ 
            var cmd = '<invoke name="' + name + '" returntype="javascript">' + __flash__argumentsToXML(arguments, 0) + '</invoke>';
            var rs = obj.flash_elem.CallFunction(cmd);
            return eval(rs);
        };
    },

    mk_flash_proxy_function: function(obj, name){
        FlashBridge.mk_flash_proxy_function_with_name(obj, name, name);
    },

    mk_flash_function_proxies: function (obj, names){
        for(var i = 0; i < names.length; i++){
            var name = names[i];
            FlashBridge.mk_flash_proxy_function(obj, names[i]);
        }
    }
};

function ___flash_event_callback(obj_id, evt_name, value){
    var obj = FlashBridge.___flash_objects[obj_id];
    if(!obj){ return; }

    var callbacks = obj.__flash_event_listeners[evt_name];
    if(!callbacks || callbacks.length === 0){ return; }

    for(var i=0; i < callbacks.length; i++){
        fn = callbacks[i];
        try{
            fn(value);
        }catch(err){} //IE won't execute handler function without error "handling"
    }
}

function ___flash_onload_callback(obj_id){
    var obj = FlashBridge.___flash_objects[obj_id];
    $extend(obj, {flash_elem: $(obj.__flash_elem_id)});
    var fn = obj.__onload;
    if(fn !== null){ fn(obj); }
    obj.__onload = null;
}

var FlashVideo = new Class({
    
    videoWidth: 0,
    videoHeight: 0,

    initialize: function(containerId, opts ){
       var options = { src: null,
                       flash_src: "player.swf",
                       width: 320,
                       height: 240,
                       deblocking: 0,
                       smoothing: false,
                       autoplay: true,
                       loop: false,
                       onload: null,
                       params: {},
                       attributes: {}
                     };

       var flashListener = opts.flashListener;
       $extend(options, opts);
       options.videoWidth = options.videoWidth || options.width;
       options.videoHeight = options.videoHeight || options.height;

       window.addEvent('unload', function(){
           this.closeStream();
           FlashBridge.rm_flash_object(this);
       }.bind(this));

       FlashBridge.mk_flash(options.flash_src, containerId, options.width, options.height, 
                                    { videoWidth: options.videoWidth,
                                      videoHeight: options.videoHeight,
                                      loop: options.loop },
                                options.params, options.attributes,
                                function(obj){
                                    $extend(this, obj);
                                    FlashBridge.mk_flash_function_proxies(this, ["pause", "resume", "closeStream", "seek", "playStream", "bufferLength",
                                                                                "bufferTime", "setBufferTime", "bytesLoaded", "bytesTotal", "liveDelay",
                                                                                "time", "deblocking", "setDeblocking", "smoothing", "setSmoothing", "videoHeight",
                                                                                "videoWidth", "setVideoSize", "alpha", "setAlpha", "volume", "setVolume"]);
                                    FlashBridge.mk_flash_proxy_function_with_name(this, "doPlayFile", "playFile");

                                    this.playFile = function(video) {
                                        if(video) { options.src = video; }
                                        if(options.src){ this.doPlayFile(options.src); }
                                    }

                                    for(var listener in flashListener) {
                                        try{
                                            this.addFlashEventListener(listener, flashListener[listener]);
                                        }catch(err){
                                            //alert('err: ' + err);
                                            console.log(err);
                                        }
                                    }

                                    this.setDeblocking(options.deblocking);
                                    this.setSmoothing(options.smoothing);

                                    if(options.autoplay) { this.playFile(); }
                                    if(options.onload) { options.onload(this); }
                                }.bind(this));
        return this;
    }
});

