(function($) {
    $.fn.oembed = function(url, options) {		
	
		options = $.extend({}, $.fn.oembed.defaults, options);
		
        return this.each(function() {      
			
			var container = $(this), 
				target = (url != null) ? url : container.attr("href"), 
				provider;		
			
			if (target != null) {			
				
				provider = getOEmbedProvider(target);

				if (provider != null) {
					provider.maxWidth = options.maxWidth;
					provider.maxHeight = options.maxHeight;               
					
					provider.embedCode(target, function(code) { container.html(code); });		
				}
			}
        });
    };

    // Plugin defaults
    $.fn.oembed.defaults = {
        maxWidth: 500,
        maxHeight: 400
    };

    $.fn.oembed.getPhotoCode = function(url, data) {
        var alt = data.title ? data.title : 'Photo';
        alt += data.author_name ? ', by '+data.author_name :'';
        alt += data.provider_name ? ', on '+data.provider_name :'';
        var code= '<a class="photo" href="'+ url +'"><img src="'+ data.url +'" alt="'+ alt +'"/></a>';
        if (data.html)
            code += "<div>" + data.html + "</div>";
        return code;
    };

    $.fn.oembed.getVideoCode = function(url, data) {
        var code = data.html;
        return code;
    };

    $.fn.oembed.getRichCode = function(url, data) {
        var code = data.html;
        return code;
    };

    $.fn.oembed.getGenericCode = function(url, data) {
        var title = (data.title != null) ? data.title : url,
			code = '<a href="' + url + '">' + title + '</a>';			
        if (data.html)
            code += "<div>" + data.html + "</div>";
		return code;
    };

    $.fn.oembed.isAvailable = function(url) {
        var provider = getOEmbedProvider(url);
        return (provider != null);
    };
	
    /* Private Methods */
    function getOEmbedProvider(url) {
        for (var i = 0; i < providers.length; i++) {
            if (providers[i].matches(url))
                return providers[i];
        }
        return null;
    }

    var providers = [
        new OEmbedProvider("fivemin", "5min.com"),
        new OEmbedProvider("amazon", "amazon.com"),
        new OEmbedProvider("flickr", "flickr", "http://flickr.com/services/oembed", "jsoncallback"),
        new OEmbedProvider("googlevideo", "video.google."),
        new OEmbedProvider("hulu", "hulu.com"),
        new OEmbedProvider("imdb", "imdb.com"),
        new OEmbedProvider("metacafe", "metacafe.com"),
        new OEmbedProvider("qik", "qik.com"),
        new OEmbedProvider("revision3", "slideshare"),
        new OEmbedProvider("slideshare", "5min.com"),
        new OEmbedProvider("twitpic", "twitpic.com"),
        new OEmbedProvider("viddler", "viddler.com"),
        new OEmbedProvider("vimeo", "vimeo.com", "http://vimeo.com/api/oembed.json"),
        new OEmbedProvider("wikipedia", "wikipedia.org"),
        new OEmbedProvider("wordpress", "wordpress.com"),
       //ou-specific, @todo Experimental.
        new OEmbedProvider("youtube", "youtube.com", "http://iet-access.open.ac.uk/malt/oembed")
        //new OEmbedProvider("youtube", "youtube.com")

//ou-specific ends.

    ];

    function OEmbedProvider(name, urlPattern, oEmbedUrl, callbackparameter) {
        this.name = name;
        this.urlPattern = urlPattern;
        this.oEmbedUrl = (oEmbedUrl != null) ? oEmbedUrl : "http://oohembed.com/oohembed/";
        this.callbackparameter = (callbackparameter != null) ? callbackparameter : "callback";
        this.maxWidth = 500;
        this.maxHeight = 400;

        this.matches = function(externalUrl) {
            // TODO: Convert to Regex
            return externalUrl.indexOf(this.urlPattern) >= 0;
        };

        this.getRequestUrl = function(externalUrl) {

            var url = this.oEmbedUrl;

            if (url.indexOf("?") <= 0)
                url = url + "?";

            url += "maxwidth=" + this.maxWidth + 

//ou-specific

                "&maxheight=" + this.maxHeight +

                //@todo Bug "&maxHeight=" + this.maxHeight + 

                "&client=" + "org.maltwiki:jquery.oembed.js" +

                "&ref=" + escape(location) +

//ou-specific ends.
 
						"&format=json" + 
						"&url=" + escape(externalUrl) + 
						"&" + this.callbackparameter + "=?";						
            return url;
        }

        this.embedCode = function(externalUrl, embedCallback) {

            var request = this.getRequestUrl(externalUrl);

            $.getJSON(request, function(data) {
                
				var code, type = data.type;

                switch (type) {
                    case "photo":
                        code = $.fn.oembed.getPhotoCode(externalUrl, data);
                        break;
                    case "video":
                        code = $.fn.oembed.getVideoCode(externalUrl, data);
                        break;
                    case "rich":
                        code = $.fn.oembed.getRichCode(externalUrl, data);
                        break;
                    default:
                        code = $.fn.oembed.getGenericCode(externalUrl, data);
                        break;
                }

                embedCallback(code);
            });
        }
    }
})(jQuery);

