/*
---
script: rotater.js
description: MGFX.Rotater, the base class that provides slides and transitions. 
authors: Sean McArthur (http://mcarthurgfx.com) 
license: MIT-style license 
requires:
 core/1.2.4: '*'
 more/1.2.4.1: [Fx.Elements]
provides: [MGFX.Rotater]
...
*/

//MGFX.Rotater. Copyright (c) 2008-2010 Sean McArthur <http://mcarthurgfx.com/>, MIT Style License.

var MGFX = MGFX || {};

MGFX.Rotater = new Class({

    Implements: [Options, Events],

    options: {
        slideInterval: 5000,
        transitionDuration: 1000,
        startIndex: 0,
        autoplay: true,
        hover: false,
        hash: true,
        onAutoPlay: function () { },
        onRotate: function () { },
        onShowSlide: function () { },
        onStop: function () { },
        onPause: function () { },
        onResume: function () { }
    },

    initialize: function (slides, options) {
        this.setOptions(options);
        this.slides = $$(slides);
        this.createFx();
        this.showSlide(this.options.startIndex);
        if (this.slides.length < 2) this.options.autoplay = false;
        if (this.options.autoplay) this.autoplay();
        return this;
    },

    createFx: function () {
        if (!this.slideFx) this.slideFx = new Fx.Elements(this.slides, { duration: this.options.transitionDuration, link: 'cancel' });
        this.slides.each(function (slide) {
            slide.setStyles({
                'opacity': 0,
                'display': 'block'
            });
        });
    } .protect(),

    setupHover: function () {
        var _timeLastRotate = new Date(),
			_timeLastPause,
			_timeTillRotate = this.options.slideInterval,
			_resumeDelay;

        var onRotate = this._onRotate = function () {
            if (this.slideshowInt) {
                _timeLastRotate = new Date();
                _timeTillRotate = this.options.slideInterval;
            }
        };
        var onMouseEnter = this._onMouseEnter = function () {
            this.stop();
            _timeLastPause = new Date();
            clearInterval(_resumeDelay);
            this.fireEvent('onPause');
        } .bind(this);

        var onMouseLeave = this._onMouseLeave = function () {
            var timePassed = (_timeLastPause - _timeLastRotate);
            _timeLastRotate = new Date() - timePassed;
            _resumeDelay = (function () {
                this.autoplay();
                this.rotate();
                this.fireEvent('onResume');
            }).delay(_timeTillRotate - timePassed, this);
        } .bind(this);

        this.addEvent('onRotate', onRotate);
        this.slides.addEvents({
            'mouseenter': onMouseEnter,
            'mouseleave': onMouseLeave
        });
    } .protect(),

    removeHover: function () {
        this.removeEvent('onRotate', this._onRotate);
        this.slides.removeEvents({
            'mouseenter': this._onMouseEnter,
            'mouseleave': this._onMouseLeave
        });
    },

    showSlide: function (slideIndex) {
        if (slideIndex == this.currentSlide) return this;
        var action = {};
        this.slides.each(function (slide, index) {
            if (index == slideIndex && index != this.currentSlide) { //show
                action[index.toString()] = {
                    opacity: 1
                };
                slide.setStyle('z-index', 1);
            } else {
                action[index.toString()] = {
                    opacity: 0
                };
                slide.setStyle('z-index', 0);
            }
        }, this);
        this.fireEvent('onShowSlide', slideIndex);
        this.currentSlide = slideIndex;
        this.slideFx.start(action);
        return this;
    },

    autoplay: function () {
        if (this.options.hover) this.setupHover();
        this.slideshowInt = this.rotate.periodical(this.options.slideInterval, this);
        this.fireEvent('onAutoPlay');
        return this;
    },

    stop: function (not_pause) {
        clearInterval(this.slideshowInt);
        this.fireEvent('onStop');
        if (not_pause && this.options.hover) this.removeHover();
        return this;
    },

    rotate: function () {
        var current = this.currentSlide;
        var next = (current + 1 >= this.slides.length) ? 0 : current + 1;
        this.showSlide(next);
        this.fireEvent('onRotate', next);
        return this;
    }

});


/*
---
script: tabs.js
description: MGFX.Tabs, extension of base class that adds tabs to control the rotater. 
authors: Sean McArthur (http://mcarthurgfx.com) 
license: MIT-style license 
requires:
 core/1.2.4: '*'
 more/1.2.4.1: [Fx.Elements]
provides: [MGFX.Tabs]
...
*/

//MGFX.Tabs. Copyright (c) 2008-2010 Sean McArthur <http://mcarthurgfx.com/>, MIT Style License.

var MGFX = MGFX || {};

MGFX.Tabs = new Class({
	
	Extends: MGFX.Rotater,
	
	options: {
		autoplay: false,
		onShowSlide: function(slideIndex) {
			this.tabs.removeClass('active');
			this.tabs[slideIndex].addClass('active');
		},
		tabIsLink: false
	},
	
	initialize: function(tabs, slides, options){
		this.setOptions(options);
		this.tabs = $$(tabs);
		this.createTabs(options.tabIsLink);
		if(this.options.hash && window.location.hash) {
			var hash = window.location.hash.substring(1);
			this.tabs.each(function(el, index) {
				if(el.get('id') == hash) {
					options.startIndex = index;
				}
			});
		}
		return this.parent(slides,options);
	},
	
	createTabs: function (isLink) {
	    if (!isLink)
		{
		    this.tabs.each(function(tab,index){
		        tab.addEvent('click', function(event){ 
			        event.preventDefault();
			        this.showSlide(index);
			        this.stop(true);
		        }.bind(this));
		    }.bind(this));
		}
	}.protect()
	
});


//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************

moopupGallery = new Class({
	Implements: [Options, Events, Chain],
	options: {
		index               : 0,
		arr_mini_src        : [],
		arr_full_src        : [],
		arr_alt_txt         : [],
        autoplay            : false,
		autoplay_time       : 5, // in seconds
        autoplay_timer      : null,
        current_img         : null,
        settings            : {
            nav_opacity_max : 1,
		    nav_opacity_min : 0.7,
		    back_opacity    : 0.85,
		    gallery_offset  : 140,
		    nav_offset      : 20,
		    arrow_offset_min: 0,
		    arrow_offset_max: -5000,
		    mini_border_up  : '#8A8986',
		    mini_border_over: '#FFFFFF'
        },
        src                 : {
            play            : '/img/popup_play.gif',
		    stop            : '/img/popup_stop.gif',
            arrow_left      : '/img/popup_arrow_left.gif',
		    arrow_right     : '/img/popup_arrow_right.gif',
            close           : '/img/popup_close.gif'
        },
        lang                : { 
	 	    left            : 'Влево',
            right           : 'Вправо',
            play            : 'Слайд-шоу',
            close           : 'Закрыть',
            of              : 'из',
            show_original   : 'открыть оригинал'
		},
        html                : {
	       popup_back       : null,
		   popup_nav        : null,
		   popup_img        : null, 
		   output_counter   : null,
		   left_btn         : null,
		   right_btn        : null,
		   mini_nav         : null,
		   play_btn         : null,
           close_btn        : null,
		   mini_gllr_cont   : null,
		   mini_gllr        : null
        }
        /*
		onInit              : function() {},   // fire when 
        onStart             : function() {},   // fire when 
		onChangeStart       : function() {},   // fire when 
        onChangeComplete    : function() {},   // fire when 
        onClose             : function() {}    // fire after the moopupGallery is closed (destroyed)
        
        arr_mini_img        : [],       // внутренний массив для мини-изображений
        ready               : true,     // флаг готовности к смене изображения
        this_class          : null,     // внутренний доступ к текущему классу
        abroad              : false     // флаг выхода изображения за границы видимой области
        */
	},
	initialize: function(options){
		this.setOptions(options); // присвоим index, arr_mini_src, arr_full_src, arr_alt_txt
		this.fireEvent('onInit'); // присвоим событие onInit если задано
		
        var _tc = this.options.this_class = this; // для глобального доступа
        var _tc_o = _tc.options;

        if (_tc_o.arr_full_src.clean().length == 0 || _tc_o.arr_full_src.clean().length == 0)
		{
			alert('Один из массивов изображений пустой');
			return false;
		}
        
        _tc.prepareHtml();
		_tc_o.ready = true;
        _tc.initShow();
        _tc.initEvents();
        _tc.changeImage();
			
		if (_tc_o.autoplay == true) _tc.autoplayStart(); // запустим слайд-шоу
	},
    prepareHtml: function()
	{
        var _tc = this.options.this_class;
        var _tc_o = _tc.options;
        var _tc_html = _tc.options.html;
        var _tc_s = _tc.options.settings;
        
        //    <div id="popup_back"></div>
        //    <div id="popup_img"></div>
        //    <div id="popup_nav">
        //        <img alt="Left" class="l" src="/img/popup_arrow_left.gif"/>
        //        <p class="counter"></p>
        //        <img alt="Right" class="r" src="/img/popup_arrow_right.gif"/>
        //        <p class="cb"></p>
        //        <div class="mini_gallery_container">
        //            <div class="mini_gallery">
        //            </div>
        //        </div>
        //        <p class="mini_nav">
        //            <img class="play" alt="SlideShow" src=""/>
        //            <img class="close" alt="Close" src="/img/popup_close.gif"/>
        //        </p>
        //    </div>

        _tc_html.popup_back = new Element('div', {'class':'popup_back'}).setStyle('opacity', _tc_s.back_opacity).inject(document.body);
		_tc_html.popup_img = new Element('div', {'class':'popup_img'}).inject(document.body);
        _tc_html.popup_nav = new Element('div', {'class':'popup_nav'}).inject(document.body);
        
		_tc_html.left_btn = new Element('img', {'class':'l',alt:_tc_o.lang.left,src:_tc_o.src.arrow_left}).inject(_tc_html.popup_nav);
        _tc_html.output_counter = new Element('p', {'class':'counter'}).inject(_tc_html.popup_nav);
		_tc_html.right_btn = new Element('img', {'class':'r',alt:_tc_o.lang.right,src:_tc_o.src.arrow_right}).inject(_tc_html.popup_nav);
        new Element('p', {'class':'cb'}).inject(_tc_html.popup_nav);
        _tc_html.mini_gllr_cont = new Element('div', {'class':'mini_gallery_container'}).inject(_tc_html.popup_nav);
		_tc_html.mini_gllr = new Element('div', {'class':'mini_gallery'}).inject(_tc_html.mini_gllr_cont);
		_tc_html.mini_nav = new Element('div', {'class':'mini_nav'}).inject(_tc_html.popup_nav).setStyles({'opacity': 0});
		_tc_html.play_btn = new Element('img', {'class':'play','alt':_tc_o.lang.play,'src':_tc_o.src.play}).inject(_tc_html.mini_nav);
		_tc_html.close_btn = new Element('img', {'class':'close','alt':_tc_o.lang.close,'src':_tc_o.src.close}).inject(_tc_html.mini_nav);

        _tc_o.arr_mini_src.each(function(mini_src, i){
			new Element('p').setStyles({
				'background': _tc_s.mini_border_up + ' url(' + mini_src + ') no-repeat 50% 50%',
				'border': '1px solid ' + _tc_s.mini_border_up
			}).inject(_tc_html.mini_gllr);
		});
		_tc_o.arr_mini_img = _tc_html.mini_gllr.getChildren('p');
    }.protect(),
	initShow: function()
	{
		this.fireEvent('onStart'); // присвоим событие onStart если задано

		var _tc = this.options.this_class;
        var _tc_o = _tc.options;
        var _tc_html = _tc.options.html;
        var _tc_s = _tc.options.settings;

		// покажем галерею
		$$(_tc_html.popup_back, _tc_html.popup_nav, _tc_html.popup_img).setStyle('display', 'block');
		
        // расстянем фон на весь экран
		if (_tc_html.popup_back.getHeight().toInt() < window.getScrollSize().y)
			_tc_html.popup_back.setStyle('height', window.getScrollSize().y);
			
		// зададим координаты
		_tc_html.popup_nav.setStyles({
			'top': _tc_s.nav_offset + window.getScroll().y,
			'left': window.getSize().x/2 - _tc_html.popup_nav.getWidth().toInt()/2 + window.getScroll().x
		});
		_tc_html.popup_img.setStyles({
			'top': _tc_s.gallery_offset + window.getScroll().y,
			'left': 
                _tc_o.current_img ? 
                window.getSize().x/2 - _tc_o.current_img.width/2 + window.getScroll().x : 
                window.getSize().x/2 - _tc_html.popup_img.getStyle('width').toInt()/2 + window.getScroll().x
		});
			
		// зададим ширину минигалереи и начальные координаты
		_tc_html.mini_gllr.setStyles({
			'width': _tc_o.arr_mini_img.length * 
					(_tc_o.arr_mini_img[0].getWidth() + 
					_tc_o.arr_mini_img[0].getStyle('margin-left').toInt() +
					_tc_o.arr_mini_img[0].getStyle('margin-right').toInt() + 2), // +2 для ие6, да-да ие гавно
			'left': _tc_html.mini_gllr_cont.getWidth()/2 -
					_tc_o.arr_mini_img[_tc_o.index].offsetLeft - 
					_tc_o.arr_mini_img[_tc_o.index].getWidth()/2
		});
	}.protect(),
    initEvents: function()
	{
        var _tc = this.options.this_class;
        var _tc_o = _tc.options;
        var _tc_html = _tc.options.html;
        var _tc_s = _tc.options.settings;

        // присвоим события для мини-изображений
        _tc_o.arr_mini_img.each(function(p, i){
			p.addEvents({
				'click': function(){
					if (!_tc_o.ready || _tc_o.autoplay) return false;
					else if (_tc_o.index != i)
					{
						if (!_tc_o.ready) return false;
						_tc_o.index = i;
						_tc.changeImage();
					}
				},
				'mouseenter': function(){
					if (_tc_o.autoplay) return false;
					this.set('tween', {transition: 'cubic:out', duration: 300}).tween('border-color', _tc_s.mini_border_over);
				},
				'mouseleave': function(){
					if (_tc_o.index != i)
						this.set('tween', {transition: 'cubic:out', duration: 300}).tween('border-color', _tc_s.mini_border_up);
				}
			});
		});
        
        // присвоим функции кнопкам навигации
		_tc_html.left_btn.addEvent('click', function(){
			if (!_tc_o.ready) return false;
			_tc_o.index--;
			_tc.changeImage();
		});
		_tc_html.right_btn.addEvent('click', function(){
			if (!_tc_o.ready) return false;
			_tc_o.index++;
			_tc.changeImage();
		});
		_tc_html.close_btn.addEvent('click', function(){
			_tc.close();
		});
		_tc_html.play_btn.addEvent('click', function(){
			if (this.getProperty('src') == _tc_o.src.stop) _tc.autoplayStop(); //остановим слайд-шоу
			else _tc.autoplayStart(); // запустим слайд-шоу
		});
			
		// спрячем кнопки мини_навигации
		_tc_html.popup_nav.addEvent('mouseenter', function(){
			_tc_html.mini_nav.fade('in');
		});
		_tc_html.popup_nav.addEvent('mouseleave', function(){
			_tc_html.mini_nav.fade('out');
		});
			
		// зададим эффект при наведении на кнопки навигации
		$$([_tc_html.popup_nav.getChildren('img'), _tc_html.play_btn, _tc_html.close_btn].flatten())
            .setStyle('opacity', _tc_s.nav_opacity_min)
            .addEvents({
			    'mouseenter': function(){
				    this.set('tween', {transition: 'cubic:out', duration: 300}).tween('opacity', _tc_s.nav_opacity_max);
			    },
			    'mouseleave': function(){
				    this.set('tween', {transition: 'cubic:out', duration: 300}).tween('opacity', _tc_s.nav_opacity_min);
			    }
		    }
        );
    }.protect(),
	changeImage: function()
	{
		this.fireEvent('onChangeStart'); // присвоим событие onChangeStart если задано

		var _tc = this.options.this_class;
        var _tc_o = _tc.options;
        var _tc_html = _tc.options.html;
        var _tc_s = _tc.options.settings;
			
		_tc_o.ready = false; // не реагировать на действия пользователя, пока не загрузится изображение
			
		if (_tc_o.index < 0)
		{
			_tc_o.index = 0;
			return false;
		}
		else if (_tc_o.index >= _tc_o.arr_full_src.length)
		{
			_tc_o.index = _tc_o.arr_full_src.length-1;
			return false;
		}
			
		if (_tc_o.autoplay == false)
		{
			if (_tc_o.index == 0) _tc_html.left_btn.setStyle('top', _tc_s.arrow_offset_max);
			else if (_tc_o.index > 0) _tc_html.left_btn.setStyle('top', _tc_s.arrow_offset_min);
			if (_tc_o.index < _tc_o.arr_full_src.length-1) _tc_html.right_btn.setStyle('top', _tc_s.arrow_offset_min);
			else if (_tc_o.index == _tc_o.arr_full_src.length-1) _tc_html.right_btn.setStyle('top', _tc_s.arrow_offset_max);
		}
			
		// выделим текущее изображение в минигалерее
		_tc_o.arr_mini_img.set('tween', {transition: 'cubic:out', duration: 300}).tween('border-color', _tc_s.mini_border_up);
		_tc_o.arr_mini_img[_tc_o.index].set('tween', {transition: 'cubic:out', duration: 300}).tween('border-color', _tc_s.mini_border_over);
			
		// прокрутим минигалерею на текущее изображение
		_tc_html.mini_gllr.set('tween', {duration: 500}).tween('left', 
			_tc_html.mini_gllr_cont.getWidth()/2 -
			_tc_o.arr_mini_img[_tc_o.index].offsetLeft - _tc_o.arr_mini_img[_tc_o.index].getWidth()/2
		);
			
		_tc_html.popup_img.empty(); // почистим от всех дочерних элементов
		_tc_html.output_counter.set('html', (_tc_o.index+1) + ' ' + _tc_o.lang.of + ' ' + _tc_o.arr_full_src.length); // напишем текущий номер
			
        _tc_o.abroad = false;

		// покажем изображение
		_tc_o.current_img = new Asset.image(_tc_o.arr_full_src[_tc_o.index], {
			alt: _tc_o.arr_alt_txt[_tc_o.index] ? _tc_o.arr_alt_txt[_tc_o.index] : '',
			onload: function(){
				_tc_html.popup_nav.setStyles({
					'top': _tc_s.nav_offset + window.getScroll().y,
					'left': window.getSize().x/2 - _tc_html.popup_nav.getWidth()/2 + window.getScroll().x
				});

                // посчитаем доступную зону просмотра
                var available_width = window.getSize().x - 100;
                var available_height = window.getSize().y - 100 - _tc_s.gallery_offset;

                // если изображение вылазит за границы доступной зоны, то меняем размеры
                if (_tc_o.current_img.width > available_width || _tc_o.current_img.height > available_height)
                {
                    _tc_o.abroad = true;

                    var new_width, new_height;

                    var new_ratio = available_width / available_height;
                    var original_ratio = _tc_o.current_img.width / _tc_o.current_img.height;

                    if (new_ratio > original_ratio)
                    {
                        new_height = available_height;
                        new_width = Math.floor(original_ratio * available_height);
                    }
                    else
                    {
                        new_height = Math.floor(available_width / original_ratio);
                        new_width = available_width;
                    }

                    _tc_o.current_img.width = new_width > available_width ? available_width : new_width;
                    _tc_o.current_img.height = new_height > available_height ? available_height : new_height;
                }

				_tc_html.popup_img.set('morph', {
					transition:'cubic:out',
					duration: 250,
					onComplete: function(){
						_tc_html.popup_img.empty(); // почистим от всех дочерних элементов

						_tc_o.current_img.inject(_tc_html.popup_img).setStyle('opacity', 0).set('tween', {
							duration: 500,
							onComplete: function(){
                                _tc.fireEvent('onChangeComplete'); // присвоим событие onChangeComplete если задано
                                _tc_o.ready = true;
                                
                                // создадим подпись, если она есть или 
                                // ссылку на оригинал, если изображение вышло за границу
								if (_tc_o.arr_alt_txt[_tc_o.index] || _tc_o.abroad)
								{
                                    var p_height = new Element('p').set('html',
                                        (_tc_o.abroad ? '» <a target="_blank" style="font-size:12px; font-weight:bold;" href="' + _tc_o.current_img.getProperty('src') + '">' + 
                                            _tc_o.lang.show_original + '</a> «<br/>' : '') + 
                                        (_tc_o.arr_alt_txt[_tc_o.index] ? _tc_o.arr_alt_txt[_tc_o.index] : '')
                                    ).inject(_tc_html.popup_img).getHeight();

                                    // растянем белое окно
									_tc_html.popup_img.set('tween', {
										transition:'cubic:out', 
										duration: 250
									}).tween('height', _tc_o.current_img.height + p_height);
								}
							}
						}).tween('opacity', 1);
					}
				}).morph({
					'top': _tc_s.gallery_offset + window.getScroll().y,
					'left': window.getSize().x/2 - _tc_o.current_img.width/2 + window.getScroll().x,
					'width': _tc_o.current_img.width,
					'height': _tc_o.current_img.height
				});
			}
		}).addEvent('click', function(){ _tc.close() });

        return _tc;
	},
	autoplayStart: function()
	{
        var _tc = this.options.this_class;
        var _tc_o = _tc.options;
        var _tc_html = _tc.options.html;
        var _tc_s = _tc.options.settings;

		_tc_o.autoplay = true;
			
		_tc_html.play_btn.setProperty('src', _tc_o.src.stop);
		_tc_html.left_btn.setStyle('top', _tc_s.arrow_offset_max);
		_tc_html.right_btn.setStyle('top', _tc_s.arrow_offset_max);
			
		_tc_html.mini_gllr.setStyle('opacity', _tc_s.nav_opacity_min == 0 ? 0 : _tc_s.nav_opacity_min/2);
		_tc_html.output_counter.setStyle('opacity', _tc_s.nav_opacity_min == 0 ? 0 : _tc_s.nav_opacity_min/2);
			
		_tc_o.arr_mini_img.setStyle('cursor', 'default');
			
		_tc_o.autoplay_timer = function (){
			if (_tc_o.ready == true)
			{
				_tc_o.index++;
				if (_tc_o.index > _tc_o.arr_full_src.length-1) _tc_o.index = 0;
				_tc.changeImage();
			}
		}.periodical(_tc_o.autoplay_time*1000);

        return _tc;
	},
	autoplayStop: function()
	{
        var _tc = this.options.this_class;
        var _tc_o = _tc.options;
        var _tc_html = _tc.options.html;
        var _tc_s = _tc.options.settings;

		_tc_o.autoplay = false;
		
		_tc_html.play_btn.setProperty('src', _tc_o.src.play);
		if (_tc_o.index != 0) _tc_html.left_btn.setStyle('top', _tc_s.arrow_offset_min);
		if (_tc_o.index != _tc_o.arr_full_src.length-1) _tc_html.right_btn.setStyle('top', _tc_s.arrow_offset_min);
			
		_tc_html.mini_gllr.setStyle('opacity', 1);
		_tc_html.output_counter.setStyle('opacity', 1);
			
		_tc_o.arr_mini_img.setStyle('cursor', 'pointer');

		clearInterval(_tc_o.autoplay_timer);

        return _tc;
	},
    removeHtml: function ()
    {
        var _tc_html = this.options.html;

        _tc_html.popup_back.destroy();
		_tc_html.popup_img.destroy();
        _tc_html.popup_nav.destroy();
    }.protect(),
	close: function()
	{
        var _tc = this.options.this_class;
        var _tc_o = _tc.options;

		_tc_o.arr_mini_src.empty();
		_tc_o.arr_full_src.empty();
		_tc_o.arr_alt_txt.empty();
        _tc_o.arr_mini_img.empty();

        clearInterval(_tc_o.autoplay_timer);

        _tc.removeHtml();
			
		_tc.fireEvent('onClose'); // присвоим событие onComplete если задано

        return _tc;
	}
});



//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************

burnUp = new Class({
    Implements: [Options, Events, Chain],
    options: {
        'width': 250,
        'opacity': 0.85,
        'offset': 50,
        'popup_back': null,
        'popup_cont': null,
        'popup_border': null,
        'html': null
    },
    initialize: function (options) {
        this.setOptions(options);

        var _tc = this.options.this_class = this;
        var _tc_o = _tc.options;

        //создадим html
        _tc_o.popup_back = new Element('div.bt_popup_back').setStyle('opacity', _tc_o.opacity).inject(document.body);
        _tc_o.popup_cont = new Element('div.bt_popup_cont').setStyle('width', _tc_o.width).inject(document.body);
        _tc_o.popup_border = new Element('div.bt_popup_border').inject(_tc_o.popup_cont);
        new Element('img.close_btn[alt=""][src="/img/popup_close.gif"]')
            .addEvent('click', function () { _tc.close(); }).inject(_tc_o.popup_cont);

        // расстянем фон на весь экран
        if (_tc_o.popup_back.getHeight().toInt() < window.getScrollSize().y)
            _tc_o.popup_back.setStyle('height', window.getScrollSize().y);

        _tc_o.popup_back.addEvent('click', function () { _tc.close(); });

        // зададим координаты
        _tc_o.popup_cont.setStyles({
            'top': _tc_o.offset + window.getScroll().y,
            'left': window.getSize().x / 2 - _tc_o.popup_cont.getWidth() / 2 + window.getScroll().x
        });

        //вставим код
        if (_tc_o.html) {
            if (typeOf(_tc_o.html) == 'string' || typeOf(_tc_o.html) == 'number') {
                _tc_o.popup_border.set('html', _tc_o.html);
            } else {
                _tc_o.html.inject(_tc_o.popup_border);
            }
        }

        return _tc;
    },
    clear: function () {
        this.options.popup_border.empty();

        return this;
    },
    set: function (html) {
        var _tc_o = this.options;

        if (typeOf(html) == 'string' || typeOf(html) == 'number') {
            _tc_o.popup_border.set('html', html);
        } else {
            html.inject(_tc_o.popup_border);
        }

        return this;
    },
    close: function () {
        var _tc = this.options.this_class;
        var _tc_o = _tc.options;

        _tc_o.popup_back.destroy();
        _tc_o.popup_cont.destroy();

        return _tc;
    }
});





//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************

/**
* Autocompleter
*
* http://digitarald.de/project/autocompleter/
*
* @version		1.1.2
*
* @license		MIT-style license
* @author		Harald Kirschner <mail [at] digitarald.de>
* @copyright	Author
*/

var Autocompleter = new Class({

    Implements: [Options, Events],

    options: {/*
		onOver: function() {},
		onSelect: function() {},
		onSelection: function() {},
		onShow: function() {},
		onHide: function() {},
		onBlur: function() {},
		onFocus: function() {},*/
        minLength: 1,
        markQuery: true,
        width: 'inherit',
        maxChoices: 10,
        injectChoice: null,
        customChoices: null,
        emptyChoices: null,
        visibleChoices: true,
        className: 'autocompleter-choices',
        zIndex: 4200,
        delay: 400,
        observerOptions: {},
        fxOptions: {},

        autoSubmit: false,
        overflow: false,
        overflowMargin: 25,
        selectFirst: false,
        filter: null,
        filterCase: false,
        filterSubset: false,
        forceSelect: false,
        selectMode: true,
        choicesMatch: null,

        multiple: false,
        separator: ', ',
        separatorSplit: /\s*[,;]\s*/,
        autoTrim: false,
        allowDupes: false,

        cache: true,
        relative: false
    },

    initialize: function (element, options) {
        this.element = $(element);
        this.setOptions(options);
        this.build();
        this.observer = new Observer(this.element, this.prefetch.bind(this), Object.merge({
            'delay': this.options.delay
        }, this.options.observerOptions));
        this.queryValue = null;
        if (this.options.filter) this.filter = this.options.filter.bind(this);
        var mode = this.options.selectMode;
        this.typeAhead = (mode == 'type-ahead');
        this.selectMode = (mode === true) ? 'selection' : mode;
        this.cached = [];
    },

    /**
    * build - Initialize DOM
    *
    * Builds the html structure for choices and appends the events to the element.
    * Override this function to modify the html generation.
    */
    build: function () {
        if ($(this.options.customChoices)) {
            this.choices = this.options.customChoices;
        } else {
            this.choices = new Element('ul', {
                'class': this.options.className,
                'styles': {
                    'zIndex': this.options.zIndex
                }
            }).inject(document.body);
            this.relative = false;
            if (this.options.relative) {
                this.choices.inject(this.element, 'after');
                this.relative = this.element.getOffsetParent();
            }
            this.fix = new OverlayFix(this.choices);
        }
        if (!this.options.separator.test(this.options.separatorSplit)) {
            this.options.separatorSplit = this.options.separator;
        }
        this.fx = (!this.options.fxOptions) ? null : new Fx.Tween(this.choices, Object.merge({
            'property': 'opacity',
            'link': 'cancel',
            'duration': 200
        }, this.options.fxOptions)).addEvent('onStart', Chain.prototype.clearChain).set(0);
        var this_class = this;
        this.element.setProperty('autocomplete', 'off')
			.addEvent((Browser.ie || Browser.safari || Browser.chrome) ? 'keydown' : 'keypress', this.onCommand.bind(this))
			.addEvent('click', this.onCommand.bind(this, [false]))
			.addEvent('focus', function () { this_class.toggleFocus(true) })
			.addEvent('blur', function () { this_class.toggleFocus(false) });
    },

    destroy: function () {
        if (this.fix) this.fix.destroy();
        this.choices = this.selected = this.choices.destroy();
    },

    toggleFocus: function (state) {
        this.focussed = state;
        if (!state) this.hideChoices(true);
        this.fireEvent((state) ? 'onFocus' : 'onBlur', [this.element]);
    },

    onCommand: function (e) {
        if (!e && this.focussed) return this.prefetch();
        if (e && e.key && !e.shift) {
            switch (e.key) {
                case 'enter':
                    if (this.element.value != this.opted) return true;
                    if (this.selected && this.visible) {
                        this.choiceSelect(this.selected);
                        return !!(this.options.autoSubmit);
                    }
                    break;
                case 'up': case 'down':
                    if (!this.prefetch() && this.queryValue !== null) {
                        var up = (e.key == 'up');
                        this.choiceOver((this.selected || this.choices)[
							(this.selected) ? ((up) ? 'getPrevious' : 'getNext') : ((up) ? 'getLast' : 'getFirst')
						](this.options.choicesMatch), true);
                    }
                    return false;
                case 'esc': case 'tab':
                    this.hideChoices(true);
                    break;
            }
        }
        return true;
    },

    setSelection: function (finish) {
        var input = this.selected.inputValue, value = input;
        var start = this.queryValue.length, end = input.length;
        if (input.substr(0, start).toLowerCase() != this.queryValue.toLowerCase()) start = 0;
        if (this.options.multiple) {
            var split = this.options.separatorSplit;
            value = this.element.value;
            start += this.queryIndex;
            end += this.queryIndex;
            var old = value.substr(this.queryIndex).split(split, 1)[0];
            value = value.substr(0, this.queryIndex) + input + value.substr(this.queryIndex + old.length);
            if (finish) {
                var tokens = value.split(this.options.separatorSplit).filter(function (entry) {
                    return this.test(entry);
                }, /[^\s,]+/);
                if (!this.options.allowDupes) tokens = [].combine(tokens);
                var sep = this.options.separator;
                value = tokens.join(sep) + sep;
                end = value.length;
            }
        }
        this.observer.setValue(value);
        this.opted = value;
        if (finish || this.selectMode == 'pick') start = end;
        this.element.selectRange(start, end);
        this.fireEvent('onSelection', [this.element, this.selected, value, input]);
    },

    showChoices: function () {
        var match = this.options.choicesMatch, first = this.choices.getFirst(match);
        this.selected = this.selectedValue = null;
        if (this.fix) {
            var pos = this.element.getCoordinates(this.relative), width = this.options.width || 'auto';
            this.choices.setStyles({
                'top': pos.bottom,
                'left': pos.left,
                'width': (width === true || width == 'inherit') ? pos.width : width
            });
        }
        if (!first) return;
        if (!this.visible) {
            this.visible = true;
            this.choices.setStyle('display', '');
            if (this.fx) this.fx.start(1);
            this.fireEvent('onShow', [this.element, this.choices]);
        }
        if (this.options.selectFirst || this.typeAhead || first.inputValue == this.queryValue) this.choiceOver(first, this.typeAhead);
        var items = this.choices.getChildren(match), max = this.options.maxChoices;
        var styles = { 'overflowY': 'hidden', 'height': '' };
        this.overflown = false;
        if (items.length > max) {
            var item = items[max - 1];
            styles.overflowY = 'scroll';
            styles.height = item.getCoordinates(this.choices).bottom;
            this.overflown = true;
        };
        this.choices.setStyles(styles);
        this.fix.show();
        if (this.options.visibleChoices) {
            var scroll = document.getScroll(),
			size = document.getSize(),
			coords = this.choices.getCoordinates();
            if (coords.right > scroll.x + size.x) scroll.x = coords.right - size.x;
            if (coords.bottom > scroll.y + size.y) scroll.y = coords.bottom - size.y;
            window.scrollTo(Math.min(scroll.x, coords.left), Math.min(scroll.y, coords.top));
        }
    },

    hideChoices: function (clear) {
        if (clear) {
            var value = this.element.value;
            if (this.options.forceSelect) value = this.opted;
            if (this.options.autoTrim) {
                value = value.split(this.options.separatorSplit).filter(arguments[0]).join(this.options.separator);
            }
            this.observer.setValue(value);
        }
        if (!this.visible) return;
        this.visible = false;
        if (this.selected) this.selected.removeClass('autocompleter-selected');
        this.observer.clear();
        var hide = function () {
            this.choices.setStyle('display', 'none');
            this.fix.hide();
        } .bind(this);
        if (this.fx) this.fx.start(0).chain(hide);
        else hide();
        this.fireEvent('onHide', [this.element, this.choices]);
    },

    prefetch: function () {
        var value = this.element.value, query = value;
        if (this.options.multiple) {
            var split = this.options.separatorSplit;
            var values = value.split(split);
            var index = this.element.getSelectedRange().start;
            var toIndex = value.substr(0, index).split(split);
            var last = toIndex.length - 1;
            index -= toIndex[last].length;
            query = values[last];
        }
        if (query.length < this.options.minLength) {
            this.hideChoices();
        } else {
            if (query === this.queryValue || (this.visible && query == this.selectedValue)) {
                if (this.visible) return false;
                this.showChoices();
            } else {
                this.queryValue = query;
                this.queryIndex = index;
                if (!this.fetchCached()) this.query();
            }
        }
        return true;
    },

    fetchCached: function () {
        return false;
        if (!this.options.cache
			|| !this.cached
			|| !this.cached.length
			|| this.cached.length >= this.options.maxChoices
			|| this.queryValue) return false;
        this.update(this.filter(this.cached));
        return true;
    },

    update: function (tokens) {
        this.choices.empty();
        this.cached = tokens;
        var type = tokens && typeOf(tokens);
        if (!type || (type == 'array' && !tokens.length) || (type == 'hash' && !tokens.getLength())) {
            (this.options.emptyChoices || this.hideChoices).call(this);
        } else {
            if (this.options.maxChoices < tokens.length && !this.options.overflow) tokens.length = this.options.maxChoices;
            tokens.each(this.options.injectChoice || function (token) {
                var choice = new Element('li', { 'html': this.markQueryValue(token) });
                choice.inputValue = token;
                this.addChoiceEvents(choice).inject(this.choices);
            }, this);
            this.showChoices();
        }
    },

    choiceOver: function (choice, selection) {
        if (!choice || choice == this.selected) return;
        if (this.selected) this.selected.removeClass('autocompleter-selected');
        this.selected = typeOf(choice) == 'array' ? choice[0].addClass('autocompleter-selected') : choice.addClass('autocompleter-selected');
        this.fireEvent('onSelect', [this.element, this.selected, selection]);
        if (!this.selectMode) this.opted = this.element.value;
        if (!selection) return;
        this.selectedValue = this.selected.inputValue;
        if (this.overflown) {
            var coords = this.selected.getCoordinates(this.choices), margin = this.options.overflowMargin,
				top = this.choices.scrollTop, height = this.choices.offsetHeight, bottom = top + height;
            if (coords.top - margin < top && top) this.choices.scrollTop = Math.max(coords.top - margin, 0);
            else if (coords.bottom + margin > bottom) this.choices.scrollTop = Math.min(coords.bottom - height + margin, bottom);
        }
        if (this.selectMode) this.setSelection();
    },

    choiceSelect: function (choice) {
        if (choice) this.choiceOver(choice);
        this.setSelection(true);
        this.queryValue = false;
        this.hideChoices();
    },

    filter: function (tokens) {
        return (tokens || this.tokens).filter(function (token) {
            return this.test(token);
        }, new RegExp(((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp(), (this.options.filterCase) ? '' : 'i'));
    },

    /**
    * markQueryValue
    *
    * Marks the queried word in the given string with <span class="autocompleter-queried">*</span>
    * Call this i.e. from your custom parseChoices, same for addChoiceEvents
    *
    * @param		{String} Text
    * @return		{String} Text
    */
    markQueryValue: function (str) {
        return (!this.options.markQuery || !this.queryValue) ? str
			: str.replace(new RegExp('(' + ((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp() + ')', (this.options.filterCase) ? '' : 'i'), '<span class="autocompleter-queried">$1</span>');
    },

    /**
    * addChoiceEvents
    *
    * Appends the needed event handlers for a choice-entry to the given element.
    *
    * @param		{Element} Choice entry
    * @return		{Element} Choice entry
    */
    addChoiceEvents: function (el) {
        return el.addEvents({
            'mouseover': this.choiceOver.bind(this, [el]),
            'click': this.choiceSelect.bind(this, [el])
        });
    }
});

var OverlayFix = new Class({

    initialize: function (el) {
        if (Browser.ie) {
            this.element = $(el);
            this.relative = this.element.getOffsetParent();
            this.fix = new Element('iframe', {
                'frameborder': '0',
                'scrolling': 'no',
                'src': 'javascript:false;',
                'styles': {
                    'position': 'absolute',
                    'border': 'none',
                    'display': 'none',
                    'filter': 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)'
                }
            }).inject(this.element, 'after');
        }
    },

    show: function () {
        if (this.fix) {
            var coords = this.element.getCoordinates(this.relative);
            delete coords.right;
            delete coords.bottom;
            this.fix.setStyles(Object.append(coords, {
                'display': '',
                'zIndex': (this.element.getStyle('zIndex') || 1) - 1
            }));
        }
        return this;
    },

    hide: function () {
        if (this.fix) this.fix.setStyle('display', 'none');
        return this;
    },

    destroy: function () {
        if (this.fix) this.fix = this.fix.destroy();
    }

});

Element.implement({

    getSelectedRange: function () {
        if (!Browser.ie) return { start: this.selectionStart, end: this.selectionEnd };
        var pos = { start: 0, end: 0 };
        var range = this.getDocument().selection.createRange();
        if (!range || range.parentElement() != this) return pos;
        var dup = range.duplicate();
        if (this.type == 'text') {
            pos.start = 0 - dup.moveStart('character', -100000);
            pos.end = pos.start + range.text.length;
        } else {
            var value = this.value;
            var offset = value.length - value.match(/[\n\r]*$/)[0].length;
            dup.moveToElementText(this);
            dup.setEndPoint('StartToEnd', range);
            pos.end = offset - dup.text.length;
            dup.setEndPoint('StartToStart', range);
            pos.start = offset - dup.text.length;
        }
        return pos;
    },

    selectRange: function (start, end) {
        if (Browser.ie) {
            var diff = this.value.substr(start, end - start).replace(/\r/g, '').length;
            start = this.value.substr(0, start).replace(/\r/g, '').length;
            var range = this.createTextRange();
            range.collapse(true);
            range.moveEnd('character', start + diff);
            range.moveStart('character', start);
            range.select();
        } else {
            this.focus();
            this.setSelectionRange(start, end);
        }
        return this;
    }

});

/* compatibility */

Autocompleter.Base = Autocompleter;






/**
* Autocompleter.Local
*
* http://digitarald.de/project/autocompleter/
*
* @version		1.1.2
*
* @license		MIT-style license
* @author		Harald Kirschner <mail [at] digitarald.de>
* @copyright	Author
*/

Autocompleter.Local = new Class({

    Extends: Autocompleter,

    options: {
        minLength: 0,
        delay: 200
    },

    initialize: function (element, tokens, options) {
        this.parent(element, options);
        this.tokens = tokens;
    },

    query: function () {
        this.update(this.filter());
    }

});






/**
* Autocompleter.Request
*
* http://digitarald.de/project/autocompleter/
*
* @version		1.1.2
*
* @license		MIT-style license
* @author		Harald Kirschner <mail [at] digitarald.de>
* @copyright	Author
*/

Autocompleter.Request = new Class({

    Extends: Autocompleter,

    options: {/*
		indicator: null,
		indicatorClass: null,
		onRequest: function() {},
		onComplete: function() {},*/
        postData: {},
        ajaxOptions: {},
        postVar: 'value'

    },

    query: function () {
        var data = Object.clone(this.options.postData) || {};
        data[this.options.postVar] = this.queryValue;
        var indicator = $(this.options.indicator);
        if (indicator) indicator.setStyle('display', '');
        var cls = this.options.indicatorClass;
        if (cls) this.element.addClass(cls);
        this.fireEvent('onRequest', [this.element, this.request, data, this.queryValue]);
        this.request.send({ 'data': data });
    },

    /**
    * queryResponse - abstract
    *
    * Inherated classes have to extend this function and use this.parent()
    */
    queryResponse: function () {
        var indicator = $(this.options.indicator);
        if (indicator) indicator.setStyle('display', 'none');
        var cls = this.options.indicatorClass;
        if (cls) this.element.removeClass(cls);
        return this.fireEvent('onComplete', [this.element, this.request]);
    }

});

Autocompleter.Request.JSON = new Class({

    Extends: Autocompleter.Request,

    initialize: function (el, url, options) {
        this.parent(el, options);
        this.request = new Request.JSON(Object.merge({
            'url': url,
            'link': 'cancel'
        }, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
    },

    queryResponse: function (response) {
        this.parent();
        this.update(response);
    }

});

Autocompleter.Request.HTML = new Class({

    Extends: Autocompleter.Request,

    initialize: function (el, url, options) {
        this.parent(el, options);
        this.request = new Request.HTML(Object.merge({
            'url': url,
            'link': 'cancel',
            'update': this.choices
        }, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
    },

    queryResponse: function (tree, elements) {
        this.parent();
        if (!elements || !elements.length) {
            this.hideChoices();
        } else {
            this.choices.getChildren(this.options.choicesMatch).each(this.options.injectChoice || function (choice) {
                var value = choice.innerHTML;
                choice.inputValue = value;
                this.addChoiceEvents(choice.set('html', this.markQueryValue(value)));
            }, this);
            this.showChoices();
        }

    }

});

/* compatibility */

Autocompleter.Ajax = {
    Base: Autocompleter.Request,
    Json: Autocompleter.Request.JSON,
    Xhtml: Autocompleter.Request.HTML
};


/**
* Observer - Observe formelements for changes
*
* - Additional code from clientside.cnet.com
*
* @version		1.1
*
* @license		MIT-style license
* @author		Harald Kirschner <mail [at] digitarald.de>
* @copyright	Author
*/
var Observer = new Class({

    Implements: [Options, Events],

    options: {
        periodical: false,
        delay: 1000
    },

    initialize: function (el, onFired, options) {
        this.element = $(el) || $$(el);
        this.addEvent('onFired', onFired);
        this.setOptions(options);
        this.bound = this.changed.bind(this);
        this.resume();
    },

    changed: function () {
        var value = this.element.get('value');
        if (___equals(this.value, value)) return;
        this.clear();
        this.value = value;
        this.timeout = this.onFired.delay(this.options.delay, this);
    },

    setValue: function (value) {
        this.value = value;
        this.element.set('value', value);
        return this.clear();
    },

    onFired: function () {
        this.fireEvent('onFired', [this.value, this.element]);
    },

    clear: function () {
        clearInterval(this.timeout || null);
        return this;
    },

    pause: function () {
        if (this.timer) clearInterval(this.timer);
        else this.element.removeEvent('keyup', this.bound);
        return this.clear();
    },

    resume: function () {
        this.value = this.element.get('value');
        if (this.options.periodical) this.timer = this.changed.periodical(this.options.periodical, this);
        else this.element.addEvent('keyup', this.bound);
        return this;
    }

});

var ___equals = function (obj1, obj2) {
    return (obj1 == obj2 || JSON.encode(obj1) == JSON.encode(obj2));
};







//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************

PageMooSlider = new Class({
    Implements: [Options],
    options: {
        container: null,
        pagesTotal: 1,
        pagesSpan: 10,
        pageCurrent: 1,
        baseUrl: './page/',
        returnOrder: false,
        lang: {
            next: "Следующая",
            last: "Последняя",
            prior: "Предыдущая",
            first: "Первая",
            arrowRight: String.fromCharCode(8594),
            arrowLeft: String.fromCharCode(8592)
        },
        html: {
            holder: null,
            table: null,
            trPages: null,
            trScrollBar: null,
            tdsPages: null,
            scrollBar: null,
            scrollThumb: null,
            pageCurrentMark: null
        },
        this_class: null //internal access in this class
    },
    initialize: function (options) {
        this.setOptions(options); //get user options and set for class
        var options = this.options;
        options.this_class = this;

        options.pagesSpan = options.pagesSpan < options.pagesTotal ? options.pagesSpan : options.pagesTotal;
        options.pageCurrent = options.pagesTotal < options.pageCurrent ? options.pagesTotal : options.pageCurrent;
        if ((typeOf(options.baseUrl) != 'function') && !options.baseUrl.match(/%page%/i)) options.baseUrl += '%page%';

        if (options.container) {
            options.html.holder = options.container;
        }
        else {
            alert('Error: container not found');
            return false;
        }

        this.prepareHtml();
        this.initScrollThumb();
        this.initPageCurrentMark();
        this.initEvents();
    },
    prepareHtml: function () {
        var options = this.options;
        var html = this.options.html;

        html.holder.set('html', this.makePagesTableHtml());
        html.table = html.holder.getElements('table table')[0];
        html.trPages = html.table.getElements('tr')[0];
        html.tdsPages = html.trPages.getChildren('td');
        html.scrollBar = html.holder.getElement('div.scroll_bar');
        html.scrollThumb = html.holder.getElement('div.scroll_thumb');
        html.pageCurrentMark = html.holder.getElement('div.current_page_mark');
        if (options.pagesTotal == options.pagesSpan) {
            html.holder.addClass('fullsize');
        }
    },
    makePagesTableHtml: function () {
        var options = this.options;

        var tdWidth = (100 / (options.pagesSpan + 2)) + '%';

        var isFunc = (typeOf(options.baseUrl) == 'function');

        var next_page = (parseInt(options.pageCurrent) < parseInt(options.pagesTotal)) ? parseInt(options.pageCurrent) + 1 : options.pagesTotal;

        var next = '<a class="lr_link" href="';
        next += isFunc ? 'javascript:;' : options.baseUrl.replace(/%page%/i, next_page);
        next += '" rel="' + next_page + '">%next%</a>';
        var last = '<a class="lr_link" href="';
        last += isFunc ? 'javascript:;' : options.baseUrl.replace(/%page%/i, options.pagesTotal);
        last += '" rel="' + options.pagesTotal + '">%last%</a>';

        var prior_page = (parseInt(options.pageCurrent) > 1) ? parseInt(options.pageCurrent) - 1 : 1;

        var prior = '<a class="lr_link" href="';
        prior += isFunc ? 'javascript:;' : options.baseUrl.replace(/%page%/i, prior_page);
        prior += '" rel="' + prior_page + '">%prior%</a>';
        var first = '<a class="lr_link" href="';
        first += isFunc ? 'javascript:;' : options.baseUrl.replace(/%page%/i, 1);
        first += '" rel="' + 1 + '">%first%</a>';


        if (options.returnOrder) {
            var top_left = options.lang.arrowLeft + ' ' + options.lang.next;
            var bottom_left = options.lang.last;
            var top_right = options.lang.prior + ' ' + options.lang.arrowRight;
            var bottom_right = options.lang.first;

            if (options.pageCurrent !== options.pagesTotal) {
                var top_left = next.replace(/%next%/, top_left);
                var bottom_left = last.replace(/%last%/, bottom_left);
            }

            if (options.pageCurrent !== 1) {
                var top_right = prior.replace(/%prior%/, top_right);
                var bottom_right = first.replace(/%first%/, bottom_right);
            }

        } else {
            var bottom_right = options.lang.last;
            var top_right = options.lang.next + ' ' + options.lang.arrowRight;
            var top_left = options.lang.arrowLeft + ' ' + options.lang.prior;
            var bottom_left = options.lang.first;

            if (options.pageCurrent !== options.pagesTotal) {
                var top_right = next.replace(/%next%/, top_right);
                var bottom_right = last.replace(/%last%/, bottom_right);
            }

            if (options.pageCurrent !== 1) {
                var top_left = prior.replace(/%prior%/, top_left);
                var bottom_left = first.replace(/%first%/, bottom_left);
            }
        }

        var html = '' +
        '<table style="width:100%;">' +
         '<tr>' +
           '<td class="left top">' + top_left + '</td>' +
           '<td class="spaser"></td>' +
           '<td rowspan="2" align="center">' +
             '<table>' +
               '<tr>'
        for (var i = 1; i <= options.pagesSpan; i++) {
            html += '<td style="width:' + tdWidth + '"></td>';
        }
        html += '' +
               '</tr>' +
               '<tr>' +
	             '<td colspan="' + options.pagesSpan + '">' +
		           '<div class="scroll_bar">' +
		             '<div class="scroll_trough"></div>' +
			         '<div class="scroll_thumb">' +
				        '<div class="scroll_knob"></div>' +
			         '</div>' +
			         '<div class="current_page_mark"></div>' +
		           '</div>' +
	             '</td>' +
               '</tr>' +
             '</table>' +
           '</td>' +
           '<td class="spaser"></td>' +
           '<td class="right top">' + top_right + '</td>' +
        '</tr>' +
        '<tr>' +
          '<td class="left bottom">' + bottom_left + '</td>' +
          '<td class="spaser"></td>' +
          '<td class="spaser"></td>' +
          '<td class="right bottom">' + bottom_right + '</td>' +
        '</tr>' +
        '</table>';

        return html;
    },
    initScrollThumb: function () {
        var options = this.options;
        var html = this.options.html;

        html.scrollThumb.widthMin = '8';
        html.scrollThumb.widthPercent = options.pagesSpan / options.pagesTotal * 100;
        html.scrollThumb.xPosPageCurrent = (options.pageCurrent - Math.round(options.pagesSpan / 2)) / options.pagesTotal * html.table.getWidth();
        if (options.returnOrder) {
            html.scrollThumb.xPosPageCurrent = html.table.getWidth() - (html.scrollThumb.xPosPageCurrent + Math.round(options.pagesSpan / 2) / options.pagesTotal * html.table.getWidth());
        }
        html.scrollThumb.xPos = html.scrollThumb.xPosPageCurrent;
        html.scrollThumb.xPosMin = 0;
        html.scrollThumb.xPosMax;
        html.scrollThumb.widthActual;

        this.setScrollThumbWidth();
    },
    setScrollThumbWidth: function () {
        var html = this.options.html;

        html.scrollThumb.setStyle('width', html.scrollThumb.widthPercent + "%");
        html.scrollThumb.widthActual = html.scrollThumb.getWidth();

        if (html.scrollThumb.widthActual < html.scrollThumb.widthMin)
            html.scrollThumb.setStyle('width', html.scrollThumb.widthMin + 'px');

        html.scrollThumb.xPosMax = html.table.getWidth() - html.scrollThumb.widthActual;
    },
    moveScrollThumb: function () {
        var html = this.options.html;

        html.scrollThumb.setStyle('left', html.scrollThumb.xPos + "px");
    },
    initPageCurrentMark: function () {
        var options = this.options;
        var html = this.options.html;

        html.pageCurrentMark.widthMin = '3';
        html.pageCurrentMark.widthPercent = 100 / options.pagesTotal;
        html.pageCurrentMark.widthActual;

        this.setPageCurrentPointWidth();
        this.movePageCurrentPoint();
    },
    setPageCurrentPointWidth: function () {
        var html = this.options.html;

        html.pageCurrentMark.setStyle('width', html.pageCurrentMark.widthPercent + '%');

        html.pageCurrentMark.widthActual = html.pageCurrentMark.getWidth();

        if (html.pageCurrentMark.widthActual < html.pageCurrentMark.widthMin)
            html.pageCurrentMark.setStyle('width', html.pageCurrentMark.widthMin + 'px');
    },
    movePageCurrentPoint: function () {
        var options = this.options;
        var html = this.options.html;

        var pos = 0;
        if (html.pageCurrentMark.widthActual < html.pageCurrentMark.getWidth()) {
            pos = (options.pageCurrent - 1) / options.pagesTotal * html.table.getWidth() - html.pageCurrentMark.getWidth() / 2;
        } else {
            pos = (options.pageCurrent - 1) / options.pagesTotal * html.table.getWidth();
        }

        if (options.returnOrder) pos = html.table.getWidth() - pos - html.pageCurrentMark.getWidth();

        html.pageCurrentMark.setStyle('left', pos + 'px');
    },
    initEvents: function () {
        var options = this.options;
        var html = this.options.html;

        this.moveScrollThumb();

        options.returnOrder ? this.drawReturn() : this.drawPages();

        html.scrollThumb.addEvent('mousedown', function (e) {
            var dx = e.page.x - html.scrollThumb.xPos;

            document.addEvent('mousemove', function (e) {
                html.scrollThumb.xPos = e.page.x - dx;

                options.this_class.moveScrollThumb();
                options.returnOrder ? options.this_class.drawReturn() : options.this_class.drawPages();
            });

            document.addEvent('mouseup', function () {
                document.removeEvents('mousemove');
                options.this_class.enableSelection();
            });

            options.this_class.disableSelection();
        });

        if (typeOf(options.baseUrl) == 'function') {
            html.holder.getElements('.lr_link').addEvent('click', function (e) {
                options.baseUrl(parseInt(this.getProperty('rel')));
            });
        };

        window.addEvent('resize', function () {
            options.this_class.setPageCurrentPointWidth();
            options.this_class.movePageCurrentPoint();
            options.this_class.setScrollThumbWidth();
        });
    },
    drawPages: function () {
        var options = this.options;
        var html = this.options.html;

        var percentFromLeft = html.scrollThumb.xPos / html.table.getWidth();
        var cellFirstValue = Math.round(percentFromLeft * options.pagesTotal);

        var data = '';

        if (cellFirstValue < 1) {
            cellFirstValue = 1;
            html.scrollThumb.xPos = 0;
            this.moveScrollThumb();
        } else if (cellFirstValue >= options.pagesTotal - options.pagesSpan) {
            cellFirstValue = options.pagesTotal - options.pagesSpan + 1;
            html.scrollThumb.xPos = html.table.getWidth() - html.scrollThumb.getWidth();
            this.moveScrollThumb();
        }

        var isFunc = (typeOf(options.baseUrl) == 'function');

        for (var i = 0; i < html.tdsPages.length; i++) {
            var cellCurrentValue = cellFirstValue + i;

            if (cellCurrentValue == options.pageCurrent) {
                data = '<span> <strong>' + cellCurrentValue + '</strong> </span>';
            } else {
                data = '<span> <a href="';
                data += isFunc ? 'javascript:;' : options.baseUrl.replace(/%page%/i, cellCurrentValue);
                data += '">' + cellCurrentValue + '</a> </span>';
            };
            html.tdsPages[i].set('html', data);

            if (isFunc) {
                html.tdsPages[i].getElements('a').addEvent('click', function (e) {
                    options.baseUrl(this.get('html'));
                });
            }

        }
    },
    drawReturn: function () {
        var options = this.options;
        var html = this.options.html;

        var percentFromLeft = html.scrollThumb.xPos / html.table.getWidth();
        var cellFirstValue = options.pagesTotal - Math.round(percentFromLeft * options.pagesTotal);

        var data = '';

        if (cellFirstValue < options.pagesSpan) {
            cellFirstValue = options.pagesSpan;
            html.scrollThumb.xPos = html.table.getWidth() - html.scrollThumb.getWidth();
            this.moveScrollThumb();
        } else if (cellFirstValue >= options.pagesTotal) {
            cellFirstValue = options.pagesTotal;
            html.scrollThumb.xPos = 0;
            this.moveScrollThumb();
        }

        var isFunc = (typeOf(options.baseUrl) == 'function');

        for (var i = 0; i < html.tdsPages.length; i++) {
            var cellCurrentValue = cellFirstValue - i;
            if (cellCurrentValue == options.pageCurrent) {
                data = '<span> <strong>' + cellCurrentValue + '</strong> </span>';
            } else {
                data = '<span> <a href="';
                data += isFunc ? 'javascript:;' : options.baseUrl.replace(/%page%/i, cellCurrentValue);
                data += '">' + cellCurrentValue + '</a> </span>';
            };
            html.tdsPages[i].set('html', data);

            if (isFunc) {
                html.tdsPages[i].getElements('a').addEvent('click', function () {
                    options.baseUrl(this.get('html'));
                });
            }

        }
    },
    enableSelection: function () {
        document.onselectstart = function () {
            return true;
        };
    },
    disableSelection: function () {
        var html = this.options.html;

        document.onselectstart = function () {
            return false;
        };
        html.scrollThumb.focus();
    }
});











//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************
//*************************************************************************************************************

/*
---
description: The Wall is a plugin for Mootools javascript framework designed to create walls of infinite dimensions. Its flexibility allows different applications, from infinite wall mode to Coda slider mode. The Wall creates compatible interfaces with the newer browsers and iPhone and iPad mobile devices.

license: MIT-style

authors:
- Marco Dell'Anna

requires:
- core/1.3: '*'

provides:
- The Wall
...
*/

/*
* Mootools The Wall
* Version 1.0
* Copyright (c) 2011 Marco Dell'Anna - http://www.plasm.it
*
* Inspiration:
* - Class implementation inspired by [Infinite Drag] (http://ianli.com/infinitedrag/) by Ian Li, Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
*
* Requires:
* MooTools http://mootools.net
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Log:
* 1.1 - Inserito onResize Windows
* 1.0 - Inizio implementazione release stabile
*/


var Wall = new Class({
    __target: undefined,
    init: false,
    Implements: Options,
    id: 0, // ID Elemento Attivo
    coordinates: [],
    wall: undefined,
    viewport: undefined,
    grid: [],
    minx: 0,
    maxx: 0,
    wallFX: undefined,
    slideshowInterval: undefined,
    options: {
        printCoordinates: false,             // Inserisce le coordinate nel tile
        speed: 1000,              // Velocità spostamento
        transition: Fx.Transitions.Quad.easeOut,
        autoposition: false,             // Autoposizionamento wall
        draggable: true,              // Abilita drag
        inertia: false,             // Abilita inertia
        invert: false,             // Inverte direzione drag
        width: 0,                 // W tile
        height: 0,                 // H tile
        startx: 0,                 // Tile iniziale
        starty: 0,                 // Tile iniziale
        rangex: [-500, 500],       // Definisce il numero di colonne (non pixel)
        rangey: [-500, 500],       // Definisce il numero di righe (non pixel)
        handle: undefined,         // Definisce un differente handle
        slideshow: false,             // Abilita Slideshow Wall
        showDuration: 3000,              // Durata visualizzazione Slideshow
        preload: false,             // Precarica contenuto
        callOnUpdate: Function,          // Azione on drag/complete
        callOnChange: Function           // Azione scatenata quando viene impostato id elemento attivo
    },

    initialize: function (id, options) {
        // Set opzioni
        this.setOptions(options);
        this.__target = id;
        // Imposta wall e Viewport
        this.wall = $(this.__target);
        this.viewport = $(this.__target).getParent();
    },

    initWall: function () {
        // Calcola tutte le coordinate
        this.coordinates = this.calculateCoordinates();
        // Prepopolate
        if (this.options.preload == true) this.preloadContent();
        // Calcola Spostamento Min e Max per Assi X,Y
        var bb = this.setBoundingBox();
        // Imposta Coordiname BB
        this.maxx = bb.maxx;
        this.maxy = bb.maxy;
        this.minx = bb.minx;
        this.miny = bb.miny;

        // Verifica Init Class
        if (this.init == false) {
            // Definisce Effetto di spostamento
            this.wallFX = new Fx.Morph(this.wall, {
                duration: this.options.speed,
                transition: this.options.transition,
                onStart: function () {
                    //periodicalID = (function(){ 
                    //this.options.callOnUpdate(this.updateWall());
                    //}).periodical(Math.floor(this.options.speed/4), this);
                } .bind(this),
                onComplete: function () {
                    this.options.callOnUpdate(this.updateWall());
                    // clearTimeout(periodicalID);
                } .bind(this)
            });
            // Inizializza Resize Windows
            window.addEvent('resize', function () { this.options.callOnUpdate(this.updateWall()); } .bind(this));

            // Inizializza Class
            this.init = true;
        } else {
            // Sgancia elemento solo se draggabile
            if (this.options.draggable == true) this.wallDrag.detach();
        }

        // Definisce Handler
        var handler = this.options.handle != undefined ? $(this.options.handle) : $(this.__target);
        // Click sul Wall
        $(this.__target).addEvent("click", function (e) {
            e.stopPropagation();
            // Reset Movement
            this.moved = 0;
        } .bind(this))

        // Definisce oggetto draggabile
        if (this.options.draggable == true) {
            this.wallDrag = $(this.__target).makeDraggable({
                handle: handler,
                limit: {
                    x: [this.minx, this.maxx],
                    y: [this.miny, this.maxy]
                },
                invert: this.options.invert,
                onStart: function (el, e) {
                    clearTimeout(this.periodicalID);
                    // Reset Movement
                    this.moved = 0;
                    // Posizione Inizio Drag
                    this.xPos = e.page.x;
                    this.yPos = e.page.y;
                } .bind(this),
                onDrag: function (el, e) {
                    this.xspeed = e.page.x - this.xPos; // x mouse speed
                    this.yspeed = e.page.y - this.yPos; // y mouse speed
                    this.xPos = e.page.x;
                    this.yPos = e.page.y;
                    //
                    e.stopPropagation();
                    // Interrompe Slideshow
                    this.clearSlideShow();
                    // Tronca transizione se riparte il drag
                    if (this.wallFX) this.wallFX.cancel();
                    this.options.callOnUpdate(this.updateWall());
                    // Considera movimento
                    this.moved++;
                } .bind(this),
                onComplete: function (el, e) {
                    e.preventDefault();
                    // Verifica inertia
                    if (this.options.inertia == true) {
                        // START Inertia
                        this.periodicalID = (function () {
                            if (this.options.invert == true) {
                                var finX = this.wall.getStyle("left").toInt() - this.xspeed;
                                var finY = this.wall.getStyle("top").toInt() - this.yspeed;
                            } else {
                                var finX = this.wall.getStyle("left").toInt() + this.xspeed;
                                var finY = this.wall.getStyle("top").toInt() + this.yspeed;
                            }
                            if (finX < 0) this.wall.setStyle("left", Math.max(this.minx, finX));
                            if (finY < 0) this.wall.setStyle("top", Math.max(this.miny, finY));
                            if (finX > 0) this.wall.setStyle("left", Math.min(this.maxx, finX));
                            if (finY > 0) this.wall.setStyle("top", Math.min(this.maxy, finY));

                            // Decrementa velocità di spostamento
                            this.xspeed *= 0.9;
                            this.yspeed *= 0.9;
                            // Aggiorna Wall
                            this.options.callOnUpdate(this.updateWall());
                            // Interrompe spostamento se prossimo a 0.6
                            if (Math.abs(this.xspeed) < 2 && Math.abs(this.yspeed) < 2) {
                                // Attiva elemento del coda, se presente
                                var p = this.calculateProximity();
                                // Calcola l'id in base alle coordinate
                                this.id = this.getIdFromCoordinates(p.c, p.r);
                                // Attiva elemento del coda
                                this.codaActiveItem(this.id);
                                this.options.callOnUpdate(this.updateWall());
                                // Ricalcola posizione
                                if (this.options.autoposition == true) this.normalizePosition();
                                // Clear Periodical
                                clearTimeout(this.periodicalID);
                            }
                        }).periodical(20, this);
                        // END Inertia
                    }
                    // Riposizionamento automatico
                    if (this.options.autoposition == true && this.options.inertia == false) {
                        // Riposiziona, se richiesto e se lo slideshow è terminato
                        if (this.slideshowInterval == undefined || this.options.slideshow == false) this.normalizePosition();
                    } else {
                        // Attiva elemento del coda, se presente
                        var p = this.calculateProximity();
                        // Calcola l'id in base alle coordinate
                        this.id = this.getIdFromCoordinates(p.c, p.r);
                        // Attiva elemento del coda
                        this.codaActiveItem(this.id);
                    }
                    // Callback wall    
                    this.options.callOnUpdate(this.updateWall());
                } .bind(this)
            });
            // Imposta Cursore
            this.wall.setStyle("cursor", "move");
            // Scarica Prediodical
            this.wallDrag.addEvent("mousedown", function (e) {
                e.stop();
                clearTimeout(this.periodicalID);
                e.stopPropagation();
            } .bind(this));
        } else {
            // Imposta Cursore default
            this.wall.setStyles({
                "cursor": "default",
                "position": "absolute"
            });
        }

        // Imposta posizione iniziale
        this.wall.setStyles({
            "left": this.options.startx * this.options.width,
            "top": this.options.starty * this.options.height
        })

        // Aggiorna Wall ed esegue CallBack di creazione
        this.options.callOnUpdate(this.updateWall());

        // Inizializza Slideshow
        if (this.options.slideshow == true) this.initSlideshow();

        // Inizializza Device Mobile
        if (this.detectMobile()) this.initMobile();

        //
        return this;
    },

    getMovement: function () {
        var m = this.moved > 0 ? true : false;
        // Resetta variabile movimento
        this.moved = 0;
        return m;
    },

    setBoundingBox: function () {
        // Estrae Coordinate Viewport
        var vp_coordinate = this.viewport.getCoordinates();
        // Tile Size
        var tile_w = this.options.width;
        var tile_h = this.options.height;
        // Viewport Size
        var vp_w = vp_coordinate.width;
        var vp_h = vp_coordinate.height;
        var vp_cols = Math.ceil(vp_w / tile_w);
        var vp_rows = Math.ceil(vp_h / tile_h);
        // Calcola X min e X max
        var maxx = Math.abs(this.options.rangex[0]) * tile_w;
        var maxy = Math.abs(this.options.rangey[0]) * tile_h;
        var minx = -((Math.abs(this.options.rangex[1])) * tile_w) + vp_w;
        var miny = -((Math.abs(this.options.rangey[1])) * tile_h) + vp_h;
        return { "minx": minx, "miny": miny, "maxx": maxx, "maxy": maxy }
    },

    calculateCoordinates: function () {
        var indice = 0;
        var coordinates = [];
        for (var r = this.options.rangey[0]; r < this.options.rangey[1]; r++) {
            for (var c = this.options.rangex[0]; c < this.options.rangex[1]; c++) {
                coordinates[indice] = { "c": c, "r": r };
                if (c == 0 && r == 0) { this.id = indice; }
                indice++;
            }
        }
        return coordinates;
    },

    getIdFromCoordinates: function (gc, gr) {
        var indice = 0;
        for (var r = this.options.rangey[0]; r < this.options.rangey[1]; r++) {
            for (var c = this.options.rangex[0]; c < this.options.rangex[1]; c++) {
                if (c == gc && r == gr) { return indice; }
                indice++;
            }
        }
        return indice;
    },

    getCoordinatesFromId: function (id) {
        return this.coordinates[id];
    },

    getActiveItem: function () {
        return this.id;
    },

    calculateProximity: function () {
        var wallx = this.wall.getStyle("left").toInt() * -1;
        var wally = this.wall.getStyle("top").toInt() * -1;
        var w = this.options.width;
        var h = this.options.height;
        // Calcola posizione
        var npx = Math.round(wallx / w);
        var npy = Math.round(wally / h);
        return { "c": npx, "r": npy };
    },

    normalizePosition: function () {
        var p = this.calculateProximity();
        // Sposta al punto
        this.moveTo(p.c, p.r);
        return;
    },

    updateWall: function () {
        // Array Nodes
        var newItems = [];
        // Estrae Coordinate Wall e Viewport
        var vp_coordinate = this.viewport.getCoordinates();
        var wall_coordinate = this.wall.getCoordinates();

        // Tile Size
        var tile_w = this.options.width;
        var tile_h = this.options.height;

        // Viewport Size
        var vp_w = vp_coordinate.width;
        var vp_h = vp_coordinate.height;
        var vp_cols = Math.ceil(vp_w / tile_w);
        var vp_rows = Math.ceil(vp_h / tile_h);

        // Posizioni
        var pos = {
            left: wall_coordinate.left - vp_coordinate.left,
            top: wall_coordinate.top - vp_coordinate.top
        }

        // Calcola visibilità elemento
        var visible_left_col = Math.ceil(-pos.left / tile_w) - 1;
        var visible_top_row = Math.ceil(-pos.top / tile_h) - 1;

        for (var i = visible_left_col; i <= visible_left_col + vp_cols; i++) {
            for (var j = visible_top_row; j <= visible_top_row + vp_rows; j++) {
                if (this.grid[i] === undefined) {
                    this.grid[i] = {};
                }
                if (this.grid[i][j] === undefined) {
                    var item = this.appendTile(i, j);
                    if (item.node !== undefined) newItems.push(item);
                }
            }
        }

        // Update viewport info.
        wall_width = wall_coordinate.width;
        wall_height = wall_coordinate.height;
        wall_cols = Math.ceil(wall_width / tile_w);
        wall_rows = Math.ceil(wall_height / tile_h);

        return newItems;
    },

    appendTile: function (i, j) {
        this.grid[i][j] = true;

        // Tile Size
        var tile_w = this.options.width;
        var tile_h = this.options.height;
        // Valori Min/Max
        var range_col = this.options.rangex;
        var range_row = this.options.rangey;
        if (i < range_col[0] || (range_col[1]) < i) return {};
        if (j < range_row[0] || (range_row[1]) < j) return {};

        var x = i * tile_w;
        var y = j * tile_h;
        var e = new Element("div").inject(this.wall);
        e.setProperties({
            "class": "tile",
            "col": i,
            "row": j,
            "rel": i + "x" + j
        }).setStyles({
            "position": "absolute",
            "left": x,
            "top": y,
            "width": tile_w,
            "height": tile_h
        })
        if (this.options.printCoordinates) e.set("text", i + "x" + j);
        return { "node": e, "x": j, "y": i };
    },

    preloadContent: function () {
        // Array Nodes
        var newItems = [];
        this.coordinates.each(function (e) {
            if (this.grid[e.c] === undefined) this.grid[e.c] = {};
            var item = this.appendTile(e.c, e.r);
            newItems.push(item);
        } .bind(this))
        // Popola tutto il wall
        this.options.callOnUpdate(newItems);
        return newItems;
    },

    setCallOnUpdate: function (f) {
        this.options.callOnUpdate = f;
        return f;
    },

    setCallOnChange: function (f) {
        this.options.callOnChange = f;
        return f;
    },

    initSlideshow: function () {
        // Controllo Speed
        if (this.options.showDuration < this.options.speed) this.options.showDuration = this.options.speed;
        this.slideshowInterval = this.getAutomaticNext.periodical(this.options.showDuration, this);
    },

    getAutomaticNext: function () {
        this.clearSlideShow();
        if (this.options.slideshow == true) {
            this.slideshowInterval = this.getAutomaticNext.periodical(this.options.showDuration, this);
        }
        // Verifica elemento
        1 + this.id > this.coordinates.length - 1 ? this.id = 0 : this.id++;
        this.moveTo(this.coordinates[this.id].c, this.coordinates[this.id].r); // Richiede prossima slide
    },

    clearSlideShow: function () {
        clearTimeout(this.slideshowInterval);
        this.slideshowInterval = undefined;
    },

    moveTo: function (c, r) {

        // Verifica validità valori possibile e valore indicato
        if (c < 0) c = Math.max(c, this.options.rangex[0]);
        if (c > 0) c = Math.min(c, this.options.rangex[1]);
        if (r < 0) r = Math.max(r, this.options.rangey[0]);
        if (r > 0) r = Math.min(r, this.options.rangey[1]);

        // Esegue Morph
        this.wallFX.cancel().start({
            'left': Math.max(-(c * this.options.width), this.minx),
            'top': Math.max(-(r * this.options.height), this.miny)
        });

        // Calcola l'id in base alle coordinate
        this.id = this.getIdFromCoordinates(c, r);

        // Attiva elemento del coda
        this.codaActiveItem(this.id);
        //
        var name = this.coordinates[this.id].c + "x" + this.coordinates[this.id].r;
        var item = $$("#" + this.__target + " div[rel=" + name + "]");
        if (item.length > 0) return $$("#" + this.__target + " div[rel=" + name + "]")[0];
        return false;
    },

    moveToActive: function () {
        // Muove il Wall alle coordinate del tile con id attivo
        return this.moveTo(this.coordinates[this.id].c, this.coordinates[this.id].r)
    },

    moveToNext: function () {
        this.clearSlideShow();
        if (1 + this.id < this.coordinates.length) { this.id++; }
        return this.moveTo(this.coordinates[this.id].c, this.coordinates[this.id].r)
    },

    moveToPrev: function () {
        this.clearSlideShow();
        if ((this.id - 1) >= 0) { this.id--; }
        return this.moveTo(this.coordinates[this.id].c, this.coordinates[this.id].r)
    },

    getListLinksPoints: function (id_target) {
        var items = [];
        // Crea Hyperlink per ogni elemento del Wall
        this.coordinates.each(function (e, i) {
            var a = new Element("a.wall-item-coda[html=" + (1 + i) + "][href=#" + (1 + i) + "]");
            a.addEvent("click", function (evt) {
                // Disabilita slideshow
                this.clearSlideShow();
                this.id = i;
                this.codaActiveItem(i);
                evt.stop();
                this.moveTo(e.c, e.r);
            } .bind(this))
            // Inserisce nel target
            a.inject($(id_target));
            // Aggiunge ad array elementi
            items.push(a);
        } .bind(this))
        // Imposta id coda target
        this.coda_target = id_target;
        // Imposta lista elementi del coda
        this.coda_items = items;
        // Imposta attivo il primo elemento del coda
        this.codaActiveItem(0);
        return items;
    },

    codaActiveItem: function (i) {
        // Esegue CallBack
        this.options.callOnChange(i);
        // Attivazione
        if (this.coda_target) {
            // Rimuove link attivi
            this.coda_items.each(function (e, i) { e.removeClass("wall-item-current"); })
            // Attiva corrente
            this.coda_items[i].addClass("wall-item-current");
            return this.coda_items[i];
        }
    },

    detectMobile: function () {
        var ua = navigator.userAgent;
        var isiPad = /iPad/i.test(ua) || /iPhone OS 3_1_2/i.test(ua) || /iPhone OS 3_2_2/i.test(ua) || /iPhone/i.test(ua) || /iPod/i.test(ua)
        return isiPad;
    },

    initMobile: function () {
        // Touch Start Slider
        this.wall.__root = this
        this.wall.addEvent('touchstart', function (e) {
            if (e) e.stop();

            // Interrompe Slideshow
            this.__root.clearSlideShow();

            // Data Start
            this._startXMouse = e.page.x;
            this._startYMouse = e.page.y;
            this._startLeft = this.getStyle("left").toInt();
            this._startTop = this.getStyle("top").toInt();
            this._width = this.getStyle("width").toInt();
            this._height = this.getStyle("height").toInt();
        });

        // Touch Move Slider
        this.wall.addEvent('touchmove', function (e) {
            if (e) e.stop();
            // Horizontal
            var _deltax = this._startXMouse - e.page.x;
            var _x = this.getStyle("left").toInt();

            if (_x > Math.min(this.__root.minx, 0)) {
                endx = Math.min(this._startLeft - _deltax, this.__root.maxx)
            } else {
                endx = Math.max(this.__root.minx, this._startLeft - _deltax)
            }
            // Imposta posizione X
            if (endx <= this.__root.maxx) this.setStyle("left", endx);

            // Vertical
            var _deltay = this._startYMouse - e.page.y;
            var _y = this.getStyle("top").toInt();

            if (_y > Math.min(this.__root.miny, 0)) {
                endy = Math.min(this._startTop - _deltay, this.__root.maxy)
            } else {
                endy = Math.max(this.__root.miny, this._startTop - _deltay)
            }
            // Imposta posizione Y
            if (endy <= this.__root.maxy) this.setStyle("top", endy);

            // Aggiorna Wall ed esegue CallBack di creazione
            this.__root.options.callOnUpdate(this.__root.updateWall());
        });

        // Touch Move End
        this.wall.addEvent('touchend', function (e) {
            if (this.options.autoposition == true) {
                // Riposiziona, se richiesto e se lo slideshow è terminato
                if (this.slideshowInterval == undefined || this.options.slideshow == false) this.normalizePosition();
            } else {
                // Attiva elemento del coda, se presente
                var p = this.calculateProximity();
                // Calcola l'id in base alle coordinate
                this.id = this.getIdFromCoordinates(p.c, p.r);
                // Attiva elemento del coda
                this.codaActiveItem(this.id);
            }
            // Aggiorna Wall ed esegue CallBack di creazione
            this.options.callOnUpdate(this.updateWall());
        } .bind(this));
    }
});
