oWidget = function () {

    this.attribute_prefix = "ow:";

    this.registry = {};

    this.register = function(instance) {
        this.registry[instance.id] = instance;
    }

    this.get = function(id) {
        return this.registry[id];
    }

    this.attr = function(el, attribute_name, defaultvalue) {
        var val = el.getAttribute(this.attribute_prefix + attribute_name);
        if (!val) return defaultvalue;
        return val;	
    }

	
    this.reinitialize = function(id, request) {
        if (request.responseText.length) {
            $(id).innerHTML = request.responseText;
            oWidget.get(id).setupWidget(true, false);
        } else{        	
        	oWidget.get(id).setupWidget(true, true);
		}
    }

    this.topics = {};

    this.publish = function(name, widget) {
        if (typeof this.topics[name] == "undefined") {
            // no subscribers
            return false;
        }

        for (i=0; i<this.topics[name].length; i++) {
            this.topics[name][i](name, widget);
        }
        return true;
    }

    this.subscribe = function(name, callback) {
        if (typeof this.topics[name] == "undefined") {
            this.topics[name] = [];
        }
        this.topics[name].push(callback);
    }

    return this;
}();


Widget = Class.create();
Widget.prototype = {
    initialize: function(id, config) {
        this.id = id;
        if (typeof config == "undefined" || !config) {
            this.config = {};
        } else {
            this.config = config;
        }
    },

    el: function(name) {
        return $(this.id+"-"+name);
    },

    setupWidget: function() {
    },

    setState: function(key, value) {
        var url = "/organic-widget/"+this.id+"/set";
        var id = this.id;
        var x = new Ajax.Request(url, {
            method: 'get',
            parameters: 'key='+escape(key)+'&value='+escape(value)+'&_uncache='+(new Date()).getTime(),
            onComplete: function(r) { oWidget.reinitialize(id, r); }
        });
    },

    _flattenVar: function(value) {
        if(value == null) return [];
        switch(typeof value) {
            case "number":
            case "string":
                return [["", value]];
            case "object":
                var rval = [];
                if(typeof value.length == "number") {
                    for(var i = 0; i < value.length; i++) {
                        var flat = this._flattenVar(value[i]);
                        for(var j = 0;j < flat.length; j++) {
                            rval.push(["[" + i + "]" + flat[j][0], flat[j][1]]);
                        }
                    }
                } else {
                }
                return rval;
            case "function":
                return [];
            default:
                alert("unknown type " + typeof value);
                return [];
        }
    },

    formatGetVar: function(value) {
        var rval = [];
        if(typeof(value) == "object") {
            for(var k in value) {
                var flat = this._flattenVar(value[k]);
                for(var i = 0;i < flat.length;i++) {
                    rval.push(escape(k) + flat[i][0] + "=" + flat[i][1]);
                }
            }
        }
        return rval.join("&");
    },

    ajaxRequest: function(method, arguments, oncomplete) {
        var url = "/organic-widget/"+this.id+"/" + method;
        var id = this.id;

        if(typeof(arguments) != "object" || arguments == null) {
            arguments = {};
        }
        
        if(typeof oncomplete == "undefined") {
            oncomplete = function(r) { oWidget.reinitialize(id, r); }
        } 
        
        arguments["_uncache"] = (new Date()).getTime();

        var params = this.formatGetVar(arguments);
        var x = new Ajax.Request(url, {
            method: 'get',
            parameters: params,
            onComplete: oncomplete,
            on403: function(er) { window.location = "/login.html"; }
        });
		
		
    },

    child: function(id) {
        return oWidget.get(this.id+"-"+id);
    }

};
