var Wall = function() {
    
    var swfURL = "http://apps.cooliris.com/embed/cooliris.swf?t=1307582197";
    var jsBaseURL = false;
    // var swfURL = "http://test.public.cooliris.com/wall/bin-debug/CoolirisInMotion.swf";
    // var jsBaseURL = "http://test.public.cooliris.com/";
    
    var nativePreviewWidth = 611;
    var nativeAppWidth = 954;
    var previewAspect = 0.618;
    
    // Technically we use the flashvars hash to store more than just flashvars,
    // so we may need to distinguish real flashvars from other random 
    // properties. This is a set of all the real flashvars
    var forFlash = {
        style: true,
        backgroundcolor: true,
        backgroundimage: true,
        feed: true,
        glowcolor: true,
        numrows: true,
        showsearch: true,
        showembed: true,
        showtutorial: true,
        showchrome: true,
        partner: true
    };
    
    // These will be returned by get() if the associated flashvar is blank.
    var defaults = {
        // location: 'header',
        // size: 'medium',
        // source: 'flickr',
        // dest: 'html',
        // dest: 'gigya',
        // dest: 'wibiya',
        theme: 'theme-black',
        numrows: 3,
        showchrome: 'false',
        showsearch: 'false',
        showtutorial: 'false',
        showembed: 'true',
        title: "My Cooliris Wall"
    };
    
    // This is the set of wall properties (not flashvars) that should not be 
    // sent back to the server
    var excludeProps = {
        id: true,
        flashvars: true,
        created_at: true,
        updated_at: true
    };
    
    var getPreviewDims = function() {
        var appWidth = $("#inner").width();
        var width = nativePreviewWidth - (nativeAppWidth - appWidth);
        var height = Math.floor(width * previewAspect);
        return [width, height];
    };
    
    
    var doEmbed = function() {
        if (window.Sources && Sources.current) {
            Wall.setFlashvar("feed", Sources.current.getFeedURL());
        }

        var params = {
            allowfullscreen: true,
            allowscriptaccess: "always",
            bgcolor: "#000000",
            wmode: "opaque"
        };

        var flashvars = Wall.getFlashvars();
        flashvars.intro = 'appear'; // disable slide-in intro to make things snappier
        flashvars.useCustomCursor = false;
        if (Wall.jsBaseURL) {
            flashvars.jsBaseURL = Wall.jsBaseURL;
        }

        var dims = getPreviewDims();

        // Kluge for Wibiya builder; it's not visible when the page first
        // loads, thus this ends up negative.
        if (dims[0] < 0) {
          dims = [377, 232];
        }

        $("#wall").css("width", dims[0]);
        $("#wall").css("height", dims[1]);
        
        $("#wall-object").remove();
        $("#wall-container").prepend("<div id='wall-object'></div>");
        
        swfobject.embedSWF(Wall.swfURL, 
                           "wall-object", 607, 375,
                           "9.0.0", "", flashvars, params);

        swfobject.embedSWF(Wall.swfURL, 
                           "mini-wall-object", 363, 225,
                           "9.0.0", "", flashvars, params);
    };
    
    return {
        
        swfURL: swfURL,
        jsBaseURL: jsBaseURL,
        
        init: function() {
            $data('wall', {});
            $data('flashvars', {});
        },
        
        // Get/set a Wall prop; these correspond to columns in the wall table
        getProp: function(key) {
            var wall = $data('wall') || {};
            return wall[key.toLowerCase()] || defaults[key.toLowerCase()] || "";
        },
        
        setProp: function(key, value) {
            var wall = $data('wall');
            wall[key.toLowerCase()] = value.toString();
            $data('wall', wall);
        },
        
        // Get/set a 'Flashvar' prop; these go into the flashvars property
        // table for the wall as key/value
        getFlashvar: function(key) {
            var flashvars = $data('flashvars') || {};
            return flashvars[key.toLowerCase()] || defaults[key.toLowerCase()] || "";
        },
        
        setFlashvar: function(key, value) {
            var flashvars = $data('flashvars');
            flashvars[key.toLowerCase()] = value.toString();
            $data('flashvars', flashvars);
        },
        
        // Returns everything in the 'flashvars' hash; these may or nay not be
        // flashvars understood by the SWF; we use this hash to store other 
        // state stuff too.
        getAllFlashvars: function() {
            return $data('flashvars');
        },
        
        // Return only the flashvars that are understood by the SWF, set from
        // the forFlash 'set' above.
        getFlashvars: function() {
            var flashvars = $data('flashvars');
            var realFlashvars = {};
            for (var key in flashvars) {
                if (forFlash[key] && flashvars[key]) {
                    realFlashvars[key] = encodeURIComponent(flashvars[key]);
                }
            }
            return realFlashvars;
        },
        
        // Get the flashvar query string for embedding the SWF.
        getQueryString: function() {
            if (this.getProp("id")) {
                return "z=" + this.getProp("id");
            }
            else {
                return this.getRealQueryString();
            }
        },
        
        getRealQueryString: function() {
            var flashvars = this.getFlashvars();
            var flashvarStrs = [];
            for (var key in flashvars) {
                if (forFlash[key]) {
                    flashvarStrs.push(key + "=" + flashvars[key]);
                }
            }
            queryString = flashvarStrs.join("&");
            if (window.Sources && Sources.current.encode) {
                return "fv=" + Base64.encode(queryString);
            }
            else {
                return queryString;
            }
        },
        
        setFromQueryString: function(queryString) {
            var params = queryString.split("&");
            $.each(params, function(){
                var param = this.split("=");
                Wall.setFlashvar(param[0], param[1]);
            });
        },
        
        // Return all properties in a format that rails understands:
        //  wall[key] for wall props (columns)
        //  flashvars[key] for things that go in the flashvars table.
        getConverted: function() {
            var flashvars = $data('flashvars');
            var converted = {};
            for (var key in flashvars) {
                converted['flashvars[' + key + ']'] = flashvars[key];
            }
            var wall = $data('wall');
            for (var key in wall) {
                if (!excludeProps[key]) {
                    converted['wall[' + key + ']'] = wall[key];
                }
            }
            return converted;
        },
        
        getEmbedCode: function(pretty) {
            var endl = ($.browser.msie && $.browser.version != "8.0") ? "" + endl : "\n";
            var str;

            var randNum = (Math.floor(Math.random() * 100000)).toString();
            
            while (randNum.length < 5) {
                randNum = "0" + randNum;
            }
            
            str = '<object id="ci_${randNum}_o" ' + 
            'classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="${width}" ' + 
            'height="${height}"><param name="movie" value="${swfURL}"/><param ' + 
            'name="allowFullScreen" value="true"/><param name="allowScriptAccess" ' + 
            'value="always"/><param name="bgColor" value="#121212" /><param ' + 
            'name="flashvars" value="${flashvars}" /><param name="wmode" value="opaque" ' + 
            '/><embed id="ci_${randNum}_e" type="application/x-shockwave-flash" src="${swfURL}" ' + 
            'width="${width}" height="${height}" allowFullScreen="true" ' + 
            'allowScriptAccess="always" bgColor="#121212" flashvars="${flashvars}" ' + 
            'wmode="opaque"></embed></object>';

            str = str.format({
                width: this.getProp('width'),
                height: this.getProp('height'),
                randNum: randNum,
                swfURL: this.swfURL,
                flashvars: this.getQueryString()
            });

            str = str.replace(/\n/g, endl);

            return str;
        },
        
        preview: function() {
            var async = false;
            if (window.Sources && Sources.current && Sources.current.preEmbed) {
                async = Sources.current.preEmbed(doEmbed);
            }
            if (!async) {
                doEmbed();
            }
        },
        doEmbed: doEmbed
    };
}();

