/*
	asyncart.js
	- validates input for AddToCart-Value
	- allows adding products asynchronously to cart
	- refreshes MiniCart
	- prepares, changes and handle Notification-Div a.k.a "Cart-Popup"
	
	13.01.10 Performance improvements & restructuring of functions
	// MarioW	
*/

// Global Vars
/*global
document , window, event, navigator, 
loctext,
AsyncCart , DWREngine , 
clearTimeout
*/

var clicked = false;
var	doWait=true;
var notvalid = false;
var GLOB_POS = 'absolute';

var actualCart = null;
var i =0;
var clicked=false;
var timer_3sec = 0;
var timer_8sec = 0;
var mouse_over=false;
var waited_8sec_over=false;
var waited_8sec=false;
var waited_3sec=false;
var started_wait_8sec = false;
var started_wait_3sec = false;
var mouse_clicked = false;
var global_mouseX=300;
var global_mouseY=300;

// reset Globals to initial value
function initGlobals(){
	clicked=false;
	timer_3sec = 0;
	timer_8sec = 0;
	mouse_over=false;
	waited_8sec_over=false;
	waited_8sec=false;
	started_wait_8sec = false;
	started_wait_3sec = false;
	waited_3sec=false;
	mouse_clicked = false;
}

// add Space to EUR Values before chanching MiniCart
function addSpaces(inputNumber) {
	if (inputNumber && inputNumber.indexOf("EUR") === 0) {
	   return inputNumber.substring(3) + " EUR";
	}
	else {
	   return inputNumber;
	}
}

// validate Input-Value for changeing Article-Count
function getNumberArticle(articleId) {
    var countElement = 'count_' + articleId;
    var temp = document.getElementById(countElement);

    var value = 1;
    if (temp) {
        var temp2 = temp.value;
		// check if value is a number
        if (temp2 && isFinite(temp2)) {
            value = Math.round(temp2);
            notvalid = false;	
		}
	    if (temp2 && !isFinite(temp2) && (temp2!='') ) {
			notvalid = true;
        }
    }
    return value;
}

// show that product is added already
function displayAddedValue(articleID) {
	// if set to 0 show "normal" cartsymbol
	var countElement = 'count_' + articleID;
	var evalCount = getNumberArticle(articleID);
        // Put it back to the edit box
        var ele = document.getElementById(countElement);
        if (ele) {
           ele.value = evalCount;
        }
		if(ele && evalCount === 0){
			ele.value = '';
		}
	clicked = false;
}

// display animated Cart-Gif while Asyn-Call is ongoing
function animateCart(articleId) {
    document.getElementById('cartimg_' + articleId).src = '/images/a-c/cart_animation.gif';
	doWait=true;
}

// show animated Cart at least some time before changing back to Status-Image
function showProductInCartStatus(articleId){
	if (doWait && clicked){
		window.setTimeout("justWait('"+articleId+"')",800);
	}
	else{
        var countElement = 'count_' + articleId;
        var ele = document.getElementById(countElement);

        if (ele && ele.value > 0){
            document.getElementById('cartimg_' + articleId).src = '/images/a-c/cart_success.gif';
            clicked = false;
        }
    }
}

// Deprecated ! - could be consolidated
// start Timer for animated Cart-Image
function justWait(articleId) {
   doWait=false;
   //window.alert("func wait");
   showProductInCartStatus(articleId);
}

// stop ongoing Animation and populate that Animation has finished
function stopCartAnimation(articleId) {
	clicked = false;
}

// set new Article-Value from cart 
function refreshSingleArticleCount(article) {
    if (article && article.articleShopId && article.count) {
        var element = document.getElementById('count_' + article.articleShopId);
        if (element) {
			element.value = article.count;
			showProductInCartStatus(article.articleShopId);
        }
    }
}

// To put the cart item count to the item edit box - if it's available
function refreshArticlesCount(cartitems) {
    if (cartitems) {
        for (var i = 0; i < cartitems.length; i++) {
            refreshSingleArticleCount(cartitems[i]);
        }
		log(i+" cartItems");
    }
}

// Change Notification-popup-Content depending on the Status retrieved from the Async AddToCart-process
function refreshCartMsg(cart,cartstatus,diffValue){
	// get headline locresource
	var headlineText = null,
		cartContent  = "";
	
	// get headline depending on Cart-Status
	switch(cartstatus){
		case 'success': headlineText= loctext["checkout.popup.headline.addedToCart"]; break;
		case 'warning_stock': headlineText=	loctext["checkout.popup.headline.warning"]; break;
		case 'warning': headlineText= loctext["checkout.popup.headline.reducedValue"]; break;
		case 'error'  :	headlineText= loctext["checkout.popup.headline.error"]; break;
		case 'deleted': headlineText= loctext["checkout.popup.headline.deletedFromCart"]; break;
		default		  : headlineText= loctext["checkout.popup.headline.addedToCart"]; break;
	}
	
	// Set new Title & replace param-placeholder 
	if (document.getElementById("cartTitleText")){
		document.getElementById("cartTitleText").innerHTML = headlineText.replace("{0}", diffValue);
	}

	// change Title Background (class)
	if (document.getElementById("cartstatusImg")){
		var imgsrc = document.getElementById("cartstatusImg").src;
		// exchange Status-Image in title
		// due to compatibility reasons with <=IE7 i replace parts of the SRC string
		//     /images/n-p/popup_iconhead_*********.gif       exchange ****** with cartstatus
		document.getElementById("cartstatusImg").src = imgsrc.replace(imgsrc.substring(imgsrc.lastIndexOf("iconhead_")+9, imgsrc.lastIndexOf(".gif")), cartstatus);
	}

	// show CART - added OR deleted OR reduced
	if(cartstatus == 'success' || (cartstatus == 'warning') || cartstatus == 'deleted' ){
		// Normal Cart
		cartContent += '<div class="text" style="padding: 5px 0 5px 30px; font-size: 11px; line-height: 11px;">';
		cartContent += '<table width="140px"  style="margin-left:0px;float:left;">';
		cartContent += '<tr style="height:18px;vertical-align:top;"><td align="left" colspan="2" align="right">'+loctext["checkout.popup.checkoutOverview"]+'</td></tr>';	
		cartContent += '<tr><td align="left" >'+loctext["checkout.popup.quantity"]+'</td><td align="right">'+cart.count+'</td></tr>';
		cartContent += '<tr><td align="left" >'+loctext["checkout.popup.shipping"]+'</td><td align="right"><nobr>'+cart.formattedShipping+'</nobr></td></tr>';
		cartContent += '<tr><td align="left" >'+loctext["checkout.popup.total"]+'</td><td align="right"><nobr>'+cart.formattedValue+'</nobr></td></tr>';
		cartContent += '</table><br class="clear">';
		cartContent += '</div>';
	}
	
	// if not that many Products in Stock get available Amount and display warning
	if(cartstatus == 'warning_stock'){
		//Warning Stock-Count Low
		cartContent += '<div class="text" style="text-align:left; padding: 6px 6px 10px 30px; font-size: 11px; line-height: 11px;">';
		cartContent += '<span>'+loctext["checkout.popup.message.stockWarning"].replace("{0}", diffValue)+'</span>';
		cartContent += '</div>';
	}
	
	// something goes wrong during AddToCart-Process
	if(cartstatus == 'error'){	
		//Error - temporarily not available
		cartContent += '<div class="text" style="text-align:left; padding: 6px 6px 10px 30px; font-size: 11px; line-height: 11px;">';
		cartContent += '<span>'+loctext["checkout.popup.message.error"]+'</span>';
		cartContent += '</div>'	;
	}

	// change Content
	if (document.getElementById("cartContent")){
		document.getElementById("cartContent").innerHTML = cartContent;
	}
}

// Show the Popup in Timeoute-state
function displayPopupTimeout(cart){
	if (mouse_over){
		return false;
	}
	else{
		//start 8sec Timeout
		clearTimeout( timer_8sec );
		clearTimeout( timer_3sec );
		i++;

		if(!started_wait_3sec){
			timer_3sec = window.setTimeout("set_waited(3)",3000);
			started_wait_3sec = true;
		}
	}
}



// flexible Eventhandler (addEvent, removeEvent) made by John Resig - http://ejohn.org/projects/flexible-javascript-events/
function addEvent( obj, type, fn )
{
   if (obj.addEventListener) {
      obj.addEventListener( type, fn, false );
   }
   else if (obj.attachEvent) {
      obj["e"+type+fn] = fn;
      obj[type+fn] = function() { obj["e"+type+fn]( window.event ); };
      obj.attachEvent( "on"+type, obj[type+fn] );
   }
}

function removeEvent( obj, type, fn )
{
   if (obj.removeEventListener) {
      obj.removeEventListener( type, fn, false );
   } else if (obj.detachEvent) {
      obj.detachEvent( "on"+type, obj[type+fn] );
      obj[type+fn] = null;
      obj["e"+type+fn] = null;
   }
}

// Close/Hide the Popup and clear all Stati & Timeouts that belong to this Popup
function closePopup(){
	//window.alert('ClosePopup');
	clearTimeout( timer_8sec );
	clearTimeout( timer_3sec );
	
	// detach events
	var popup = document.getElementById('cart_popup');
	//removeEvent(document,"click",watchClick);
	removeEvent(popup,"mouseover",watchMouseOver);
	removeEvent(popup,"mouseout",watchMouseOut);
	
	// hide popup
	var elem = document.getElementById('cart_popup');
	elem.style.visibility = 'hidden';
	elem.style.left = '-999px';
	elem.style.top  = '-999px';
	clicked=false;
}

// decide if popup should be closed or timeout-state is next
function checkPopupStatusForStateChange(cart){
	if (!mouse_over){
		if ((waited_8sec_over && waited_3sec) || mouse_clicked || waited_3sec || (waited_8sec && (!started_wait_3sec || waited_3sec))){
			closePopup();
		}
		else{		
			if ((waited_8sec_over || (!waited_8sec && started_wait_8sec && !started_wait_3sec))  ){
				displayPopupTimeout(cart);		
			}
			else{
				// no cart status appears often while timeout is still running - so no problem here
			}
		}
	}
		
	// set to default
	mouse_clicked = false;
	//waited_8sec_over=false;
	waited_8sec=false;
	waited_3sec=false;
}

// Checks if an Event is Thrown inside a Node-Tree with Parent (parentID) on top
function eventThrownInside(e, objId){

	// get Target of mouseMovement // script from http://www.quirksmode.org/js/events_mouse.html
	var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;

	// theres a firefox Bug that shows up an error if we try to access property of reltg:
	// Error: Permission denied to access property 'xyz' from a non-chrome context
	try{
		while (reltg && reltg.id != objId && reltg.nodeName != 'BODY'){
			if (reltg.parentNode){
				reltg = reltg.parentNode;
			}else{
				break;
			}
		}
		// Inside Event Bubbling
		if (reltg && reltg.id && reltg.id == objId) {
			return true;
		}
		
		// Moved to Outside 
		if(reltg && reltg.nodeName && reltg.nodeName == 'BODY'){
			return false;
		}
		else{
			return true;
		}
	}
	catch(error){
		// if something goes wrong - send back that event is Outside of Popup
		return false;
	}
}

// Check for Mouse Over Popup - initiate Status comparation
function watchMouseOver(e){
	if (eventThrownInside(e, 'cart_popup')){
		mouse_over=true;
	}
	if(actualCart && actualCart !== null){
		checkPopupStatusForStateChange(actualCart);	
	}
}

// Check for Mouse Out Popup - initiate Status comparation
function watchMouseOut(e){
	//get Area in which the Event is thrown
	if (!eventThrownInside(e, 'cart_popup')){
		mouse_over = false;	
	}
	if(actualCart && actualCart !== null){
		checkPopupStatusForStateChange(actualCart);
	}
}

// Check for Mouse Click - initiate Status comparation
function watchClick(e){
	mouse_clicked = true;
	// added check to determine if click is outside popup - to close it imediately
	if (!eventThrownInside(e, 'cart_popup')){
		mouse_over = false;	
	}
	if(actualCart && actualCart !== null){
		checkPopupStatusForStateChange(actualCart);
	}
}

// handle Timers and waited/timer status
function set_waited(time){

	if (time==8){
		if (mouse_over){
			waited_8sec_over = true;
			waited_8sec = true;
		}
		else{
			waited_8sec = true;
		}
		
		started_wait_8sec = false;
	}
	else{
		if (time==3){
			started_wait_3sec = false;
			waited_3sec = true;
		}
	}
		
	clearTimeout( timer_8sec );
	clearTimeout( timer_3sec );
	
	// change the Popup Display?
	if(actualCart && actualCart !== null){
		checkPopupStatusForStateChange(actualCart);
		clearTimeout( timer_8sec );
		clearTimeout( timer_3sec );
	}
}

// change Position of Popup
function cartPopupPos(){
	if (document.getElementById('cart_popup')){
		var popup = document.getElementById('cart_popup');
	
		if (popup){
			popup.style.left = global_mouseX + 'px';
			popup.style.top  = global_mouseY + 'px';
		}	
	}
}

// Initiate Positioning by attaching event handler on Click
function initPopupPos(){
	addEvent(document,"click",function(e){
		var tempX,tempY=0;
		
		// deprecated we don't need fixed values anymore
		var clientX = e.clientX ? e.clientX : 868;
		var clientY = e.clientY ? e.clientY : 450;
		
		// get click-position depending on Browser
		if(e)   {
			tempX=e.pageX ? e.pageX : clientX; 
			tempY=e.pageY ? e.pageY : clientY;
		}
		 else if(event) {
			tempX=event.clientX; tempY=event.clientY;
		}
		// Offset Popup-position by popup dimension
		global_mouseX = (tempX - 125);
		global_mouseY = (tempY - 140);
		
		// IE fix for wrong positioning // its not posible to get pageXY from IE so I do position this element as fixed with clientXY otherwise it appears on upper position on a  scrolled page
		GLOB_POS = (!e.pageY)?'fixed':'absolute';
		
		// after all Globals were set allow to change Position	
		if (document.getElementById('cart_popup')){
			cartPopupPos();
		}
	});
}
 

/*
How the Popup should behave

keep popup for 8 sec. least
keep popup displayed while mouse_over
keep popup displayed 3sec after mouse_out
close popup after waited 8 sec && mouse_out
close popup after waited 3 sec && mouse_out after waited 8sec && mouse_over
close popup on pressed popup button
close popup on mouse_out && click
*/

// Show the Cart-Popup
function displayPopup(cart,cartstatus,count){

	initGlobals();
	actualCart = cart;
	
	clicked=true;
	
	// change Popup Content on status
	refreshCartMsg(cart,cartstatus,count);
	
	// show popup and change Positioning Method on Browsertype
	if (document.getElementById('cart_popup')){
		cartPopupPos();
		document.getElementById('cart_popup').style.visibility = 'visible';
		document.getElementById('cart_popup').style.position = GLOB_POS;
	}
	
	// register Event-Handler  -- standard.js
	// Check direktion in whitch coursor goes over areas - IN or OUT to set MOUSE_OVER
	var popup = document.getElementById('cart_popup');
	addEvent(document,"click",watchClick);
	addEvent(popup,"mouseover",watchMouseOver);
	addEvent(popup,"mouseout",watchMouseOut);

	//start 8sec Timeout
	clearTimeout( timer_3sec );
	clearTimeout( timer_8sec );
	started_wait_8sec = true;

	timer_8sec = window.setTimeout("set_waited(8)",8000);
}

// A callback function when article is successfully added
function refreshCartContent(cart, articleId, oldCart) {
		
		var diffValue = null;

		// Get singleArticleValue from cart
        var singleArticleValue = null;
		var i;
        if (cart && cart.items) {
            for (i = 0; i < cart.items.length; i++) {
                if (cart.items[i] && (cart.items[i].articleShopId == articleId) && cart.items[i].count) {
                    singleArticleValue = cart.items[i].count;
                }
                if (!cart.items[i] || !cart.items[i].articleShopId || !cart.items[i].count) {
                    singleArticleValue = null;
                }
            }
        }
		
		// Get singleArticleValue from OLD cart
        var oldArticleValue = null;
        if (oldCart && oldCart.items) {
            for (i = 0; i < oldCart.items.length; i++) {
                if (oldCart.items[i] && (oldCart.items[i].articleShopId == articleId) && oldCart.items[i].count) {
                    oldArticleValue = oldCart.items[i].count;
                }
                if (!oldCart.items[i] || !oldCart.items[i].articleShopId || !oldCart.items[i].count) {
                    oldArticleValue = null;
                }
            }
        }
		
		// get Difference NEW - OLD
		if (singleArticleValue){
			//negative Value -> reduce amount (warning) 
			diffValue = (oldArticleValue)?(singleArticleValue - oldArticleValue):singleArticleValue;
		}

        // Check if Cart contains the submitted value
        var countElement = 'count_' + articleId;
        var ele = document.getElementById(countElement);
		var order_status=null;
		
        if (ele && !notvalid) {

			//default
			document.getElementById('cartimg_' + articleId).src = '/images/einkauf.gif';

			// success
			if (singleArticleValue && ((Math.round(ele.value) == singleArticleValue) || (ele.value == ''))){
			   order_status='success';
			}
			// warning only addeded some OR reduced Value
			if((Math.round(ele.value) != singleArticleValue) && (Math.round(ele.value) > singleArticleValue) && (Math.round(ele.value) > 0)){
			   diffValue=singleArticleValue;
			   order_status='warning_stock';
			}   
			// if reduced value - change diff to actual value (for loc_resource display)
			if (diffValue<0) {
				diffValue=singleArticleValue;
				order_status='warning';
			}
			// error
			if((!singleArticleValue) && (Math.round(ele.value) !== 0)){
			   order_status='error';
			}
			//deleted   
			if(singleArticleValue === null && (oldArticleValue > 0) ){
			order_status='deleted';
			}
        }
		
		//Case if insert crappy things on empty field
		else{
			// nothing in cart - crap
			if (ele && notvalid && singleArticleValue && oldArticleValue === null){
				order_status='success';
			}
			// 1 in Cart - crap
			if(notvalid && singleArticleValue && oldArticleValue){
				order_status='success';
			}
			// more than 1 in Cart - crap
			if(notvalid && singleArticleValue == 1 && oldArticleValue > 1){
				order_status='success';
			}
		}
				
		//change Cart Symbol
		var imgUrl = "/images/einkauf.gif",
			imgTitle = "";
		// channge Tooltip-Text and Status-Image	
		if (order_status){
			switch (order_status){
				case 'success': 
					imgUrl = '/images/a-c/cart_success.gif';
					imgTitle = loctext["checkout.popup.headline.addedToCart"];
					break;
				case 'warning': 
					imgUrl = '/images/a-c/cart_warning.gif';
					imgTitle = loctext["checkout.popup.headline.reducedValue"];
					break;
				case 'warning_stock': 
					imgUrl = '/images/a-c/cart_warning_stock.gif';
					imgTitle = loctext["checkout.popup.headline.warning"];
					if (ele) {
						ele.value = singleArticleValue;
					} 
					break;
				case 'error'  :	
					imgUrl = '/images/a-c/cart_error.gif';
					imgTitle = loctext["checkout.popup.headline.error"];
					break;
				case 'deleted': 
					imgUrl = '/images/einkauf.gif';
					imgTitle = loctext["checkout.popup.headline.deletedFromCart"];
					break;
			}
		}else{
			if(clicked && document.getElementById('cartimg_' + articleId)){
				imgUrl = '/images/einkauf.gif';
			}
		}
		
		// replace parameters in Locresources
		if(document.getElementById('cartimg_' + articleId)){
			var cartImg = document.getElementById('cartimg_' + articleId);
			cartImg.src = imgUrl;
			cartImg.title = imgTitle.replace("{0}", diffValue);
		}
		
		// Update cart summary information
		if (document.getElementById('customerCartCount')){
			var customerCartCount = document.getElementById('customerCartCount');
			customerCartCount.innerHTML = cart.count;
		}
		if (document.getElementById('customerCartValue')){
			var customerCartValue = document.getElementById('customerCartValue'); 
			customerCartValue.innerHTML = addSpaces(cart.formattedValue);
		}
		if (document.getElementById('customerCartShipping')){
			var customerCartShipping = document.getElementById('customerCartShipping');
			customerCartShipping.innerHTML = addSpaces(cart.formattedShipping);
		}

        // Set Input Value to added ProductCount
        displayAddedValue(articleId);

		// move this to function in standard.js
		// check IE version if not IE use 10
		var ie_v=10;
		if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)){ //test for MSIE x.x;
			var ieversion=new Number(RegExp.$1); // capture x.x portion and store as a number
			if (ieversion>=8){
				ie_v=8;
			}
			else if (ieversion>=7){
				ie_v=7;
			}
			else if (ieversion>=6){
				ie_v=6;
			}
			else if (ieversion>=5){
				ie_v=5;
			}
		}
		
		// decide if popup should be displayed
		if ( order_status && ie_v>6 && ((diffValue && (diffValue !== 0)|| order_status == 'deleted' )) ) {
			displayPopup(cart,order_status,diffValue);
		}		
}

// The function which is called when the page is reloaded for the first time
// to initialize the shopping cart.
function reloadCart() {
		log("reload Cart");
	    // Get the cart content - asynchronously
	    AsyncCart.getContent({
			callback:function(cart) {
				refreshCartContent(cart, '','');
				refreshArticlesCount(cart.items);
			},
			timeout:15000
		 });					
}

// To add article to the shopping cart asynchronously
function addArticleToCart(articleId, groupId, location, configurable) {
  if (!clicked) {
        animateCart(articleId);
		clicked = true;
		
		// Check input value
		var evalCount = getNumberArticle(articleId);

		//Synchroneous Call for cart - to get possible old Article-Value to calculate difference
		var oldCart = null;
	
		if (isFinite(evalCount)){
			DWREngine.setAsync(false);
			AsyncCart.getContent({
	                        callback:function(cart) {
								oldCart = cart;
	                        }
	                     });
			DWREngine.setAsync(true);
		}
	
        // Be carefull, a sync communication - when server is done with the
        // request - refreshCartContent is called.
		AsyncCart.add(articleId, evalCount, groupId,location,configurable,
				{	
					callback:function(cart) {
						refreshCartContent(cart, articleId, oldCart);
					}
				});
    }
	else{
		clicked=false;
	}
    return false;
}