﻿function Animator(options) {
	this.setOptions(options);
	var _this = this;
	this.timerDelegate = function () { _this.onTimerEvent() };
	this.subjects = [];
	this.target = 0;
	this.state = 0;
	this.lastTime = null;
};
Animator.prototype = {
    // apply defaults
    setOptions: function (options) {
        this.options = Animator.applyDefaults({
            interval: 20,  // time between animation frames
            duration: 400, // length of animation
            onComplete: function () { },
            onStep: function () { },
            transition: Animator.tx.easeInOut,
            optionalDuration: 0
        }, options);
    },
    // animate from the current state to provided value
    seekTo: function (to) {
        this.seekFromTo(this.state, to);
    },
    // animate from the current state to provided value
    seekFromTo: function (from, to) {
        this.target = Math.max(0, Math.min(1, to));
        this.state = Math.max(0, Math.min(1, from));
        this.lastTime = new Date().getTime();
        if (!this.intervalId) {
            this.intervalId = window.setInterval(this.timerDelegate, this.options.interval);
        }
    },
    // animate from the current state to provided value
    jumpTo: function (to) {
        this.target = this.state = Math.max(0, Math.min(1, to));
        this.propagate();
    },
    // seek to the opposite of the current target
    toggle: function () {
        this.seekTo(1 - this.target);
    },
    // add a function or an object with a method setState(state) that will be called with a number
    // between 0 and 1 on each frame of the animation
    addSubject: function (subject) {
        this.subjects[this.subjects.length] = subject;
        return this;
    },
    // remove all subjects
    clearSubjects: function () {
        this.subjects = [];
    },
    // forward the current state to the animation subjects
    propagate: function () {
        var value = this.options.transition(this.state);
        for (var i = 0; i < this.subjects.length; i++) {
            if (this.subjects[i].setState) {
                this.subjects[i].setState(value);
            } else {
                this.subjects[i](value);
            }
        }
    },
    // called once per frame to update the current state
    onTimerEvent: function () {
        var now = new Date().getTime();
        var timePassed = now - this.lastTime;
        this.lastTime = now;
        var movement = (timePassed / (this.options.optionalDuration > 0? this.options.optionalDuration : this.options.duration)) * (this.state < this.target ? 1 : -1);
        if (Math.abs(movement) >= Math.abs(this.state - this.target)) {
            this.state = this.target;
        } else {
            this.state += movement;
        }

        try {
            this.propagate();
        } finally {
            this.options.onStep.call(this);
            if (this.target == this.state) {
                window.clearInterval(this.intervalId);
                this.intervalId = null;
                this.options.onComplete.call(this);
            }
        }
    },
    // shortcuts
    play: function (opt_duration) {
        this.options.optionalDuration = opt_duration;
        this.seekFromTo(0, 1);
    },
    reverse: function () {
        this.seekFromTo(1, 0);
    },
    stop: function () {
        window.clearInterval(this.intervalId);
        this.intervalId = null;
    }
}
// merge the properties of two objects
Animator.applyDefaults = function(defaults, prefs) {
	prefs = prefs || {};
	var prop, result = {};
	for (prop in defaults) result[prop] = prefs[prop] !== undefined ? prefs[prop] : defaults[prop];
	return result;
}
// make an array from any object
Animator.makeArrayOfElements = function(o) {
	if (o == null) return [];
	if ("string" == typeof o) {
		return [document.getElementById(o)];
	}
	if (!o.length) return [o];
	var result = [];
	for (var i=0; i<o.length; i++) {
		if ("string" == typeof o[i]) {
			result[i] = document.getElementById(o[i]);
		} else {
			result[i] = o[i];
		}
	}
	return result;
}
Animator.camelize = function(string) { return string.replace(/(-[a-z])/gi, function(m) { return m.toUpperCase().substring(1); }); }

Animator.makeEaseIn = function(a) { return function(state) { return Math.pow(state, a*2); } }
Animator.makeEaseOut = function(a) { return function(state) { return 1 - Math.pow(1 - state, a*2); } }
Animator.makeElastic = function(bounces) {	return function(state) { state = Animator.tx.easeInOut(state);	return ((1-Math.cos(state * Math.PI * bounces)) * (1 - state)) + state; } }
Animator.makeBounce = function(bounces) { var fn = Animator.makeElastic(bounces); return function(state) { state = fn(state); return state <= 1 ? state : 2-state; } }

// make an Attack Decay Sustain Release envelope that starts and finishes on the same level
Animator.makeADSR = function(attackEnd, decayEnd, sustainEnd, sustainLevel) {
	if (sustainLevel == null) sustainLevel = 0.5;
	return function(state) {
		if (state < attackEnd) return state / attackEnd;
		if (state < decayEnd)  return 1 - ((state - attackEnd) / (decayEnd - attackEnd) * (1 - sustainLevel));
		if (state < sustainEnd)return sustainLevel;
		return sustainLevel * (1 - ((state - sustainEnd) / (1 - sustainEnd)));
	}
}

Animator.tx = {
	easeInOut: function(pos){
		return ((-Math.cos(pos*Math.PI)/2) + 0.5);
	},
	linear: function(x) {
		return x;
	},
	easeIn: Animator.makeEaseIn(1.5),
	easeOut: Animator.makeEaseOut(1.5),
	strongEaseIn: Animator.makeEaseIn(2.5),
	strongEaseOut: Animator.makeEaseOut(2.5),
	elastic: Animator.makeElastic(1),
	veryElastic: Animator.makeElastic(3),
	bouncy: Animator.makeBounce(1),
	veryBouncy: Animator.makeBounce(3)
}

// animates a pixel-based style property between two integer values
function NumericalStyleSubject(els, property, from, to, units) {
	this.els = Animator.makeArrayOfElements(els);
	if (property == 'opacity' && window.ActiveXObject) {
		this.property = 'filter';
	} else {
		this.property = Animator.camelize(property);
	}
	this.from = parseFloat(from);
	this.to = parseFloat(to);
	this.units = units != null ? units : 'px';
}
NumericalStyleSubject.prototype = {
    setState: function (state) {
        var style = this.getStyle(state);
        var visibility = (this.property == 'opacity' && state == 0) ? 'hidden' : '';
        var j = 0;
        for (var i = 0; i < this.els.length; i++) {
            try {
                this.els[i].style[this.property] = style;
            } catch (e) {
                // ignore fontWeight - intermediate numerical values cause exeptions in firefox
                if (this.property != 'fontWeight') throw e;
            }
            if (j++ > 20) return;
        }
    },
    getStyle: function (state) {
        state = this.from + ((this.to - this.from) * state);

        if (this.property == 'filter') return "alpha(opacity=" + Math.round(state * 100) + ")";
        if (this.property == 'opacity') return state;
        return Math.round(state) + this.units;
    }
}

// animates a property between two integer values
function NumericalSubject(els, property, from, to) {
	this.els = Animator.makeArrayOfElements(els);
	this.property = property;
	this.from = parseFloat(from);
	this.to = parseFloat(to);
}
NumericalSubject.prototype = {
	setState: function(state) {
		var j=0;
		for (var i=0; i<this.els.length; i++) {
			this.els[i][this.property] = Math.round(this.from + ((this.to - this.from) * state));
			if (j++ > 20) return;
		}
	}
}


function chn(element, tn, op, f) {
	if(f == null) f = 0;
	if(op == null) op = 100;
	if(f == 0){
	if(document.getElementsByClassName('preloader').length>0){
	elems=document.getElementsByClassName('preloader');
	for(var i=0;i<elems.length;i++)elems[i].className='preloader_white';
	}
	if(op > 0){
	setOpacity(document.getElementById(element), op);
	op-=10;
	setTimeout('chn(\'' + element + '\',\'' + tn + '\',' + op + ', 0)',50);
	return;
	}
	}else{
	if(document.getElementsByClassName('preloader').length>0){
	elems=document.getElementsByClassName('preloader');
	for(var i=0;i<elems.length;i++)elems[i].className='preloader_white';
	}
	if(op <= 100){
	setOpacity(document.getElementById(element), op);
	op+=10;
	setTimeout('chn(\'' + element + '\',\'' + tn + '\',' + op + ', 1)',50);
	return;
	}else return;
	}
	if(document.getElementsByClassName('preloader_white').length>0){
	elems=document.getElementsByClassName('preloader_white');
	for(var i=0;i<elems.length;i++)elems[i].className='preloader';
	}
	document.getElementById(element).src='' + tn + '';
	chn(element,tn, 0, 1);
}

document.getElementsByClassName = function(clsName){
   var retVal = new Array();
   var elements = document.getElementsByTagName("*");
   for(var i = 0;i < elements.length;i++){
       if(elements[i].className.indexOf(" ") >= 0){
           var classes = elements[i].className.split(" ");
           for(var j = 0;j < classes.length;j++){
               if(classes[j] == clsName)
                   retVal.push(elements[i]);
           }
       }
       else if(elements[i].className == clsName)
           retVal.push(elements[i]);
   }
   return retVal;
}

function setOpacity(el,op){
	opacity='0.'+op;
	opie='alpha(opacity: '+op+')';
	switch(op){
		case 100: opacity='1.0'; break;
		case 9: opacity='0.09'; break;
		case 8: opacity='0.08'; break;
		case 7: opacity='0.07'; break;
		case 6: opacity='0.06'; break;
		case 5: opacity='0.05'; break;
		case 4: opacity='0.04'; break;
		case 3: opacity='0.03'; break;
		case 2: opacity='0.02'; break;
		case 1: opacity='0.01'; break;
		case 0: opacity='0.0'; break;
	}
	el.style.filter=opie;
	el.style.KHTMLOpacity=opacity;
	el.style.MozOpacity=opacity;
	el.style.opacity=opacity;
}

function tim_galleryim()
{
	prev_rand_galleryim++;
	
	if (prev_rand_galleryim >= 5) prev_rand_galleryim = 0;
	
	chn('infotxt', tablica_galleryim[prev_rand_galleryim]);
	setTimeout("tim_galleryim()", 7000);
}


function gallery_delay()
{
	setTimeout("tim_galleryim()", 7000);	
}
