/*
 * Vimeo jQuery plugin
 *
 * Copyright (c) 2009 Cory Taylor
 *
 * $Id$
 */

(function($) {

    /**
    * Description coming soon
    *
    *
    * @type jQuery
    * @name Vimeo.com
    * @cat Plugins/Vimeo.com
    *
    */
    $.fn.vimeo = function(user, options, tOptions, cbFnc) {
        $.defineTag('script');
        var opts = $.extend({ 'user': user }, defaults, options),
		    $self = this,
		    fn = cbFnc || jQuery.vimeo.parsers[opts.type],
		    url = 'http://www.vimeo.com/api/' + user + '/' + opts.type + '.json?',
		    tOpts = $.extend({ callback: name(fn) }, $.vimeo.types[opts.type], tOptions);

        // prepare tag names for DOM Creator
        opts.itemTag = opts.itemTag.toUpperCase();
        opts.wrapTag = opts.wrapTag.toUpperCase();
        url += $.param(tOpts);
        document.getElementsByTagName('head')[0].appendChild($.SCRIPT({ src: url, type: 'text/javascript' }));
        return $self;

        // Ingenious name() closure function from Michael Geary
        // http://mg.to/2006/01/25/json-for-jquery
        function name(callback) {
            var i = $.vimeo.callbacks.length;

            $.vimeo.callbacks[i] = function(json) {
                delete $.vimeo.callbacks[i];
                $self.each(function() { callback.apply(this, [json, opts, tOpts]); });
            };
            return 'jQuery.vimeo.callbacks[' + i + ']';
        };
    };

    var defaults = {
        type: 'info', // possible values = user_info, clips
        itemTag: 'li',
        wrapTag: 'ul',
        append: false,
        portrait: true,
        popopen: false,
        loadedCallback: null,
        itemClickCallback: null
    };

    $.vimeo = {

        callbacks: [],

        types: {
            info: {
                headtext: '',
                headclass: '',
                bio: true,
                upload: true,
                liked: true,
                contacts: true
            },
            likes: {
                headtext: '',
                headclass: '',
                wrapID: '',
                wrapClass: ''
            }
        },

        // Prebuilt Callback Function
        parsers: {
            info: function(data, opts, tOpts) {
                var ls = [], tPortrait = '', h_opts = {}, a_opts = {};
                var oDiv, oSpan;

                if (opts.portrait)
                    tPortrait = $.IMG({ src: data.thumbnail_small, height: 30, width: 30, border: 0, alt: data.display_name })
                h_opts = { 'class': tOpts.headclass }
                a_opts = { href: data.profile_url, target: (opts.popopen) ? '_blank' : '_self' }
                oDiv = $.DIV({}, $.H3(h_opts,
				        $.A(a_opts, tPortrait,
				            oSpan = $.SPAN({}, tOpts.headtext)
				        )
				    )
				);

                if (opts.portrait) {
                    $(tPortrait).css({ 'vertical-align': 'middle' }).bind('load', function() { $(this).show('slow') });
                    $(oSpan).css({ marginLeft: '5px' });
                }
                if (tOpts.bio) ls[ls.length] = $[opts.itemTag]({}, $.SPAN({}, data.bio));
                if (tOpts.upload) ls[ls.length] = $[opts.itemTag]({}, $.SPAN({}, data.total_videos_uploaded + ' Videos'));
                if (tOpts.liked) ls[ls.length] = $[opts.itemTag]({}, $.SPAN({}, data.total_videos_liked + ' Likes'));
                if (tOpts.contacts) ls[ls.length] = $[opts.itemTag]({}, $.SPAN({}, data.total_contacts + ' Contacts'));

                if (!ls.length)
                    ls[ls.length] = $[opts.itemTag]({}, 'Info not available');

                $.vimeo.add(oDiv, $[opts.wrapTag]({}, ls), { append: true });
                $.vimeo.add(this, oDiv, opts);

                if (opts.loadedCallback != null) opts.loadedCallback(this);
            },
            likes: function(data, opts, tOpts) {
                var ls = [], h_opts = {}, oDiv;
                h_opts = { 'class': tOpts.headclass }

                $.each(data, function(i, iData) {
                    var oThumb = '', a_opts = { href: '#' };
                    if (opts.popopen) a_opts = { href: iData.url, target: '_blank' };
                    oThumb = $.IMG({ src: iData.thumbnail_small, height: 80, width: 80, border: 0, alt: iData.title });
                    if (opts.itemClickCallback != null) $(oThumb).bind('click', { video_id: iData.clip_id }, opts.itemClickCallback);
                    ls[ls.length] = $[opts.itemTag]({}, $.A(a_opts, oThumb));
                });

                if (!ls.length)
                    ls[ls.length] = $[opts.itemTag]({}, 'Likes not available');

                oDiv = $.DIV({}, $.H3(h_opts,
				        oSpan = $.SPAN({}, tOpts.headtext)
				    )
				);
                $.vimeo.add(oDiv, $[opts.wrapTag]({ id: tOpts.wrapID, 'class': tOpts.wrapClass }, ls), { append: true });
                $.vimeo.add(this, oDiv, opts);

                if (opts.loadedCallback != null) opts.loadedCallback(this);
            }
        },

        add: function(elm, obj, opts) {
            $(elm)[opts.append ? 'append' : 'html'](obj);
        }

    };

    /*
    * Code below by Michael Geary
    * Included for convenience
    *
    * DOM element creator for jQuery and Prototype by Michael Geary
    * http://mg.to/topics/programming/javascript/jquery
    * Inspired by MochiKit.DOM by Bob Ippolito
    * Free beer and free speech. Enjoy!*/
    $.defineTag = function(tag) {
        $[tag.toUpperCase()] = function() {
            return $._createNode(tag, arguments);
        }
    };

    (function() {
        var tags = [
		'a', 'br', 'button', 'canvas', 'div', 'fieldset', 'form',
		'h1', 'h2', 'h3', 'hr', 'img', 'input', 'label', 'legend',
		'li', 'ol', 'optgroup', 'option', 'p', 'pre', 'select',
		'span', 'strong', 'table', 'tbody', 'td', 'textarea',
		'tfoot', 'th', 'thead', 'tr', 'tt', 'ul'];
        for (var i = tags.length - 1; i >= 0; i--) {
            $.defineTag(tags[i]);
        }
    })();

    $.NBSP = '\u00a0';

    $._createNode = function(tag, args) {
        var fix = { 'class': 'className', 'Class': 'className' };
        var e;
        try {
            var attrs = args[0] || {};
            e = document.createElement(tag);
            for (var attr in attrs) {
                var a = fix[attr] || attr;
                e[a] = attrs[attr];
            }
            for (var i = 1; i < args.length; i++) {
                var arg = args[i];
                if (arg == null) continue;
                if (arg.constructor != Array) append(arg);
                else for (var j = 0; j < arg.length; j++)
                    append(arg[j]);
            }
        }
        catch (ex) {
            alert('Cannot create <' + tag + '> element:\n' +
			args.toSource() + '\n' + args);
            e = null;
        }

        function append(arg) {
            if (arg == null) return;
            var c = arg.constructor;
            switch (typeof arg) {
                case 'number': arg = '' + arg;  // fall through
                case 'string': arg = document.createTextNode(arg);
            }
            e.appendChild(arg);
        }

        return e;
    };

})(jQuery);

