var transaction = function (element1, element2) {
	var THIS, stepCounter = 0, step, speed, v;
	//------
	var customParams = {};
	//------
	var localParams = {
		apeed: 1,
		step: 0.2
	};
	//------
	var isLock = function () {
		if (! transaction.lockElements) {
			transaction.lockElements = {};
		}
		if (! element1.uniqueID) {
			element1.uniqueID = Math.random();
		}
		if (! element2.uniqueID) {
			element2.uniqueID = Math.random();
		}
		if (element1.uniqueID in transaction.lockElements || 
		element2.uniqueID in transaction.lockElements) {
			return true;
		}
		transaction.lockElements[element1.uniqueID] = 1;
		transaction.lockElements[element2.uniqueID] = 1;
		return false;
	}
	//------
	var releaseLock = function () {
		delete transaction.lockElements[element1.uniqueID];
		delete transaction.lockElements[element2.uniqueID];
	};
	//------
	var init = function () {
		THIS = this;
		if (isLock()) {
			return false;
		}
		element2.style.filter = "progid:DXImageTransform.Microsoft.Alpha(0)";
		element2.style.visibility = "visible";
		apply();
	};
	//------
	var onTransactionEnd = function () {
		releaseLock();
		stepCounter = 0;
		element1.style.cssText = "";
		element2.style.cssText = "";
		element1.style.visibility = "hidden";
		element2.style.visibility = "visible";
		var goTo = localParams.onTransactionEnd;
		if (goTo) {
			goTo(THIS);
		}
	};
	//------
	var apply = function () {
		clearTimeout(v);
		step = localParams.step;
		speed = localParams.speed;
		stepCounter += step;
		if (stepCounter >= 10) {
			stepCounter = 10;
		}
		element1.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + (10 - stepCounter) * 10 + ")";
		element2.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + stepCounter * 10 + ")";
		element1.style.opacity = (10 - stepCounter) / 10;
		element2.style.opacity = stepCounter / 10;
		if (stepCounter < 10) {
			v = setTimeout(apply, speed);
		} else {
			onTransactionEnd();
		}
	};
	//------
	var applyElements = function (a, b) {
		element1 = a;
		element2 = b;
	};
	//------
	return {
		start: init,
		applyElements: applyElements,
		setSpeed: function (value) {
			localParams.speed = value;
		},
		setStep: function (value) {
			localParams.step = value;
		},
		onTransactionEnd: function (goTo) {
			localParams.onTransactionEnd = goTo;
		},
		setParam: function (param, value) {
			customParams[param] = value;
		},
		getParam: function (param) {
			return customParams[param] || localParams[param];
		},
		toString: function () {
			return "This function perform transaction between two html elements";
		}
	};
};


var autoTransaction = function () {
	var imgColl = document.getElementById("slideshowimage").getElementsByTagName("img");
	var i, l;
	var elementsArr = [];
	var v;
	//------
	for (i = 0, l = imgColl.length; i < l; i += 1) {
		elementsArr.push(imgColl[i]);
	}
	//------
	var afterTransactionEnd = function () {
		v = setTimeout(initFunc, 2000);
	};
	//------
	var t = transaction(elementsArr[0], elementsArr[1]);
	var firstElementIndex = 0;
	var secondElementIndex = 1;
	var initFunc = function () {
		clearTimeout(v);
		//alert()
		t.applyElements(elementsArr[firstElementIndex], elementsArr[secondElementIndex]);
		t.onTransactionEnd(afterTransactionEnd);
		t.start();
		firstElementIndex += 1;
		secondElementIndex += 1;
		if (secondElementIndex === elementsArr.length) {
			firstElementIndex = secondElementIndex - 1;
			secondElementIndex = 0;
		}
		if (firstElementIndex === elementsArr.length) {
			firstElementIndex = 0;
		}
	};
	afterTransactionEnd();
};
