//
//                                                           скрипт движения слоя
//                                                           разработка: A.St.
//                                                           май 2009
//
// подключение:
//      - подключить скрипт в хэде
//      - после определения всех элементов, участвующих в процессе (слои, кнопки) прописать инициализацию объекта ( z.b. currentMotion = new motion.load( "moutingDiv", "holdDiv", 300);)
//      - написать привязки к событиям, в которых указать ссылку на init с указанием направления (currentMotion.init( direction);)
//      - проверить стили у слоёв
//      - читать консоль ошибок в случае неудачи


var motion = new Object();

function $( id) {
    return document.getElementById( id);
}

motion.load = function( mDiv, hDiv, delta, cycle, element, beginFunc, endFunc) {
/*
    конструктор( что_двигать( id), рамка( id),  на_сколько_двигать( px))
    нажатие на левую кнопку    ->  движение вправо  ->  1
    нажатие на правую кнопку  ->  движение влево    -> -1
*/
    this.moutingDiv = mDiv;               // id двигающегося слоя
    this.holdDiv = hDiv;                      // id слоя-рамки
    this.delta = parseInt( delta);       // на сколько двигаться
    if ( !this.delta) {
    	this.delta = parseInt( $( this.holdDiv).offsetWidth);
    }
    this.constantStep = 0;
    this.finalPosition = null;                   // финальная позиция слоя после окончания движения
    this.currentPosition = 0;               // текущая позиция
    this.time = 0;                                 // переменная времени
    this.direction = 0;                          // направление движения
    this.step = 0;                                  // шаг текущего цикла
    this.condition = 0;                         // условие остановки
    this.timeOut = 15;                           // время задержки м/д циклами
    this.cycle = 0;
    this.begin_func = this.defaultEventFunc;
    this.end_func = this.defaultEventFunc;
    if ( beginFunc) {
    	this.begin_func = beginFunc;
    }
    if ( endFunc) {
	    this.end_func = endFunc;
    }
    if ( cycle) {
        this.cycle = 1;                             // нужно перемещать элементы или нет
	    this.currentElement = 0;
        this.cycleElementType = element;
        this.elementArray = $( this.moutingDiv).getElementsByTagName( this.cycleElementType);
        this.mDivWidth = this.elementArray.length * this.delta;
    }
}

motion.load.prototype = {
    init: function( direct, currentFinal) {
        // определяем направление движения
        this.direction = direct;
		this.insertElement();
        // если движение не идет (финальная координата не определена) - прибавляем к кэшу смещения текущее положение
        if ( this.finalPosition == null) {
            this.temp = parseInt( $( this.moutingDiv).style.left);
        }
        // прибавляем к кэшу смещения прирост, равный заранее определённой величине delta ( размер дива, картинки)
        this.temp += this.direction * this.delta;
        // если финальная координата задается
        if ( currentFinal) {
            if ( currentFinal > (parseInt( $( this.moutingDiv).style.width) - Math.floor( $( this.holdDiv).offsetWidth / this.delta) * this.delta)) {
                currentFinal = parseInt( $( this.moutingDiv).style.width) - Math.floor( $( this.holdDiv).offsetWidth / this.delta) * this.delta;
            }
            clearTimeout( this.time);
            this.finalPosition = currentFinal;
			// поехали
			this.move();
        } else if ( ( this.direction > 0 && this.temp <= 0) || ( this.direction < 0 && ( Math.abs( this.temp) <= Math.abs( parseInt( $( this.moutingDiv).offsetWidth) - Math.floor( $( this.holdDiv).offsetWidth / this.delta) * this.delta)))) {
             // условие присутствия реакции на нажатие кнопок-активаторов
             // отчищаем ссылку на таймаут, определяем финальную координату и начинаем движение
            clearTimeout( this.time);
            this.finalPosition = this.temp;
			// поехали
			this.move();
        }
    },
    move: function() {
        // присваем this переменной для функции setTimeout, которая просто this не понимает
        thisObj = this;
        // определяем currentPosition
        this.currentPosition = parseInt( $( this.moutingDiv).style.left);
		// если шаг не задан явно
        if ( !this.constantStep) {
			// определяем прирост для данного цикла ( описание закона движения)
			this.step = this.direction * Math.round (Math.abs( this.finalPosition - this.currentPosition) / 7);
			if ( Math.abs (this.step) < 2) {
				this.step = this.direction * 1;
			}
        } else {
        	// выполняем прирост на заданое значение
        	this.step = this.constantStep;
        }
        // определяем условие повторного вызова этой функции ( достигается ли за этот цикл финальная позиция)
        if ( this.direction > 0) {
             this.condition = (this.currentPosition < this.finalPosition);
        } else {
            this.condition = (this.currentPosition > this.finalPosition);
        }
        if ( this.condition) {
            // передвигаем слой и перезапускаем функцию
            $( this.moutingDiv).style.left = (this.currentPosition + this.step) + "px";
            this.time = window.setTimeout( function() { thisObj.move() }, thisObj.timeOut);
        } else {
            // чистим таймаут и обнуляем переменные
            clearTimeout( this.time);
            this.finalPosition = null;
            this.time = null;
            this.step = 0;
            // вызываем внешнюю функцию
            this.end_func.call( this);
        }
    },
    insertElement: function() {
		if ( this.cycle == 1) {
			if ( this.currentElement == (this.elementArray.length - 1) && this.direction < 0) {
// 				alert( "step1");
				this.elementArray = $( this.moutingDiv).getElementsByTagName( this.cycleElementType);
				$( this.moutingDiv).style.left = ($( this.moutingDiv).offsetLeft + this.delta) + "px";
				$( this.moutingDiv).appendChild( document.getElementById( this.elementArray[0].id));
				this.currentElement = this.elementArray.length - 1;
			} else if ( this.currentElement == 0 && this.direction > 0) {
// 				alert( "step2");
				this.elementArray = $( this.moutingDiv).getElementsByTagName( this.cycleElementType);
 				$( this.moutingDiv).style.left = ( $( this.moutingDiv).offsetLeft - this.delta) + "px";
				this.lastElement = this.elementArray.length - 1;
				this.firstElement = 0;
				$( this.moutingDiv).insertBefore( document.getElementById( this.elementArray[this.lastElement].id),  document.getElementById( this.elementArray[this.firstElement].id));
				this.currentElement = 0;
			} else {
// 				alert( "step3");
				this.currentElement += (-1) * this.direction;
			}
		}
		// вызываем внешнюю функцию
		this.begin_func.call( this);
    },
	defaultEventFunc: function() {
    }

}