(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); });	
					$(".previewErrors").html('');
					
					options.onSuccess.call(this);
				} else {
					
					$(".previewErrors").html('Sorry, it looks like we don\'t support this site yet.');
					$("#videoPreview").html('');
				}
			}
        });
    };

    // Plugin defaults
    $.fn.oembed.defaults = {
        maxWidth: 500,
        maxHeight: 400,
        onSuccess:function() {} 
    };

    $.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 displayError(thisError) {
		$(".previewErrors").html('There was a problem processing your video ('+thisError);
	
	};

    var providers = [
        new OEmbedProvider("flickr", "flickr", "http://flickr.com/services/oembed", "jsoncallback"),
        new OEmbedProvider("vimeo", "vimeo.com", "http://vimeo.com/api/oembed.json"),
        new OEmbedProvider("googlevideo", "video.google."),
        new OEmbedProvider("metacafe", "metacafe.com"),
        new OEmbedProvider("qik", "qik.com"),
        new OEmbedProvider("viddler", "viddler.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 + "?";

            url += "maxwidth=" + this.maxWidth + 
						"&maxHeight=" + this.maxHeight + 
						"&format=json" + 
						"&url=" + escape(externalUrl) + 
						"&" + this.callbackparameter + "=?";						
            return url;
        }

        this.embedCode = function(externalUrl, embedCallback) {
            var request = this.getRequestUrl(externalUrl);
            $.getJSON(request, function(data,status) {   
				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);

