/*
 * jQuery WMImageStacker
 * Copyright 2009 Wonderful Machine
 * Maintined by Bryan Mills
 *
 * The ImageStacker binds together a list of links (the control list) to lists of images
 *  (stacks) that fade in/out on link hover. Each control list can have multiple stacks
 *  bound to it. Use the 'prefix' option to create namespaces sets of stakcs.
 */



(function($) {

	$.fn.WMImageStack = function(options) {

		// default options
		$.fn.WMImageStack.defaults = {
                        stacks: null,
                        speedOut: 200,
                        speedIn: 200
		}

		// options merge
		var config = $.extend({}, $.fn.WMImageStack.defaults, options)

                // private properties
                var loaded = [];
                var images = [];
                var ajaxRunning = false;
                var lists = $(config.lists)
                var stacks = $(config.stacks);
                var t; // global setTimeout used for effect interrupt


		return initStack();


		// private members
		function initStack() {

                    hideAllVisible();

                    // load a reference for each image and attach an onImagesLoad callback to each set
                    lists.each(function() {
                        $(this).find('a').each(function() {
                            var key = $(this).attr('rel');
                             if (key !== '') {
                                images[key] = $("." + key);
                              }

                            $(this).hover(function() {
                                if ($(this).attr('rel') == 'ignore') {
                                 return;
                                }

                                if ( $.inArray($(this).attr('rel'), getActive()) == -1 ) {
                                    transitionTo($(this).attr('rel'));
                                    clearActive($(this).closest('ul'));
                                    clearActive($('#photographer-specialties')); // TODO: un-hardcode
                                    $(this).parent().addClass('active');
                                }
                            }, function() {

                            });
                        });
                    });

                    showActiveImages();


                }

                function transitionTo(key) {

                    // interrupt any transition in process
                    clearTimeout(t);

                    // set a slight delay before starting new transition
                    t = setTimeout(function() {

                        // fade out active image
                        fadeAllVisible(key);

                        // get all image paths for images that we're showing
                        // if the image doesn't exist at page load, add it to the ajax fetch queue
                        var sources = [];
                        var loadQueue = [];
                        if (typeof(images[key]) !== "undefined") {
                            images[key].each(function(i) {

                                var img = $(this).find('img');
                                if (img.length > 0 ) {
                                    sources[i] = img.attr('src');
                                } else if (key.indexOf("-stack") == -1) {
                                    loadQueue[i] = images[key];
                                }
                            });

                            // check to see if each image is loaded, fade it in
                            for (var i=0; i<sources.length; i++) {
                                if (typeof(sources[i]) !== 'undefined') {
                                    setTimeout(function() {
                                        images[key].fadeIn(config.speedIn);
                                    }, 200);
                                }
                            }

                            // load images via ajax if necessary
                            for (var i=0; i<loadQueue.length; i++) {
                                ajaxImage(loadQueue[i]);
                            }
                        }



                   }, 100);


                }

                function ajaxImage(elem) {

                    var url = "/api/images/" + elem.attr('id');
                    $.ajax({
                        type: 'GET',
                        url: url,
                        dataType: 'html',
                        beforeSend: function() {
                            $('#loading-indicator p').text('loading');
                            $('#loading-indicator').fadeIn(200);
                        },
                        success: function(data){
                            $('#loading-indicator').fadeOut(200, function() {

                                // call should return a single html image element
                                // if '<img' doesn't exit, its probably a Zend error message

                                if (data.indexOf('<img') == 4) {
                                    $(this).hide();
                                    elem.find('a').html(data);
                                    fadeAllVisible(elem.attr('class'));
                                    elem.fadeIn(config.speed);
                                } else {
                                    ajaxError();
                                }
                            });
                        },
                        error: function(xhr, status, error) {
                            ajaxError();
                        }
                    })

                }

                function ajaxError() {
                    $('#loading-indicator p').text('error...').show();
                    $('#loading-indicator').fadeIn(200);
                    setTimeout(function() { $('#loading-indicator').fadeOut(200)}, 2000);

                }


                function showActiveImages() {

                    var active = getActive();


                    for (var i=0; i<active.length; i++) {
                        var img = images[active[i]];
                        if (typeof(img) !== "undefined") {
                            img.each(function() { $(this).show(); });
                        }
                    }
                }

                function hideAllVisible() {
                    stacks.each(function() {
                       $(this).find("li:not('#photographer-specialties ul li')").hide();
                    });
                }

                function fadeAllVisible(key) {
                    stacks.each(function() {
                        // TODO: avoid a hardcode echeck for the 'stack' string to prevent specialties from disappearing the entire image set on hover
                       if (typeof(images[key]) == "undefined" || images[key].find('a img').length == 0) {
                            return;
                       } else if (key.indexOf("-stack") == -1) {
                            $('#col-right .inner li:visible').fadeOut(config.speedOut);

                       } else {
                            $(this).find("li:visible:not('#photographer-specialties ul li')").fadeOut(config.speedOut);
                       }
                    });
                }

                function clearActive(list) {
                    list.find('li.active').removeClass('active');

                    // if there is a sibling list, clear it there, too
                    var next = list.next('ul.photographer-list');
                    if (next.find('.active').length > 0) {
                        clearActive(next);
                    }

                    var prev = list.prev('ul.photographer-list');
                    if (prev.find('.active').length > 0) {
                        clearActive(prev);
                    }



                }

                function getActive() {
                   var active = []
                   lists.each(function(i) {
                       active[i] = $(this).find('li.active a').attr('rel');
                   });
                   return active;
                }
	}

}(jQuery));
