var carousel = function () {
	var config = {
		slider : 'div#carousel_slider',
		holder : 'div#carousel_slider ul',
		items : 'div#carousel_slider ul li',
		single : 'div#carousel_slider ul li:first',
		emptyFirst : 'div#carousel_slider ul li.empty:first',
		
		products : 'div#carousel_slider ul li.products',
		productsRollover : 'products_rollover',
		productPrice : 'div.product_price',
		
		arrows : 'a.arrow_carousel',
		arrowPrev : 'a.arrow_carousel.back',
		arrowNext : 'a.arrow_carousel.forward',
		disabled : 'disabled',
		selected : 'selected',
		
		itemsLength : 0,
		singleWidth : 0
	},
	
	params = {
		running : false,
		speed : 600,
		visible : 4,
		start : 0,
		pageCount : 0,
		currentPage : 1,
		currentItem : '',
		arrowNormalImg : {
			carouselBack : {src : 'http://media.canon-asia.com/v3.5media/common/carousel_arrow_back_normal.jpg', isEnabled : true, isHover : false},
			carouselForw : {src : 'http://media.canon-asia.com/v3.5media/common/carousel_arrow_forward_normal.jpg', isEnabled : true, isHover : false}
		}
	},
	
	priv = {
		getInitialArrowImages : function() {
			params.arrowNormalImg.carouselBack.src = $(config.arrowPrev).find('> img').attr('src');
			params.arrowNormalImg.carouselForw.src = $(config.arrowNext).find('> img').attr('src');
		},
		
		setEmptyItems : function () {
			var modulus = config.itemsLength % params.visible;
			if (modulus != 0) {
			    $(config.holder).append( priv.repeat('<li class="empty"></li>', params.visible - modulus) );
				priv.setItemsLength();
			};
			$(config.emptyFirst).css({marginLeft : '1px'});
		},
		
		slideCarousel : function (to, dir) {
			if(!params.running) {
				if (to < 0 || to > config.itemsLength - params.visible) {
					return;
				}
				else {
					params.start = to;
					params.currentPage = dir == config.arrowPrev ? params.currentPage -= 1 : params.currentPage += 1;
				}
				params.running = true;
				
                $(config.slider).animate(
                    {scrollLeft : (params.start * config.singleWidth)},
					params.speed,
                    function () {
                        params.running = false;
                    }
                );
            };
            return false;
        },
		
		hoverCarousel : function () {
			$(config.items).filter(config.products).hover(
				function () {
					if(!isMobile())
						$(this).not('.'+config.selected).addClass(config.productsRollover).find(config.productPrice).show();
					else
						$(this).not('.'+config.selected).addClass(config.productsRollover).find(config.productPrice).hide();
				},
				function () {
					$(this).removeClass(config.productsRollover).find(config.productPrice).hide();
					$('.'+config.selected).find(config.productPrice).show();
				}
			);
		},
		
		setCarouselArrows : function () {
			if (config.itemsLength <= params.visible){
				$(config.arrows).hide();
			} 
			else {
				$(config.arrowPrev).click( function () {
	                priv.slideCarousel( (params.start - params.visible),  config.arrowPrev);
					priv.setArrowState();
	            });
	            $(config.arrowNext).click( function () {
	                priv.slideCarousel( (params.start + params.visible),  config.arrowNext);
					priv.setArrowState();
	            });
			};
		},
		
		setHoverCarouselArrows : function () {
			$(config.arrows).hover(
				function () {
					priv.setArrowHover(this, true);
				},
				function () {
					priv.setArrowHover(this, false);
				}
			);
		},
		
		setArrowEnabled : function(selector, state) {
			priv.setArrowImage(selector, {isEnabled : state});
		},
		
		setArrowHover : function(selector, state) {
			priv.setArrowImage(selector, {isHover : state});
		},
		
		setArrowImage : function(selector, state) {
			var img = $(selector).find('> img');
			var id = img.attr('id');
			var arrowObj = params.arrowNormalImg[id];
			
			for (var key in state) {
				arrowObj[key] = state[key];
			}

			var stateStr = 'inact';
			
			if (arrowObj.isEnabled) {
				if (arrowObj.isHover) {
					stateStr = 'hover';
				} else {
					stateStr = 'normal';
				}
			}
			//var src = arrowObj.src.replace('normal.jpg', stateStr + '.jpg');
			var src = arrowObj.src.replace('inact.jpg', 'normal' + '.jpg');
			src = src.replace('normal.jpg', stateStr + '.jpg');
			img.attr('src', src);
		},
		
		setArrowState : function () {
			priv.setArrowEnabled(config.arrowNext, params.currentPage != params.pageCount);
			priv.setArrowEnabled(config.arrowPrev, params.currentPage != 1);
		},
		
		visual : function () {
			return $(config.items).slice(params.start).slice( 0, params.visible);
		},
		
		repeat : function (str, num) {
		    return new Array(num + 1).join(str);
		},
		
		setItemsLength : function () {
			return config.itemsLength = $(config.items).length;
		},
		
		setItemWidth : function () {
			config.singleWidth = $(config.single).outerWidth(true);
		},
		
		setPageCount : function () {
			params.pageCount = Math.ceil(config.itemsLength / params.visible);
		}
	};
	
	return {
		setSelectedItem : function (itemId, position) {
			
			params.start = position * params.visible;
			if (position != 0){
				params.currentPage += position;	
			};
			if (itemId != ''){
				params.currentItem = 'li#' + itemId;
				$(params.currentItem).addClass(config.selected);
				$('.'+config.selected).find(config.productPrice).show();
			};
			
			$(config.slider).scrollLeft( (params.start * config.singleWidth));
			
			//priv.slideCarousel( (params.start + params.visible),  config.arrowNext);
			priv.setArrowState();
		},
		
		initiate : function () {
			priv.getInitialArrowImages();
			priv.setItemsLength();
			priv.setItemWidth();
			priv.setPageCount();
			priv.setEmptyItems();
			priv.hoverCarousel();
			priv.setCarouselArrows();
			priv.setHoverCarouselArrows();
		}
	};
}();

$(document).ready( function () {
 	carousel.initiate();
});

function isMobile() {
	return isMobileDevice(navigator.userAgent||navigator.vendor||window.opera);
}

function isMobileDevice(a){
	// ***** FOR FUTURE DEVELOPERS *****
	// CODES IS COPIED FROM http://detectmobilebrowser.com/
	
	if(/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))
		return true;
	
	if(/android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a))
		return true;
		
	return false;
}
