﻿(function($) {
    $.fn.oembed = function(url, options, provider, pattern, apiurl) {		

		options = $.extend({}, $.fn.oembed.defaults, options);

    setOEmbedProvider(provider,pattern,apiurl);

    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: 300,
        maxHeight: 200
    };

    $.fn.oembed.getPhotoCode = function(url, data) {
        var code = '<div><a href="' + url + '" target="_blank"><img src="' + data.url + '"/></a></div>';
        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;
    }

    function setOEmbedProvider(name,url,apiurl) {
		  providers[providers.length++] = new OEmbedProvider(name,url,apiurl);
    }

    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"),
        new OEmbedProvider("youtube", "youtube.com")
    ];

    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 + "?";
            else
                url = url + "&";

            url += "maxwidth=" + this.maxWidth + 
						"&maxHeight=" + this.maxHeight + 
						"&format=json" + 
						"&url=" + escape(externalUrl) + 
						"&"+this.callbackparameter + "=";
						if (callbackparameter != null)
						 url += "?";						

            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);


