﻿/*
base.js
Primary javascript for IM-like sites.
*/

$(function () {
    // Select/toggle main menu items.
    // PONDER: can be removed?
    $("#mainmenu > li").click(function (ev) {
        var me = $(this), sel = $('#mainmenu > li.active');
        sel.removeClass('active');

        // NOTE: can't compare jquery object directly, but you can compare 
        // the DOM objects they're attached to.
        if (me[0] != sel[0])
            me.addClass('active');
    });

    initBanner();
    initGalleries();
    initVideos();
    initGoogleMaps();

    //# TODO: Goto and play video on anchor.
    if (document.location.hash) {
        //# if vbox-id:
        //# goto anchor and play
        document.location.hash = document.location.hash;

        //# if gallery-anchor:
        //# goto gallery viewport and select gallery item.
    }
});


//-----------------------------------------------------------------------------
// FUNCTIONS
//-----------------------------------------------------------------------------

/* =UTILITY
---------------------------------------------------------------------------- */

// NOTE: the way console.log works is apparently very browser specific. 
// Firefox: console.log.apply(this, args), but only if Firebug's open.
// IE: console.log is object, not function, so apply doesn't work.
// Safari: ???
// Opera: ???
// Because of the various potential problems, wrapping it in an exception block.
function log(format, args) {
    try {
        console.log.apply(this, arguments);
    }
    catch (err) { }
}

// http://stackoverflow.com/questions/1038746/equivalent-of-string-format-in-jquery
String.prototype.format = function () {
    var args = arguments;
    return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) {
        if (m == "{{") { return "{"; }
        if (m == "}}") { return "}"; }
        return args[n];
    });
};

//! Check for flash availability.
/*!
@return	true if flash is available, otherwise false.
@note	Requires swfobject.
*/
function hasFlash() {
    var flash = swfobject.getFlashPlayerVersion();
    return (flash && flash.major);
}

//! Joins an object's key-value pairs together based on an sprintf-like formatstring.
/*!
@param format	Format string. Use "%k" for keys and "%v" for values.
@param obj		Object whose members to join.
@param glue		Separator between items.
*/
function kvjoin2(format, obj, glue) {
    var a = [];
    for (i in obj)
        a.push(format.replace("%k", i).replace("%v", obj[i]));

    return a.join(glue);

}

/* =DRIVERS
---------------------------------------------------------------------------- */

//! Prepare the banner for animations.
function initBanner() {
    var $banner = $('#banner'), $ul = $('.img-cycle', $banner);

    if ($ul.length == 0)
        return;

    var opts = {
        fx: 'fade',
        timeout: 4000,
        speed: 1000,
        pause: 1
    };
    var json = $('._opts', $banner).text();
    $.extend(opts, $.parseJSON(json));
    log(opts);

    $('._opts', $banner).remove();

    // --- Construct actual banner ---
    $ul.wrap('<div id="banner-main">');

    if (opts.nav) {
        $banner.append('<div id="cycle-left" class="cycle-nav"> <a>L</a></div>');
        $banner.append('<div id="cycle-right" class="cycle-nav"> <a>R</a></div>');
        $('#banner-main').addClass('nav');
        opts.next = '#cycle-right';
        opts.prev = '#cycle-left';
    }
    if (opts.pager) {
        $banner.append('<div id="pager-holder"><div id="pager-nav"></div></div>');
        opts.pager = '#pager-nav';
        opts.pauseOnPagerHover = 1;
    }

    $ul.cycle(opts);

    // Collapsable banner. Pauses when collapsed.
    $('#banner-bar').click(function () {
        var $me = $(this);
        $(this).toggleClass('up');
        $banner.slideToggle("slow", function () {
            if ($me.hasClass('up'))
                $ul.cycle('pause');
            else
                $ul.cycle('resume');
        });
    });
}

function initGoogleMaps() {
    $('.gmap').each(function (i, el) {
        var obj = $.parseJSON($('._opts', $(el)).text());
        gmapInsert(el, obj);
    });
}

//! Prepare video buttons and elements.
function initVideos() {
    $('.vbox').each(function (i, el) {
        var $me = $(el), videoId = 'video-' + i;

        $('.preview', $me)
            .wrap('<span id="' + videoId + '" />')
            .after('<span class="play-icon" />')
            .parent()
            .wrap('<a href="#' + videoId + '" />');

        $me.click(function (e) {
            var opts = $.parseJSON($('._opts', $me).text());
            videoInsert(videoId, opts);
            $me.unbind('click');
        });
    });
}

//! Prepare gallery of images and videos.
function initGalleries() {
    //# NOTE: since $thumbs has multiple entries, $ul will too.
    //# OBviously, this is not what was indended, so just using the 
    //# first will have to do for now.
    var $thumbs = $('#gallery').find('.gallery-ithumb, .gallery-vthumb');
    var $ul = $thumbs.closest('ul').eq(0), $main = $ul.parent();

    // --- Prep thumbs ---
    var sumWidth = 0;
    if ($thumbs.length > 0) {
        $thumbs.each(function (i, el) {
            var $me = $(el);
            sumWidth += $me.outerWidth(true);
            $me.click(function () { galSelect($me); });
        });
        galSelect($thumbs.eq(0));
    }

    // Special prep for vthumbs.
    $thumbs.filter('.gallery-vthumb').find('a').append('<span class="play-icon"></span>');

    $ul.width(sumWidth);

    // --- Add nav-elements if container is too small ---
    var docWidth = $ul.width(), viewWidth = $main.width();
    if (viewWidth < docWidth) {
        $right = $('<div class="slider-nav-right"> </div>').insertAfter($main);
        $right.click(function () {
            var newX = $ul.position().left - viewWidth;
            if (newX + docWidth < viewWidth)
                newX = viewWidth - docWidth;

            $ul.animate({ 'left': newX }, 'slow');
        });

        $left = $('<div class="slider-nav-left"> </div>').insertAfter($main);
        $left.click(function () {
            var newX = $ul.position().left + viewWidth;
            if (newX > 0)
                newX = 0;
            $ul.animate({ 'left': newX }, 'slow');
        });
    }
    else		// --- Or center it ---
        $ul.css('left', (viewWidth - docWidth) / 2);
}

// ----------------------------------------------------------------------------

//! Select an image or video item in a gallery
function galSelect($sel) {
    var opts = $.parseJSON($('._opts', $sel).text());
    var $gallery = $sel.closest('.gallery');

    // Switch active item and show it.
    $gallery.find('.active').removeClass('active');
    $sel.find('a').addClass('active');
    var thumbClass = $sel.attr('class');
    if (thumbClass == 'gallery-vthumb') {
        $gallery.find('.view').html('<object id="vplayer"> </object>');
        videoInsert('vplayer', opts);
    }
    else

        $gallery.find('.view').html(
            '<img src="' + opts.src + '" alt="">'
        );
    /*# This centers, but now the image inside won't always fit :(
    $gallery.find('.view').html(
    '<table class="tcenter tmiddle"><tr><td>' + 
    '<img src="' + opts.src + '" alt="">' + 
    '</td></tr></table>'
    );
    */
}

//! Prepare google-map items.
function gmapInsert(el, opts) {
    if (opts.id)
        el.id = opts.id;
    if (opts.height)
        el.style.height = opts.height;
    if (opts.width)
        el.style.width = opts.width;

    if (!opts.zoom)
        opts.zoom = 8;
    if (opts.center)
        opts.center = new google.maps.LatLng(opts.center[0], opts.center[1]);
    opts.mapTypeId = google.maps.MapTypeId.ROADMAP;

    var map = new google.maps.Map(el, opts);
    for (i in opts.markers) {
        var marker = opts.markers[i];
        if (!marker.pos)
            continue;

        marker.position = new google.maps.LatLng(marker.pos[0], marker.pos[1]);
        marker.map = map;

        // --- complex icon ---
        if (marker.iconx) {
            var icon = marker.iconx;
            var src, size, org, anchor;
            src = icon.src;
            if (icon.size)
                size = new google.maps.Size(icon.size[0], icon.size[1]);
            if (icon.org)
                org = new google.maps.Point(icon.org[0], icon.org[1]);
            if (icon.anchor)
                anchor = new google.maps.Point(icon.anchor[0], icon.anchor[1]);

            marker.icon = new google.maps.MarkerImage(src, size, org, anchor);
        }

        var mk = new google.maps.Marker(marker);

        if (marker.info) {
            var content = $("<div/>").html(marker.info).text();
            var info = new google.maps.InfoWindow({
                content: content
            });
            google.maps.event.addListener(mk, 'click', function () {
                info.open(map, this);
            });
        }
    }
}

function videoInsert(id, opts) {
    var HOST_URL = location.protocol + "//" + location.host;
    var PLAYER_URL = HOST_URL + "/mediaplayer";

    var url = opts.src;
    var width = (opts.width ? opts.width : "100%");
    var height = (opts.height ? opts.height : "100%");

    if (hasFlash())		// --- JW-player stuff ---
    {
        var player = PLAYER_URL + "/player.swf";
        var flashvars = {
            file: encodeURIComponent(url),
            width: encodeURIComponent(width),
            height: encodeURIComponent(height),
            skin: encodeURIComponent(PLAYER_URL + "/modieus.swf"),
            controlbar: "over",
            autostart: true
        };

        var params = {
            allowfullscreen: true,
            allowscriptaccess: "always",
            wmode: "opaque"
        };

        var res = swfobject.embedSWF(player, id, width, height, "9.0.0", "",
            flashvars, params);
    }
    else				// --- QT player ---
        $('#' + id).html(QT_GenerateOBJECTText(url, width, height, '', 'scale', 'aspect'));
}

function swfInsert(src, objID, width, height, flashvars) {
    var params = {
        menu: "false",
        scale: "noScale",
        salign: "t",
        allowFullscreen: "true",
        allowScriptAccess: "always",
        bgcolor: "#FFFFFF"
    };
    var attributes = {
        id: "banner-obj"
    };
    swfobject.embedSWF(src, objID, width, height, "9.0.0", "expressInstall.swf",
        flashvars, params, attributes);
}


// EOF

