function SjProductListing() {
	this.plDivHolderId = 'productListingContainer';
	this.plMainImageHolderId = 'izView';
	this.plMainImageId = 'plMainImage';
	this.plMoreColorsAvailableId = 'plMoreColorsAvailable';
	this.plMoreViewsId = 'plMoreViews';
	this.serverUrl = '/is/image/';
	this.imageList = null;
	this.colorCode = null;
	this.anchor = null;
	this.showDelay = 1000;
	this.hideId = null;
	this.modifiers = null;
	this.skuArray = null;
	this.productDetailURL = null;
	this.validator = new SjValidator(this);
	this.onEvent = new Object();
	this.startTime = (new Date()).getTime();
	this.sessionId = this.createSessionId();
	this.imageListsArray = new Array();
	this.color_attributes_list = ['_A', '_B', '_C', '_D', '_E', '_F', '_G', '_H', '_I'];
};

SjProductListing.prototype.setServerUrl = function(inServerUrl) {
	this.serverUrl = inServerUrl;
	if (this.serverUrl.charAt(this.serverUrl.length - 1) != '/') {
		this.serverUrl += '/';
	}
};

SjProductListing.prototype.setColorCode = function(inColorCode) {
	this.colorCode = inColorCode;
};

SjProductListing.prototype.getImageList = function() {
	this.imageList = '';
	if (this.imageListsArray[this.colorCode] != null){
		for (var i = 0; i < this.imageListsArray[this.colorCode].imageList.length; i++){
			if (this.imageList == ''){
				this.imageList += this.imageListsArray[this.colorCode].imageList[i];
			} else {
				this.imageList += ',' + this.imageListsArray[this.colorCode].imageList[i];
			}
		}
		this.doShow();
	} else {
		this.doGetImageList();
	}
};

SjProductListing.prototype.doGetImageList = function() {
	this.imageListsArray[this.colorCode] = new Object();
	this.imageListsArray[this.colorCode].jsonResponseArray = new Array();
	this.imageListsArray[this.colorCode].imageList = new Array();
	this.imageListsArray[this.colorCode].responseIdx = 0;
	for (var i = 0; i < this.color_attributes_list.length; i++) {
		this.check(this.colorCode, i);
	}
};

SjProductListing.prototype.check = function(inColorCode, i) {
	var image = 'samsclub/' + inColorCode + this.color_attributes_list[i];
	var selfRef = this;
	var obj = new Object();
	
	obj.colorId = inColorCode;
	obj.image = inColorCode + this.color_attributes_list[i];
	this.imageListsArray[inColorCode].jsonResponseArray.push(obj);
	this.imageListsArray[inColorCode].jsonResponseArray[i].jsonResponse = function(inData){
		selfRef.imageListsArray[this.colorId].responseIdx ++;
		if (inData['catalogRecord.exists'] == 1){
			selfRef.imageListsArray[this.colorId].imageList.push(this.image);

		}
		if (selfRef.color_attributes_list.length == selfRef.imageListsArray[this.colorId].responseIdx){
			var imList = selfRef.imageListsArray[this.colorId].imageList;
			for (var j = 0; j < imList.length; j++){
				if (selfRef.imageList == ''){
					selfRef.imageList += imList[j];
				} else {
					selfRef.imageList += ',' + imList[j];						
				}
			}
			selfRef.doShow();
		}
	};
	var id = image;
	sjGetResponse(
		this.serverUrl + image + '?req=exists,json',
		function (inData) {
			obj.jsonResponse(inData);
		},
		function (inData) {
			//by design, fail quitely
			//alert('unable to load image props for ips id [' + heroImageName + ']: ' + inData.message);
		}
	);
};

SjProductListing.prototype.setAnchor = function(inAnchor) {
	this.anchor = inAnchor;
};

SjProductListing.prototype.setShowDelay = function(inShowDelay) {
	this.showDelay = inShowDelay;
};

SjProductListing.prototype.setModifiers = function(inModifiers) {
	this.modifiers = inModifiers;
};

SjProductListing.prototype.setSKU = function(inSKUArray) {
	this.skuArray = inSKUArray;
};

SjProductListing.prototype.setProductDetailURL = function(inProductDetailURL) {
	this.productDetailURL = inProductDetailURL;
};

SjProductListing.prototype.requestShow = function() {
	if (this.hideId != null) {
		clearTimeout(this.hideId);
		this.hideId = null;
	}
	var selfRef = this;
	setTimeout(
		function() {
			selfRef.show();
		}, this.showDelay
	);
};

SjProductListing.prototype.requestHide = function() {
	var selfRef = this;
	this.hideId = setTimeout(
		function() {
			selfRef.hide();
		}, 100
	);
};

SjProductListing.prototype.show = function() {
	if (this.anchor == null) {
		return;
	}
	if (!this.validate()) {
		return;
	}	
	this.getImageList();
};

SjProductListing.prototype.doShow = function() {
	var originalPosition = this.anchor.style.position;
	this.anchor.style.position = 'relative';
	var centerX = Math.round(this.anchor.offsetLeft + this.anchor.offsetWidth / 2);
	var centerY = Math.round(this.anchor.offsetTop + this.anchor.offsetHeight / 2);
	this.anchor.style.position = originalPosition;
	var plDivHolder = document.getElementById(this.plDivHolderId);
	plDivHolder.style.left = centerX + 'px';
	plDivHolder.style.top = (centerY - 100) + 'px';
	plDivHolder.style.visibility = 'inherit';

	var selfRef = this;
	this.anchor.onmouseout = function() {
		selfRef.requestHide();
	};
	plDivHolder.onmouseover = function() {
		if (selfRef.hideId != null) {
			clearTimeout(selfRef.hideId);
			selfRef.hideId = null;
		}
	};
	plDivHolder.onmouseout = function() {
		selfRef.requestHide();
	};
	if (this.productDetailURL != null) {
		plDivHolder.onmouseup = function() {
			document.location.href = selfRef.productDetailURL;
		};
	}

	var plMoreColorsAvailable = document.getElementById(this.plMoreColorsAvailableId);
	plMoreColorsAvailable.style.visibility = 'hidden';
	if ((this.skuArray != null) && (this.skuArray.length > 0)) {
		var toknes = this.skuArray[0].split('|');
		if (toknes.length > 3) {
			var text = toknes[3];
			plMoreColorsAvailable.innerHTML = text;
		}
		plMoreColorsAvailable.style.visibility = 'inherit';
	}

	var plMoreViews = document.getElementById(this.plMoreViewsId);
	plMoreViews.style.visibility = 'hidden';

	var tokens = this.imageList.split(',');

	var firstImage;
	if (tokens.length > 0) {
		firstImage = 'samsclub/' + tokens[0];
	} else {
		firstImage = 'samsclub/';
	}
	
	this.loadMainImage(firstImage);
	this.loadLabel(firstImage, document.getElementById(this.plMainImageId));

	for (var i = 1; i < 6; i ++) {
		var swatch = document.getElementById('swatch' + (i - 1));
		swatch.style.visibility = 'hidden';
	}

	var selfRef = this;
	for (var i = 0; (i < tokens.length) && (i < 5); i ++) {
		var imageName = 'samsclub/' + tokens[i];
		var swatch = document.getElementById('swatch' + i);
		swatch.style.visibility = 'inherit';
		swatch.src = this.serverUrl + imageName + '?wid=56&hei=56' + (this.modifiers == null ? '' : '&' + this.modifiers);
		swatch.imageName = imageName;
		swatch.idx = i;

		swatch.onmouseover = function() {
			selfRef.loadMainImage(this.imageName);
			selfRef.evtPAGE(this.idx, null);
		};

		this.loadLabel(imageName, swatch);
	}

	if (tokens.length > 5) {
		plMoreViews.style.visibility = 'inherit';
	}
};

SjProductListing.prototype.hide = function() {
	var plDivHolder = document.getElementById(this.plDivHolderId);
	plDivHolder.style.visibility = 'hidden';
	plDivHolder.onmouseover = null;
	plDivHolder.onmouseout = null;
	this.anchor = null;
};

SjProductListing.prototype.loadMainImage = function(inImageName) {
	var plMainImageHolder = document.getElementById(this.plMainImageHolderId);
	var width = plMainImageHolder.offsetWidth;
	var height = plMainImageHolder.offsetHeight;
	var plMainImage = document.getElementById(this.plMainImageId);
	plMainImage.src = this.serverUrl + inImageName + '?wid=' + width + '&hei=' + height + (this.modifiers == null ? '' : '&' + this.modifiers);
};

SjProductListing.prototype.loadLabel = function(inImageName, inElm) {
/*
	temporary disabled
	sjGetResponse(
		this.serverUrl + inImageName + '?req=userdata,json',
		function (inData) {
			//look for the first non-empty key (in order to not bother with passing labelKey)
			var label = null;
			for (var field in inData) {
				if (inData[field] != null) {
					label = inData[field];
				}
			}
			if ((label != null) && (label != '')) {
				inElm.title = label;
				inElm.alt = label;
			}
		},
		function (inData) {
			alert('unable to load userdata for ips id [' + inImageName + ']: ' + inData.message);
		}
	);
*/
};

SjProductListing.prototype.evtPAGE = function(inIdx, inLabel) {
	if (this.onEvent.onLogEvent != null) {
		var eventData = 'PAGE,' + inIdx + (inLabel != null ? ',' + inLabel : '');
		var time = Math.round(((new Date().getTime()) - this.startTime) / 1000);
		this.onEvent.onLogEvent(eventData, time, this.sessionId, null);
	}
};

SjProductListing.prototype.createSessionId = function() {
	//can't use random due to safari crash
	var d = new Date();
	var n = d.getTime() * d.getMilliseconds() * d.getTimezoneOffset();
	return this.intToHex(Math.abs(n), 16);
};

SjProductListing.prototype.intToHex = function(inVal, inLength) {
	var num = new Number(inVal);
	var hexStr = num.toString(16);
	if (inLength != null) {
		while (hexStr.length < inLength) {
			hexStr = '0' + hexStr;
		}
	}
	return hexStr;
};

SjProductListing.prototype.validate = function() {
	if (!this.validator.notNull('serverUrl')) {
		return false;
	}
	if (!this.validator.notNull('imageList')) {
		return false;
	}
	if (!this.validator.notNull('colorCode')) {
		return false;
	}
	if (!this.validator.elementNotNull('plDivHolderId')) {
		return false;
	}
	if (!this.validator.elementNotNull('plMainImageHolderId')) {
		return false;
	}
	if (!this.validator.elementNotNull('plMainImageId')) {
		return false;
	}
	if (!this.validator.elementNotNull('plMoreColorsAvailableId')) {
		return false;
	}
	if (!this.validator.elementNotNull('plMoreViewsId')) {
		return false;
	}
	return true;
};

