/*
 * jQuery Promotion Plugin for Noeastro, v0.2
 * Requires jQuery 1.4.2 and jQuery Templates Plugin 1.0.0pre
 *
 * Author: Martin Gamnitzer (kontakt@martin-gamnitzer.de)
 * Date: Jul 26 10:14:48 2011 +0100
 *
 * Hinweise zu Benutzung:
 *
 * Das HTML ben??tigt lediglich einen Platzhalter (hier: <div id="promotionbox"></div> ).
 * Alle weiteren Inhalte werden durch das JavaScript eingef??gt, eventuelle
 * Template-??nderungen m??ssen hier vorgenommen werden.
 *
 * Der Aufruf erfolgt dann ??ber den bekannten Plugin-Syntax: jQuery('#promotionbox').promotion();
 * Dabei lassen sich das zu lesende XML-File, die Geschwindigkeit der Animation und die Pause zwischen
 * den automatischen Schritten optional festlegen:
 *
 * jQuery('#promotionbox').promotion({
 *     xmlPath : '/text.xml',  // absolute path to xml file, must have same domain
 *     slidertime: 400,        // animation speed in ms 
 *     sliderpause: 6000      // time between animation in ms
 *  });
 *
 */




(function($) {

        $.fn.promotion = function(userOptions) {

            var parent = $(this);
            var defaults = {
                xmlPath : '/noe/text.xml',
                slidertime: 400,
                sliderpause: 6000
            };
            var options = $.extend(defaults,userOptions);

            //var xmlPath = '/text.xml';
            var current = 0;
            var amount = 0; //total number of elelments.
            var last = 0; //amount -1
            var slides = new Array();
            var tmpl_headline = '<div id="prom_headline" class="png"><h1>${headline}</h1></div>';
            var tmpl_menu = '<div class="prom_menu png"><div>${title}</div></div>';
            var tmpl_content = '<div class="prom_content"><a href="${link}"><img class="prom_image" src="${image}" /><div class="prom_text png"><span class="png">${text}</span></div></a></div>';
            var menuOuter = $('<div id="prom_menuOuter"></div>');
            var contentOuter = $('<div id="prom_contentOuter"></div>');
            var contentbox = $('<div id="prom_contentbox"></div>');
            var nextButton = $('<div class="prom_nextButton png"></div>');
            var prevButton = $('<div class="prom_prevButton png"></div>');
            var menuItemWidth = 121;
            var contentWidth = 483;
            //var slidertime = 500;//ms
            //var sliderpause = 6000;//ms
            var lock = false;
            var menusInView = new Array(0,1,2,3);
            var userMoved = 0;

            $.template("headlineTemplate", tmpl_headline);
            $.template("menu", tmpl_menu);
            $.template("content", tmpl_content);

            //load texts from XML
            $.ajax({
                type: "GET",
                url: options.xmlPath,
                dataType: "xml",
                success: function(xml) {
                    buildSlider(xml);
                }
            });

            function  buildSlider(xml) {
                var menuList = new Array();
                var contentList = new Array();
                //translate header from xml into object
                var headline = { headline: $(xml).find('headline').text() };
                $.tmpl("headlineTemplate", headline).appendTo(parent);           

                $(xml).find('item').each(function() {
                    menuList.push({title : $(this).children('header').text()});
                    contentList.push({
                        image: $(this).children('image').text(),
                        link: $(this).children('link').text(),
                        text: $(this).children('text').text()
                    });
                });
                $.tmpl("menu", menuList).appendTo(menuOuter);
                $.tmpl("content", contentList).appendTo(contentOuter);
                parent.append(contentbox.append(menuOuter).append(contentOuter));

                //anordnen der Elemente zu Beginn
                menuOuter.children().eq(0).css({left:0}).addClass('prom_menuActive');
                menuOuter.children().eq(1).css({left:'121px'});
                menuOuter.children().eq(2).css({left:'242px'});
                menuOuter.children().eq(3).css({left:'363px'});
                contentOuter.children().eq(0).css({left:0});
                amount = contentOuter.children().length;            
                last = amount -1;


                //center texts in menu vertically, still a mess with cross-browser CSS
                menuOuter.children().each(function() {
                    var myPad = Math.abs((43 - $(this).children().innerHeight()) / 2);
                    $(this).children().css('padding-top', myPad+'px');
                });
                //add click-trigger to menu
                menuOuter.children().each(function() {
                    $(this).click(function() {
                        //find indexes of current and this and select direction
                        var pos = $(this).prevAll().length;
                        if(menusInView.findIndex(current) - menusInView.findIndex(pos) < 0)
                            var dir = 1;
                        else
                            var dir = -1;
                        sliderMoveTo(pos,dir);
                        //block autorunner and start again
                        userMoved++;
                        run();
                    });
                });

                //add Buttons
                if(amount > 4)
                    contentbox.append(nextButton).append(prevButton);
                
                //run!!
                run();
            }
            
            function getNext(c) {
                if(c==null) c=current;
                return c == last ? 0 : c+1;
            }

            function getPrev(c) {
                if(c==null) c=current;
                return c == 0 ? last : c-1;
            }

            nextButton.click(function() {
                sliderMoveTo(getNext());
                //block autorunner and start again
                userMoved++;
                run();
            });
            
            prevButton.click(function() {
                sliderMoveTo(getPrev(), -1);
                //block autorunner and start again
                userMoved++;
                run();
            });
            
            function sliderMoveTo(pos,dir) {
                if(lock) return;
                lock = true;
                if(dir != 1 && dir != -1) dir = 1;
                menuOuter.children().removeClass('prom_menuActive');
                checkMenus(pos,dir);
                //if (dir == 1)
                var posDiff = current - pos;
                var overflow = false;
                if((posDiff > 0 && dir == 1) || (posDiff < 0 && dir == -1)) {
                    posDiff -= dir * amount;
                    overflow = true;
                }
                var from = {property: 0};
                var to = {property: posDiff * contentWidth};
                $(from).animate(to, {
                    duration: options.slidertime,
                    step: function() {
                        var j = 0;
                        var prop = this.property;
                        if(dir == 1) {
                            var i = current;
                            var notme = getNext(pos);
                            while(i != notme) {
                                if((!overflow && i >= current && i <= pos) || (overflow && (i >= current || i <= pos))) {
                                    var n =  prop + (j * contentWidth);
                                    contentOuter.children().eq(i).css({left:n+'px'});
                                    j++;
                                }
                                i = i==last ? i=0 : i+1;
                            }
                        } else {
                            var i = current;
                            var notme=getPrev(pos);
                            while(i != notme) {
                                if((!overflow && i <= current && i >= pos) || (overflow && (i <= current || i >= pos))) {
                                    var n =  prop - (j * contentWidth);
                                    contentOuter.children().eq(i).css({left:n+'px'});
                                    j++;
                                }
                                i = i==0 ? i=last : i-1;
                            }
                        }

                    },
                    complete: function() {
                        //final position;
                        contentOuter.children().css({left:'800px'});  
                        contentOuter.children().eq(pos).css({left:0});  
                        current = pos;
                        lock = false;
                        menuOuter.children().eq(current).addClass('prom_menuActive');
                    }
                }); //animate end


            }

            function checkMenus(pos,dir) {
                if(menusInView.in_array(pos))
                    return;

                var starter = menusInView[0];
                var from = {property: 0};
                var to = {property: -1 * dir * contentWidth};
                $(from).animate(to, {
                    duration: options.slidertime,
                    step: function() {
                        var prop = this.property;
                        if(dir==1) {
                            for(var i=0; i<8;i++) {
                                var n = prop + (i * menuItemWidth);
                                var m = starter+i <= last ? starter+i : starter+i-amount;
                                if(n >= -121 && n <= 604)
                                    menuOuter.children().eq(m).css({left:n+'px'});
                            }
                        } else {
                            for(var i=3; i>=-4;i--) {
                                var n = prop + (i * menuItemWidth);
                                var m = starter+i <= last ? starter+i : starter+i-amount;
                                if (m<0) m += amount;
                                if(n >= -121 && n <= 604)
                                    menuOuter.children().eq(m).css({left:n+'px'});
                            }
                        }
                    },
                    complete: function() {
                        menuOuter.children().css({left:'800px'});
                        //create new array
                        if(dir == 1) {
                            for(var i=0; i<4; i++) {
                                menusInView[i] = starter+i+4;
                                while(menusInView[i] > last)
                                  menusInView[i] = menusInView[i]-amount;
                                var mypos = i*menuItemWidth;
                                menuOuter.children().eq(menusInView[i]).css({left:mypos+'px'});
                            }
                        } else {
                            for(var i=0; i<4; i++) {
                                menusInView[i] = starter+i-4 >= 0 ? starter+i-4 : starter+i-4+amount;
                                var mypos = i*menuItemWidth;
                                menuOuter.children().eq(menusInView[i]).css({left:mypos+'px'});
                            }
                        }
                        
                    }
                });

            }


            function run() {
                window.setTimeout(function() {
                    if(userMoved > 0) {
                      userMoved--;
                      return;
                    }
                    sliderMoveTo(getNext());
                    run();
                }, options.sliderpause);


            }

        };

})(jQuery);


//extending the Array Object to support in_array method
Array.prototype.in_array = function(needle) {
for(var i=0; i < this.length; i++) if(this[ i] === needle) return true;
return false;
}
Array.prototype.findIndex = function(value){
var ctr = "";
for (var i=0; i < this.length; i++) {
// use === to check for Matches. ie., identical (===), ;
if (this[i] == value) {
return i;
}
}
return ctr;
};

