/**
 * Slides and maps widget
 *
 * Internal data model:
 * {
 *     pictures: [
 *         {
 *             url: '/i/pic1.jpg',
 *             width: 360,
 *             height: 240
 *         }, {
 *             ...
 *         }
 *     ],
 *     thumbnails: [
 *         ...			 
 *     ]
 * }
 *
 * Since version 1.1 it designed to be caused as function or through 'new' statement.
 *
 * @version 1.1
 * @author Mista K.
 */

(function () {
    /**
     * Constructor
     *
     * @param  target  {DomNode}
     * @param  model   {Object}
     */
    TRAVEL.Slides = function (target, targetSelector, model) {

        var assets = TRAVEL.Assets.Slides;

        // private fields and methods
        // widget holder
        var root = target;
        var rootSelector = targetSelector;
		// position of curent picture
        var position = 0;
		// total items in slideline
        var totalItems;
		// slideline width
        var totalWidth;
		// width of slideline's container
        var wrapperWidth;

        // inherit Observable
        var self = TRAVEL.Observable2();

        /**
         * Set picture positions according offset and it's width
         *
         * @param  offset  {Integer}  Slideline offset
         * @return         {Integer}  Slideline width
         */
        function setPosition(offset) {
            var x = offset;
            var items = $(".slideline", root).children();
            for (var i = 0; i < items.length; i++) {
                $(items.get(i)).css("left", x);
                x = x + $(items.get(i)).width() + 3;
            }
            return x - 3;
        }

        /**
         * Update slideline position and enable/disable control gadgets
         *
         * @param  option  {Integer}  Prefered direction: -1 - prev, 1 - next, 0 - no preferences
         */
        function update(option) {
            var ele, items, targetItem, x0, x1, x2;
            var direction = option || 0;
            var targetPosition = position + direction;

            if (targetPosition >= totalItems || targetPosition < 0) {
                targetPosition = position;
                direction = 0;
            }
	
            // enable or disable controls
            ele = $(".navigate li.prev span", rootSelector);
            if (position === 0) {
                ele.addClass("disabled");
            } else {
                ele.removeClass("disabled");
            }

            ele = $(".navigate li.next span", rootSelector);
            if (position === totalItems - 1) {
                ele.addClass("disabled");
            } else {
                ele.removeClass("disabled");
            }

            $("div.fullsize", root).html(['<img class="picture" src="', model.pictures[position].url, '" ',
                'width="', model.pictures[position].width, '" height="', model.pictures[position].height, '" alt="Fullsize image" />'].join(''));

            if (totalWidth > wrapperWidth) {
                items = $(".slideline", root).children();
                targetItem = items.get(targetPosition);
                x0 = $(items.get(0)).position().left;
                x1 = $(targetItem).position().left;
                x2 = x1 + $(targetItem).width();

                if (x1 < 0) {
                    setPosition(x0 - x1);
                } else if (x2 > wrapperWidth) {
                    setPosition(x0 - x2 + wrapperWidth);
                }
            }

            self.notify('changePicture', position);
        }

        /**
         * "Previous" gedget click listener
         */
        function previousItem() {
            if (! $(this).hasClass("disabled")) {
                position--;
                update(-1);
            }
        }

        /**
         * "Next" gedget click listener
         */
        function nextItem() {
            if (! $(this).hasClass("disabled")) {
                position++;
                update(1);
            }
        }

        /**
         * "onItem" click listener
         */
        function chooseItem() {
            var dir, i = $.inArray(this, $(".slideline", root).children());
            if (i >= 0) {
                dir = (i === position) ? 0 : ((i > position) ? 1 : -1);
                position = i;
                update(dir);
            }
        }

        /**
         * Create widget
         */
        (function () {
            var obj;

            totalItems = Math.min(model.pictures.length, model.thumbnails.length);

            obj = ['<ul class="navigate navigate-slides', (totalItems <= 1 ? ' hidden' : ''), '">',
                    '<li class="prev"><span unselectable="on">', assets.prev, '</span></li>',
                    '<li class="next"><span unselectable="on">', assets.next, '</span></li>',
                '</ul>'];

            $(rootSelector).append(obj.join(''));

            obj = ['<div class="slideline', (totalItems <= 1 ? ' hidden' : ''), '">'];
            for (var i = 0; i < totalItems; i++) {
                obj.push('<img class="picture" src="', model.thumbnails[i].url, '" width="', model.thumbnails[i].width, '" height="', model.thumbnails[i].height, '" alt="Thumbnail" />');
            }
            obj.push('</div>');

            obj.push('<div class="fullsize-wrapper clearer"><div class="fullsize"></div></div>');

            $(root).append(obj.join(''));

            $(".navigate .prev span", rootSelector).click(previousItem);
            $(".navigate .next span", rootSelector).click(nextItem);
            $(".slideline", root).children().click(chooseItem);

            wrapperWidth = $(".slideline", root).width();
            totalWidth = setPosition(0);
            update();
        })();

        return self;
    };
})();