var debug = false;
var sessionController = null;
var accountController = null;
var basketController  = null;


var storeId   =  null;
var catalogId =  null;
var categoryId = null;
var langId    =  null;


var QS_Utils;
function  QS_Utils(){
  return{
	getUrlParam:function(name){
		name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); 
		var regexS = "[\\?&]"+name+"=([^&#]*)"; 
		var regex = new RegExp( regexS ); 
		var results = regex.exec( window.location.href ); 
		if( results == null ){
			if(name == 'storeId'){
				return sessvars.tvbook_storeId;
			}
			else if(name == 'catalogId'){
				return sessvars.tvbook_catalogId;
			}
			else if(name == 'langId'){
				return sessvars.tvbook_langId;
			}
			else{
				return ""; 
			}	
		}
		else {
			var param = results[1];
			if(param)
			{
				if(name == 'storeId'){
				 if(sessvars.tvbook_storeId != param){
					 sessvars.tvbook_storeId = param;
				 }
				}
				else if(name == 'catalogId'){
				 if(! sessvars.tvbook_catalogId != param){
					 sessvars.tvbook_catalogId = param;
				 }
				}
				else if(name == 'langId'){
				 if(! sessvars.tvbook_langId != param ){
					 sessvars.tvbook_langId = param;
				 }
				}
			}
		    return param;
	    }
		
	},
	
	getCookie:function (name){		
	  var pattern ="(?:; )?" + name + "=([^;]*);?";
	  var regex = new RegExp(pattern);
	  
	  if( regex.test(document.cookie) ){
	    return decodeURIComponent(RegExp["$1"]);
	  }
	  else{
	   return null;
	  }
	  
	},
	
	deleteCookie:function (name, path, domain) {	
	    if (QS_Utils.getCookie(name)) {
	        document.cookie = name + "=" + 
	            ((path) ? "; path=" + path : "") +
	            ((domain) ? "; domain=" + domain : "") +
	            "; expires=Thu, 01-Jan-70 00:00:01 GMT";
	   }
	},
	

	
	callNull:function(){	
	},
	
	createPageLink:function(linkName , linkTarget,linkClass , linkContainerId){ 
	 $("#"+linkContainerId).append("<li class='"+linkClass+"'><a href='#"+linkTarget+"'>"+linkName+"</a></li>");
	},

	fadeTransition:function(fadeOutSelector, fadeInSelector, speed){
	    $(fadeOutSelector).fadeOut(speed,function(){
	    	$(fadeInSelector).fadeIn(speed)
	    });   
	},
	
	encodeHtml:function( s ) {
	    so = new String(s);
	    so =  so.replace("\"", ""); 
	    so =  so.replace("\'", ""); 
		return  so.valueOf();
	 }, 
	 
	 validateEmailAddress:function(emailAddress){
	  var filter=/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9])+$/;
	  if (emailAddress==null || emailAddress=="" || !filter.test(emailAddress)) return false;
	  return true;
    },
	
	validateCardExpiryDate:function( expiryMonth, expiryYear ){
		var date = new Date();
		var year = date.getFullYear();
		var month = date.getMonth();
		month++;
	
		var monthsSinceADZero = year * 12 + month;
		var expiryMonthsSinceADZero = (expiryYear +2000) * 12 + expiryMonth;
		
		if((monthsSinceADZero <= expiryMonthsSinceADZero)  && (expiryMonth < 13) && (expiryMonth > 0)) {
		    return true;
		} else {    
		    return false;
		}
	},
	
	validateCardStartDate:function( startMonth, startYear ){
			var date = new Date();
			var year = date.getFullYear();
			var month = date.getMonth();
			month++;
		
			var monthsSinceADZero = year * 12 + month;
			var startMonthsSinceADZero = (startYear +2000) * 12 + startMonth;
			
			if( (startMonthsSinceADZero <= monthsSinceADZero) && (startMonth < 13) && (startMonth > 0)){
			    return true;
			} else {    
			    return false;
			}
	},
	
	hideDefaultErrors:function(){
	  $("#QS_defaultErrorSection").hide();
	},
	openCertDetails:function(refferer){
	  window.open('https://www.thawte.com/core/process?process=public-site-seal-cert-details&public-site-seal-cert-details.referer='+ refferer, 'anew',config='height=500,width=516,toolbar=no,menubar=no,scrollbars=yes,resizable=no,location=no,directories=no,status=yes');
	},
	
	hideValidationErrors:function(){
		$(".errorSection").hide();
		$(".errorSection ul").empty();
		$("*").removeClass("errorHighlight");
	}
  }
}

$(function(){
 QS_Utils = new QS_Utils();
});




var QS_Constants;
function  QS_Constants(){
  var POSTCODE_REGEX = /^[a-zA-Z][a-zA-Z0-9]{1,3}\s?\d[a-zA-Z]{2}$/;
  return{
	initCustomValidationRules:function(){
		 jQuery.validator.addMethod("ukPostCode", function(value, element) {	
		  if(value){
			 value = new String($.trim(value)).toUpperCase();
			 element.value=value;
		  }
		  return this.optional(element) ||  POSTCODE_REGEX.test(value); 
	      }, "Please enter a valid UK Postcode");	
	},
	validation_rules: function(form){
		
		if(!form){
			alert("DEV NOTE: Please set a form id against validation rules for this form");
			return;
		}
		
		return {
			personTitle: {
				required: true
			},
			firstName: {
				required: true,
				maxlength: 30
			},
			lastName: {
				required: true,
				maxlength: 30
			},
			phone1: {
				required: true,
				maxlength: 20
			},
			phone2: {
				maxlength: 20
			},
			address1: {
				required: true,
				maxlength: 30
			},
			address2: {
				maxlength: 30
			},
			address3: {
				maxlength: 30
			},
			zipCode: {
				required: function(element){
					return $(form + " select[name='country']").val() == "GB";
				},
				ukPostCode: true
			},
			postcode: {
				required: function(element){
					return $(form + " select[name='country']").val() == "GB";
				},
				ukPostCode: true
			},
			city: {
				required: true,
				maxlength: 30
			},
			state: {
				required: true,
				maxlength: 30
			},
			country: {
				required: true
			},
			email1: {
				email: true,
				required: true,
				minlength: 4
			},
			emailVerify: {
				email: true,
				required: true,
				minlength: 4,
				equalTo: form + " input[name='email1']"
			},
			maginusAccountNumber: {
				required: true
			},
			shipModeId: {
				required: true
			},
			policyId: {
				required: true
			},
			cardNumber: {
				required: true,
				maxlength: 20,
				creditcard: true,
				digits: true
			},
			cardHolderName: {
				required: true,
				maxlength: 100
			},
			cardExpiryMonth: {
				required: true,
				digits: true,
				maxlength: 2,
				minlength: 2
			},
			cardExpiryYear: {
				required: true,
				digits: true,
				maxlength: 2,
				minlength: 2
			},
			cardStartMonth: {
				digits: true,
				maxlength: 2,
				minlength: 2
			},
			cardStartYear: {
				digits: true,
				maxlength: 2,
				minlength: 2
			},
			cardIssue: {
				digits: true,
				maxlength: 2
			},
			verificationNumber: {
				required: true,
				maxlength: 3,
				minlength: 3,
				digits: true
			},
			subscribeEmail: {
				required: true,
				email: true
			},
			subscribeEmailAddress: {
				required: true,
				email: true,
				maxlength: 100
			},
			subscribeTitle: {
				required: true
			},
			subscribeFirstName: {
				required: true
			},
			subscribeLastName: {
				required: true
			},
			logonId: {
				required: true,
				maxlength: 100
			},
			logonPassword: {
				required: true,
				minlength: 6
			
			},
			logonPasswordVerify: {
				required: true,
				minlength: 6,
				equalTo: form + " input[name='logonPassword']"
			},
			terms: {
				required: true
			},
			sender_name: {
				required: true,
				minlength: 2
			},
			sender: {
				email: true,
				required: true,
				minlength: 4
			},
			recipient_name: {
				required: true,
				minlength: 2
			},
			recipient: {
				email: true,
				required: true,
				minlength: 4
			},
			message: {
				required: false,
				maxlength: 1000
			},
			fromname: {
				required: true,
				maxlength: 100
			},
			toname: {
				required: true,
				maxlength: 100
			},
			fromemail: {
				required: true,
				email: true,
				maxlength: 100
			},
			toemail: {
				required: true,
				email: true,
				maxlength: 100
			},
			emailMessage: {
				required: true,
				maxlength: 1000
			},
			rating: {
				required: true
			},
			foreName: {
				required: true,
				maxlength: 100
			},
			forename: {
				required: true,
				maxlength: 100
			},
			emailAddress: {
				required: true,
				email: true,
				maxlength: 100
			},
			reviewTitle: {
				required: true,
				maxlength: 100
			},
			reviewText: {
				required: true,
				maxlength: 1000
			},
			QS_contactFormOption: {
				required: true
			},
			surname: {
				required: true,
				maxlength: 30
			},
			tel: {
				maxlength: 20
			},
			fromEmail: {
				required: true,
				email: true,
				maxlength: 100
			}
		 }
	   },
		validation_messages: {
			personTitle:{
			   required:"Please select your title."
		     },
		    firstName:{
		    	 required:"Your first name is required.",
		    	 maxlength:"Forename must not exceed 30 characters in length."
		     },
		     lastName:{
		    	 required:"Your surname is required.",
		    	 maxlength:"Surname must not exceed 30 characters in length."
		     },
		     phone1:{
		    	 required:"Please enter your phone number."	,
		    	 maxlength:"Your phone number cannot exceed 20 characters."
		     },
		     phone2:{
		    	 maxlength:"Your phone number cannot exceed 20 characters."		    	 
		     },
		     address1:{
		    	 required:"Please enter the first line of your address.",
		    	 maxlength:"Your address cannot contain more then 30 characters"
		     },
		     address2:{
		    	 maxlength:"The second line of your address cannot contain more then 30 characters"
		     },
		     address3:{
		    	 maxlength:"The third line of your address cannot contain more then 30 characters"
		     },
		     zipCode:{
				   required:"Please enter a UK Postcode.",
				   ukPostCode:"UK Postcode has invalid format"					  
			 },
			 postcode:{
				   required:"Please enter a UK Postcode.",
				   ukPostCode:"UK Postcode has invalid format"					  
			 },
		     city:{
		    	 required:"Please enter a valid city or town.",
				 maxlength:"Your city/town cannot exceed 30 characters."
		     },
		     state:{
		    	 required:"Please enter a state/county/province.",
				 maxlength:"Your state/county/province cannot exceed 30 characters."
		     },
		     country:{
		    	 required:"Please select a country."
		     }, 
			 email1:{
			   email:"Invalid email address",
		       minlength:"email must be 4 characters or more."
		      
		     },
	         emailVerify: {
	            email:"Invalid email address",
		        minlength:"Re-typed email must be 4 characters or more.",
		        equalTo: "emails entered do not match"
		    },	
			maginusAccountNumber:{			    	 
			   required:"Your customer number is required.",
			   minlength:"Invalid customer number",
			   maxlength:"Invalid customer number",
			   digits:"Invalid customer number"
			},
			shipModeId:{			    	 
			   required:"A shipping option must be selected."
			},
			policyId:{
			   required:"Please select a card type."
		     },
		    cardNumber:{			    	 
		    	 maxlength:"Your card number cannot exceed 20 numbers in length.",
		    	 creditcard:"You did not enter a valid credit card number.  Please verify and try again.",
		    	 digits:"The card number you entered must contain numbers only"
		     },
		     cardHolderName:{
		    	 required:"Please enter your name as it appears on your card",
		    	 maxlength:"Your name must not exceed 100 characters in length."
		     },
		     cardExpiryMonth:{
		    	 required:"Card expiry month id required",
		    	 digits:"Please enter a 2 digit number for the expiry month, i.e. for January enter 01.",
		    	 maxlength:"Please enter a 2 digit number for the expiry month, i.e. for January enter 01.",
		    	 minlength:"Please enter a 2 digit number for the expiry month, i.e. for January enter 01."
		     },
		     cardExpiryYear:{
		    	 required:"Card expiry year is required",
		    	 digits:"Please enter a 2 digit number for the expiry year.",
		    	 maxlength:"Please enter a 2 digit number for the expiry year.",
		    	 minlength:"Please enter a 2 digit number for the expiry year."
		     },
		     cardStartMonth:{
		    	 digits:"Please enter digits only for the start month, i.e. for January enter 01.",
		    	 maxlength:"Please enter a 2 digit number for the start month, i.e. for January enter 01.",
		    	 minlength:"Please enter a 2 digit number for the start month, i.e. for January enter 01."
		     },
		     cardStartYear:{
		    	 digits:"Please enter digits only for the start year.",
		    	 maxlength:"Please enter a 2 digit number for the start year.",
		    	 minlength:"Please enter a 2 digit number for the start year."
		     },
		     cardIssue:{			    	 
		    	 digits:"Please enter numbers only for the issue number.",
		    	 maxlength:"Issue number cannot exceed 2 digits."
		     },
		     verificationNumber:{
		    	 required:"Please enter the last 3 digits of the number on the back of your card",
		    	 maxlength:"Please only enter the last 3 digits",
		    	 minlength:"Please only enter the last 3 digits",
		    	 digits:"Please enter numbers only for the verification number."
		     },
			subscribeEmail:{
		       required:"Please supply a valid email address.",
		       email: "Please supply a valid email address."
		     },
			 subscribeEmailAddress: {
			 	required:'Email address is required', 
			    email:'Invalid email address' 
			 },
		     subscribeTitle:{
		        required:"Please select a title."
		     },
		     subscribeFirstName:{
		    	required:"Please enter your first name."
		     },
		     subscribeLastName:{
		    	required:"Please enter your last name."
		     },
			logonId:{
				required:"Your email address is required.",
				email:"Your email does not seem to be in a valid format.",
				maxlength:"Your email cannot exceed 100 characters."
			},
			logonPassword:{
		       minlength:"Password must be 6 characters or more.",
		       equalTo: "Passwords entered do not match"
		     },
			logonPasswordVerify: {
		        minlength:"Re-typed password must be 6 characters or more.",
				equalTo:"Re-typed password must match password"
		    },
		    terms:{
				required:"Please read and accept our terms and conditions before completing your registration"
			},
			sender_name:{
			   minlength:"Your name must be at least 2 characters in length"
		    },
		    sender:{
			   email:"Your email address is not valid",
		       minlength:"Your email address must be 5 characters or more."
		    },
			recipient_name:{
			   minlength:"Friend's name must be at least 2 characters in length"
		    },
	        recipient: {
	            email:"Friend's email address is not valid",
		        minlength:"Friend's email address must be 5 characters or more."
		    },
		    message: {
		        maxlength:"Message must be 1000 characters or less."
		    },
			fromname:{
		    	 required:"Your name is required to send.",
		    	 maxlength:"Forename must not exceed 100 characters in length."
		     },
		     toname:{
		    	 required:"Your friend's name is required.",
		    	 maxlength:"Surname must not exceed 100 characters in length."
		     },
		     fromemail:{
		    	 required:"Please enter a valid email address.",
		    	 email:"The email you entered seems to have an error, please re-enter.",
		    	 maxlength:"The length of the email address cannot exceed 100 characters."
		     },
		     toemail:{
		    	 required:"Please enter a valid email address.",
		    	 email:"Your friend's email seems to have an error, please re-enter.",
		    	 maxlength:"The length of the email address cannot exceed 100 characters."
		     },
		     emailMessage:{
		    	 required:"Please supply a message to send to your friend.",
		    	 maxlength:"Message cannot contain more then 1000 characters."
		     },
			 rating:{
		    	 required:"Please choose a rating from 1 to 5 stars."	    	
		     },
		     foreName:{
		    	 required:"Your name is required for this review.",
		    	 maxlength:"Your name not exceed 100 characters in length."
		     },
			 forename:{
		    	 required:"Your name is required for this review.",
		    	 maxlength:"Your name not exceed 100 characters in length."
		     },
		     emailAddress:{
		    	 required:"Please enter a valid email address.",
		    	 email:"The email you entered seems to have an error, please re-enter.",
		    	maxlength:"The length of the email address cannot exceed 100 characters."
		     },
		     reviewTitle:{
		    	 required:"Please give a title to your review.",
		    	 maxlength:"Your title cannot exceed 100 characters."
		     },
		     reviewText:{
		    	 required:"Please supply comments to your review.",
		    	 maxlength:"Your review cannot contain more then 1000 characters."
		     },
			 QS_contactFormOption:{
			   required:"Please select a reason for your enquiry."
		     },
		     surname:{
		    	 required:"Your surname is required.",
		    	 maxlength:"Surname must not exceed 30 characters in length."
		     },
		     tel:{			    	 
		    	 maxlength:"Telephone must not exceed 20 characters in length."
		     },
		     fromEmail:{
		    	 required:"Please enter a valid email address.",
		    	 email:"The email you entered does not seem to have a valid format.  Please check and try again.",
		    	 maxlength:"The length of the email address cannot exceed 100 characters."
		     }
			
	    },
		
		postcodeRegex:function(){
			return POSTCODE_REGEX;
		}
  }
}
$(function(){
 QS_Constants = new QS_Constants();
 QS_Constants.initCustomValidationRules();
});










function  QS_SessionController(){

  return{

    init: function(debug){
		
	  storeId   =  QS_Utils.getUrlParam("storeId");
	  catalogId =  QS_Utils.getUrlParam("catalogId");
	  categoryId = QS_Utils.getUrlParam("categoryId");
	  langId    =  QS_Utils.getUrlParam("langId");
	  
	  $.ajaxSetup({
	    type:'POST',
	    timeout:60000,
	    dataType:'json',
	    beforeSend:function(){
		  $.blockUI({ 
			  css: { 
	            border: 'none', 
	            padding: '15px', 
	            backgroundColor: '', 
	            '-webkit-border-radius': '10px', 
	            '-moz-border-radius': '10px', 
	            opacity: '.7' 
	            
	        },
	        overlayCSS:  {  
	            backgroundColor:'',  
	            opacity:        '0.2'  
	        }, 
	        message:'<img src="/siteimages/TVBOOK/common/ajaxBusy.gif"/>'
		  }); 
	    },
	    complete:function(data,status){
	    	 $.unblockUI();
	    },
	    error: function( xmlHttpObj ,status){
	   
	    	$("#QS_errorOverlayTitle").html("System Error");
	    	 $("#QS_errorOverlayMessage").html("There has been an unexpected problem. <br/><br/>  Ajax status: " + status + "<br/>  Http status: " + xmlHttpObj.status );
	    	var errorOverlay = $("#QS_errorOverlay").overlay();      
	    	errorOverlay.load();   	
	    }
	  });

      accountController = new QS_AccountController();
      accountController.init();

      basketController  = new QS_BasketController(); 
      basketController.init();
  
      if(debug){
        sessvars.$.debug()
      }
    }, 
    
 
    
    deleteProduct:function(orderItemId, successCallback , errorCallback){
      basketController.deleteProduct(orderItemId, successCallback , errorCallback);
    },
    
    updateProduct:function( orderItemId, quantity, successCallback , errorCallback){
      basketController.updateProduct(orderItemId, quantity, successCallback , errorCallback);
    },
    
    moveToWishList:function(catEntryId, orderItemId, successCallback , errorCallback ){
      basketController.moveToWishList(catEntryId, orderItemId, successCallback , errorCallback);
    },
 
    logIn:function(){
      accountController.purge();
      basketController.purge();
      sessvars.$.flush(); 
    },
    
    logOut:function(){
      accountController.purge();
      basketController.purge();
      sessvars.$.clearMem(); 
      sessvars.$.flush(); 
    },
    
    register:function(){
      accountController.purge();
      sessvars.$.flush(); 
    },
    
    showErrorOverlay:function(errorMessage, errorTitle){
    	
    	if(! errorTitle){
    		errorTitle = "Sorry, there is a problem.";
    	}
    	
    	$("#QS_errorOverlayMessage").html( QS_Utils.encodeHtml(errorMessage) );
    	$("#QS_errorOverlayTitle").html(errorTitle);
    	var errorOverlay = $("#QS_errorOverlay").overlay();      
    	errorOverlay.load();   
    },
    
    setPageVisit:function(context, name, cssClass, url){
    	var contextName = 'tvbook_visit_'+context;
         sessvars[contextName] = {name:name, cssClass:cssClass, url:url};
    },
    
    getPageVisit:function(context){
    	var contextName = 'tvbook_visit_'+context;
    	return sessvars[contextName];
    },
	setSelectedTopCategory:function(categoryIdentifier){
   
         sessvars['tvbook_selectedTopCategory'] = categoryIdentifier;
    },
    getSelectedTopCategory:function(){
    	return sessvars['tvbook_selectedTopCategory'];
    }
    

  }
}

     
$(function(){
 
  	sessionController = new QS_SessionController();
    sessionController.init(debug);
  
});

$(window).load(function(){
	  
	  $("#QS_errorOverlay").overlay({
			close: 'button.QS_closeOverlay'  
	  }); 
	
});




var MAX_BASKET_LINE_QUANTITY = 20;


function  QS_BasketController(){

  return{

    init: function(){
     var bypassSync = ($(".QS_bypassSync").size() > 0);
     if(!bypassSync){
	 	
      if(sessvars.tvbook_order == null){
         $.ajax({
           url:'qs_jsonOrderBeans',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'orderId':'.',
            'errorViewName':'qs_jsonStatusError'
           },
           success:function(data){
             if(data.status == 'success'){    
               basketController.setOrder(data.order);
               basketController.refreshMiniBasket();
			   basketController.refreshBookPoints();
               basketController.initSpecialShippingRules();
             }
             else{
              sessionController.showErrorOverlay(data.errorMessages);
              
             }
           }
         });    
      }
      else{
        this.refreshMiniBasket();
		basketController.refreshBookPoints();
        this.initSpecialShippingRules();
      }
	  
	 }
    }, 

    refreshMiniBasket:function(){
      
	  if(this.getOrder()){
       $('.QS_basketQty').html(this.getOrder().basketQty);
       $('.QS_basketTotal').html("&pound;"+ new Number(this.getOrder().basketTotal).toFixed(2));
	  }
    },
	
	refreshBookPoints:function(){
	   if(this.getOrder().bookPoints){
	    $('.QS_bookPointsTotal').html(this.getOrder().bookPoints.currentBalance);
	   }
	},
    
    initSpecialShippingRules:function(){
	  if ( (new Number(this.getOrder().basketQty).valueOf() == 1) ) {
	   	 $('.QS_singleShipping').show();
	   	 $('.QS_stdShipping').hide();
	   	 $('.QS_stdShipping :radio').removeAttr('checked');
	  } else {
		 $('.QS_stdShipping').show();
	   	 $('.QS_singleShipping').hide();
	   	 $('.QS_singleShipping :radio').removeAttr('checked');
	  }
    },
    
    purge:function(){
     sessvars.tvbook_order = null;
     sessvars.$.flush();
    },
    
    getOrder:function(){
      return sessvars.tvbook_order;
    },
    
    setOrder:function(order){
      sessvars.tvbook_order = order;
      sessvars.$.flush();
    },
    
    getPendingOrders:function(){
      return sessvars.tvbook_pendingOrders;
    },
    
    setPendingOrders:function(pendingOrders){
      sessvars.tvbook_pendingOrders = pendingOrders;
      sessvars.$.flush();
    },
    
      getOrderItemInfoForProductById:function(catEntryId){
      var order = this.getOrder();
      if(order != null && order != undefined && order.cashOrderItems != null && order.cashOrderItems != undefined){
        
        if( order.cashOrderItems.length > 0){
         for (var i = 0, item; item = order.cashOrderItems[i]; i++) {
            
      
            if(item.objectStatus == "valid" && item.itemId == catEntryId){
              var info = new Object();
              info.orderItemId = item.orderItemId;
			  info.itemId = item.itemId;
			  info.partNumber = item.partNumber;
              info.qty = item.qty;
              return info;
            }
          }
        }
      }
      
      return null;
    },
	
	
	getOrderItemInfoForProductByCode:function(productCode){
      var order = this.getOrder();
      if(order != null && order != undefined && order.cashOrderItems != null && order.cashOrderItems != undefined){
        
        if( order.cashOrderItems.length > 0){
         for (var i = 0, item; item = order.cashOrderItems[i]; i++) {
            
     
            if(item.objectStatus == "valid" && item.partNumber == productCode){
              var info = new Object();
              info.orderItemId = item.orderItemId;
			  info.itemId = item.itemId;
			  info.partNumber = item.partNumber;
              info.qty = item.qty;
              return info;
            }
          }
        }
      }
      
      return null;
    },
	
	getOrderItemInfoForProductByOrderItemId:function(orderItemId){
      var order = this.getOrder();
      if(order != null && order != undefined && order.cashOrderItems != null && order.cashOrderItems != undefined){
        
        if( order.cashOrderItems.length > 0){
         for (var i = 0, item; item = order.cashOrderItems[i]; i++) {
            
       
            if(item.objectStatus == "valid" && item.orderItemId == orderItemId){
              var info = new Object();
              info.orderItemId = item.orderItemId;
			  info.itemId = item.itemId;
			  info.partNumber = item.partNumber;
              info.qty = item.qty;
              return info;
            }
          }
        }
      }
      return null;
    },

	getRedeemedBPOrderItemInfoForProductById:function(itemId){

      var order = this.getOrder();
   
      if(order != null && order != undefined && order.redeemedBPOrderItems != null && order.redeemedBPOrderItems != undefined){
   
        if( order.redeemedBPOrderItems.length > 0){
         for (var i = 0, item; item = order.redeemedBPOrderItems[i]; i++) {
     
            if(item.objectStatus == "valid" && item.itemId == itemId){
              var info = new Object();
              info.orderItemId = item.orderItemId;
			  info.itemId = item.itemId;
			  info.partNumber = item.partNumber;
              info.qty = item.qty;
              return info;
            }
          }
        }
      }
      
      return null;
    },
    
    getRedeemedBPOrderItemInfoForProductByOrderItemId:function(orderItemId){

      var order = this.getOrder();
   
      if(order != null && order != undefined && order.redeemedBPOrderItems != null && order.redeemedBPOrderItems != undefined){
   
        if( order.redeemedBPOrderItems.length > 0){
       
          for (var i = 0, item; item = order.redeemedBPOrderItems[i]; i++) {
          
             if(item.objectStatus == "valid" ){
             
               if( item.orderItemId == orderItemId){
        
                 var info = new Object();
                 info.orderItemId = item.orderItemId;
			     info.itemId = item.itemId;
			     info.partNumber = item.partNumber;
                 info.qty = item.qty;
                 return info;
               }
            }
           
          }
        }
      }
      
      return null;
    },
    
   
    addProduct:function( catEntryId, quantity, successCallback , errorCallback){
      
      var orderItemInfo = this.getOrderItemInfoForProductById(catEntryId);
      if(orderItemInfo != null ){
        var  orderItemId = orderItemInfo.orderItemId;
        var newQuantity = (new Number(quantity) + new Number(orderItemInfo.qty));
        this.updateProduct( orderItemId, newQuantity, successCallback , errorCallback, catEntryId);
       return;  
      }
      
      
      if(quantity > MAX_BASKET_LINE_QUANTITY ){
    	  if(confirm('There is a limit of '+MAX_BASKET_LINE_QUANTITY +' of this product available to purchase at one time. Would you like to add '+MAX_BASKET_LINE_QUANTITY+' to your basket?')){ 
    		quantity = MAX_BASKET_LINE_QUANTITY;  
    	  }
    	  else{
    		  return;
    	  }
    	  
      }
  
      $.ajax({
           url:'OrderItemUpdate',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'orderId':'.',
            'catEntryId':catEntryId,
            'quantity': quantity,
            'URL':'qs_jsonOrderBeans',
            'errorViewName':'qs_jsonStatusError'
           },
           success:function(data){
             if(data.status == 'success'){    
               basketController.setOrder(data.order);
               basketController.refreshMiniBasket();
			   basketController.refreshBookPoints();
               successCallback(data,catEntryId);
             }
             else{
              errorCallback(data.errorMessages);
             }
           }
         });    
    },
	
	
	addProductAndCalculate:function( catEntryId, quantity, successCallback , errorCallback){
    
      var orderItemInfo = this.getOrderItemInfoForProductById(catEntryId);
      if(orderItemInfo != null ){
        var  orderItemId = orderItemInfo.orderItemId;
        var newQuantity = (new Number(quantity) + new Number(orderItemInfo.qty));
        this.updateProduct( orderItemId, newQuantity, successCallback , errorCallback, catEntryId);
       return;  
      }
  
      if(quantity > MAX_BASKET_LINE_QUANTITY ){
    	  if(confirm('There is a limit of '+MAX_BASKET_LINE_QUANTITY +' of this product available to purchase at one time. Would you like to add '+MAX_BASKET_LINE_QUANTITY+' to your basket?')){ 
    		quantity = MAX_BASKET_LINE_QUANTITY;  
    	  }
    	  else{
    		  return;
    	  }
    	  
      }
  
      $.ajax({
           url:'OrderItemUpdate',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'orderId':'.',
            'catEntryId':catEntryId,
            'quantity': quantity,
			'updatePrices':'1',
            'calculationUsageId':'-1',
            'URL':'OrderCalculate?URL=qs_jsonOrderBeans',
            'errorViewName':'qs_jsonStatusError'
           },
           success:function(data){
             if(data.status == 'success'){    
               basketController.setOrder(data.order);
               basketController.refreshMiniBasket();
			   basketController.refreshBookPoints();
               successCallback(data,catEntryId);
             }
             else{
              errorCallback(data.errorMessages);
             }
           }
         });    
    },
   
   
    quickShop:function( productCode, quantity, orderId, successCallback , errorCallback){
     
      var orderItemInfo = this.getOrderItemInfoForProductByCode(productCode);
      if(orderItemInfo != null ){
        var  orderItemId = orderItemInfo.orderItemId;
        var  catEntryId = orderItemInfo.itemId;
        var newQuantity = (new Number(quantity) + new Number(orderItemInfo.qty));
        this.updateProduct( orderItemId, newQuantity, successCallback , errorCallback, catEntryId);
       return;  
      }
  
      if(quantity > MAX_BASKET_LINE_QUANTITY ){
    	  if(confirm('There is a limit of '+MAX_BASKET_LINE_QUANTITY +' of this product available to purchase at one time. Would you like to add '+MAX_BASKET_LINE_QUANTITY+' to your basket?')){ 
    		quantity = MAX_BASKET_LINE_QUANTITY;  
    	  }
    	  else{
    		  return;
    	  }
    	  
      }
  
      $.ajax({
           url:'QuickShop',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'orderId':orderId,
            'quantity': quantity,
            'field2':'QuickShop',
			'updatePrices':'1',
            'calculationUsageId':'-1',
            'productListId':'',
            'productCode':productCode,
            'URL':'OrderCalculate?URL=qs_jsonOrderBeans',
            'errorViewName':'qs_jsonStatusError'
           },
           success:function(data){
             if(data.status == 'success'){    
               basketController.setOrder(data.order);
               basketController.refreshMiniBasket();
			   basketController.refreshBookPoints();
               successCallback(data);
             }
             else{
              errorCallback(data.errorMessages);
             }
           }
         });    
    },
	
	redeemBookpoints: function(orderItemId, successCallback,errorCallback ){
		
		var item = this.getOrderItemInfoForProductByOrderItemId(orderItemId);
		var bpRedeemedItem = this.getRedeemedBPOrderItemInfoForProductById(item.itemId);
		var isRedemption = true;
	
		if(item.qty == 1 && bpRedeemedItem == null){
			this.bookPointsUpdate_single(orderItemId,isRedemption, successCallback,errorCallback);
		}
		else if(item.qty > 1 && bpRedeemedItem == null){
			this.bookPointsUpdate_split_new(item,isRedemption,successCallback,errorCallback);
		}
		else if(item.qty >= 1 && bpRedeemedItem != null){
			this.bookPointsUpdate_split_existing(item, bpRedeemedItem, isRedemption, successCallback, errorCallback);
		}
		
	},
	undoBookpoints: function(orderItemId, successCallback,errorCallback ){
		
		var bpRedeemedItem = this.getRedeemedBPOrderItemInfoForProductByOrderItemId(orderItemId);
     
		var item = this.getOrderItemInfoForProductById(bpRedeemedItem.itemId);
		var isRedemption = false;
		
		if(bpRedeemedItem.qty == 1 && item == null){
		  this.bookPointsUpdate_single(orderItemId,isRedemption, successCallback,errorCallback);
		}
		else if(bpRedeemedItem.qty > 1 && item == null){
			this.bookPointsUpdate_split_new( bpRedeemedItem,isRedemption, successCallback,errorCallback);
		}
		else if(bpRedeemedItem.qty >= 1 && item != null){
			this.bookPointsUpdate_split_existing(item, bpRedeemedItem, isRedemption, successCallback, errorCallback);
		}	
	},
	
	bookPointsUpdate_single: function(orderItemId,isRedemption, successCallback, errorCallback){
		
		var field1 = '0'
		if(isRedemption){
		  field1 = '1'
		}
		
		$.ajax({
             url:'OrderItemUpdate',
             data:{
              'storeId':storeId,
              'catalogId':catalogId,
              'langId':langId,
              'orderId':'.',
              'orderItemId':orderItemId,
			  'field1':field1,
              'quantity': '1',
              'updatePrices':'1',
              'calculationUsageId':'-1',
              'errorViewName':'qs_jsonStatusError',
              'URL':'qs_jsonOrderBeans'
             },
             success:function(data){
               if(data.status == 'success'){    
                 basketController.setOrder(data.order);
                 basketController.refreshMiniBasket();
				 basketController.refreshBookPoints();
                 successCallback(data);
               }
               else{
                errorCallback(data.errorMessages);
               }
             }
           }); 
	},
	
	bookPointsUpdate_split_new: function(item,isRedemption, successCallback, errorCallback){
	

		var field1_1 ='1';
		var field1_2 ='0';

	    if(isRedemption){
		   field1_1 ='0';
		   field1_2 ='1';
		}
		

		$.ajax({
             url:'OrderItemUpdate',
             data:{
              'storeId':storeId,
              'catalogId':catalogId,
              'langId':langId,
              'orderId':'.',
              'orderItemId_1':item.orderItemId,
			  'catEntryId_1':item.itemId,
			  'catEntryId_2':item.itemId,
              'quantity_1': (new Number(item.qty).valueOf() - 1),
			  'quantity_2': 1,
			  'field1_1':field1_1,
			  'field1_2':field1_2,
              'updatePrices':'1',
              'calculationUsageId':'-1',
              'errorViewName':'qs_jsonStatusError',
              'URL':'qs_jsonOrderBeans'
             },
             success:function(data){
               if(data.status == 'success'){    
                 basketController.setOrder(data.order);
                 basketController.refreshMiniBasket();
				 basketController.refreshBookPoints();
                 successCallback(data);
               }
               else{
                errorCallback(data.errorMessages);
               }
             }
           }); 
	},
	
	bookPointsUpdate_split_existing: function(item, bpRedeemedItem,isRedemption, successCallback, errorCallback){
		
	    var quantity_1 = new Number(item.qty).valueOf();
		var quantity_2 = new Number(bpRedeemedItem.qty).valueOf();
		
	    if(isRedemption){
		   quantity_1 = (quantity_1 - 1);
		   quantity_2 = (quantity_2 + 1);
		}
		else{
		   quantity_1 = (quantity_1 + 1);
		   quantity_2 = (quantity_2 - 1);
		}
		
		$.ajax({
             url:'OrderItemUpdate',
             data:{
              'storeId':storeId,
              'catalogId':catalogId,
              'langId':langId,
              'orderId':'.',
              'orderItemId_1':item.orderItemId,
			  'orderItemId_2':bpRedeemedItem.orderItemId,
              'quantity_1': quantity_1,
			  'quantity_2': quantity_2,
			  'field1_1':'0',
			  'field1_2':'1',
              'updatePrices':'1',
              'calculationUsageId':'-1',
              'errorViewName':'qs_jsonStatusError',
              'URL':'qs_jsonOrderBeans'
             },
             success:function(data){
               if(data.status == 'success'){    
                 basketController.setOrder(data.order);
                 basketController.refreshMiniBasket();
				 basketController.refreshBookPoints();
                 successCallback(data);
               }
               else{
                errorCallback(data.errorMessages);
               }
             }
           }); 
	},
	
     
     updateProduct:function( orderItemId, quantity, successCallback , errorCallback, catEntryId ){

         if(quantity > MAX_BASKET_LINE_QUANTITY ){
       	  if(confirm('There is a limit of '+MAX_BASKET_LINE_QUANTITY +' of this product available to purchase at one time. Would you like to change your basket quantity to '+ MAX_BASKET_LINE_QUANTITY +'?')){ 
       		quantity = MAX_BASKET_LINE_QUANTITY;  
       	  }
       	  else{
       		  return;
       	  }
         }

         $.ajax({
             url:'OrderItemUpdate',
             data:{
              'storeId':storeId,
              'catalogId':catalogId,
              'langId':langId,
              'orderId':'.',
              'orderItemId':orderItemId,
              'quantity': quantity,
              'updatePrices':'1',
              'calculationUsageId':'-1',
              'errorViewName':'qs_jsonStatusError',
              'URL':'qs_jsonOrderBeans'
             },
             success:function(data){
               if(data.status == 'success'){    
                 basketController.setOrder(data.order);
                 basketController.refreshMiniBasket();
				 basketController.refreshBookPoints();
                 successCallback(data,catEntryId);
               }
               else{
                errorCallback(data.errorMessages);
               }
             }
           });  
      },

    updateProductAndCalculate:function( orderItemId, quantity, successCallback , errorCallback,catEntryId){
 
       $.ajax({
           url:'OrderItemUpdate',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'orderId':'.',
            'orderItemId':orderItemId,
            'quantity': quantity,
            'updatePrices':'1',
            'calculationUsageId':'-1',
            'errorViewName':'qs_jsonStatusError',
            'URL':'OrderCalculate?URL=qs_jsonOrderBeans'
           },
           success:function(data){
             if(data.status == 'success'){    
               basketController.setOrder(data.order);
               basketController.refreshMiniBasket();
			   basketController.refreshBookPoints();
               successCallback(data,catEntryId);
             }
             else{
              errorCallback(data.errorMessages);
             }
           }
         });  
    },
	
	updateProductAndCalculateShipping:function( orderItemId, quantity, successCallback , errorCallback,catEntryId){
 
       $.ajax({
           url:'OrderItemUpdate',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'orderId':'.',
            'orderItemId':orderItemId,
            'quantity': quantity,
            'updatePrices':'1',
            'calculationUsageId':'-1',
			'calculationUsageId':'-2',
            'errorViewName':'qs_jsonStatusError',
            'URL':'OrderCalculate?URL=qs_jsonOrderBeans'
           },
           success:function(data){
             if(data.status == 'success'){    
               basketController.setOrder(data.order);
               basketController.refreshMiniBasket();
			   basketController.refreshBookPoints();
               successCallback(data,catEntryId);
             }
             else{
              errorCallback(data.errorMessages);
             }
           }
         });  
    },
    
    calculateOrder:function( successCallback , errorCallback){
    	 
        $.ajax({
            url:'OrderCalculate',
            data:{
             'storeId':storeId,
             'catalogId':catalogId,
             'langId':langId,
             'orderId':'.',
             'updatePrices':'1',
             'calculationUsageId':'-1',
             'errorViewName':'qs_jsonStatusError',
             'URL':'qs_jsonOrderBeans'
            },
            success:function(data){
              if(data.status == 'success'){    
                basketController.setOrder(data.order);
                basketController.refreshMiniBasket();
				basketController.refreshBookPoints();
                successCallback(data);
              }
              else{
               errorCallback(data.errorMessages);
              }
            }
          });  
     },
	 
	 calculateOrderAndShipping:function( successCallback , errorCallback){
    	 
        $.ajax({
            url:'OrderCalculate',
            data:{
             'storeId':storeId,
             'catalogId':catalogId,
             'langId':langId,
             'orderId':'.',
             'updatePrices':'1',
             'calculationUsageId':'-1',
			 'calculationUsageId':'-2',
             'errorViewName':'qs_jsonStatusError',
             'URL':'qs_jsonOrderBeans'
            },
            success:function(data){
              if(data.status == 'success'){    
                basketController.setOrder(data.order);
                basketController.refreshMiniBasket();
				basketController.refreshBookPoints();
                successCallback(data);
              }
              else{
               errorCallback(data.errorMessages);
              }
            }
          });  
     },
    
    
    
    deleteProductAndCalculate:function( orderItemId, successCallback , errorCallback ){
         $.ajax({
           url:'OrderItemDelete',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'orderId':'.',
            'orderItemId':orderItemId,
            'updatePrices':'1',
            'calculationUsageId':'-1',
            'errorViewName':'qs_jsonStatusError',
            'URL':'OrderCalculate?URL=qs_jsonOrderBeans'
            
           },
           success:function(data){
             if(data.status == 'success'){    
               basketController.setOrder(data.order);
               basketController.refreshMiniBasket();
			   basketController.refreshBookPoints();
               successCallback(data);
             }
             else{
              errorCallback(data.errorMessages);
             }
           }
         });    
    },
	
	 deleteProductAndCalculateShipping:function( orderItemId, successCallback , errorCallback ){
         $.ajax({
           url:'OrderItemDelete',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'orderId':'.',
            'orderItemId':orderItemId,
            'updatePrices':'1',
            'calculationUsageId':'-1',
			'calculationUsageId':'-2',
            'errorViewName':'qs_jsonStatusError',
            'URL':'OrderCalculate?URL=qs_jsonOrderBeans'
            
           },
           success:function(data){
             if(data.status == 'success'){    
               basketController.setOrder(data.order);
               basketController.refreshMiniBasket();
			   basketController.refreshBookPoints();
               successCallback(data);
             }
             else{
              errorCallback(data.errorMessages);
             }
           }
         });    
    },
	
	 updateOrderShippingAddress:function( orderId, addressId,successCallback , errorCallback){
    	 
        $.ajax({
            url:'OrderItemUpdate',
            data:{
             'storeId':storeId,
             'catalogId':catalogId,
             'langId':langId,
             'orderId':orderId,
			 'addressId':addressId,
			 'updatePrices':'1',
             'calculationUsageId':'-1',
             'errorViewName':'qs_jsonStatusError',
             'URL':'OrderCalculate?URL=qs_jsonOrderBeans'
            },
            success:function(data){
              if(data.status == 'success'){    
                successCallback(data);
              }
              else{
               errorCallback(data.errorMessages);
              }
            }
          });  
     },
    
    makePayment:function( orderId,
            policyId,
            cardBrand,
            cardNumber,
            cardHolderName,
            cardExpiryMonth,
            cardExpiryYear,
            verificationNumber,
            cardStartMonth,
            cardStartYear,
            cardIssue,
            notifyShopper,
            notifyOrderSubmitted,
            notify_OrderReceived_EMailSender_recipient,
            city,
            billtoAddressId,
            successCallback , 
            errorCallback ){
            
            
		var referrerId = QS_Utils.getCookie( 'Referrer');
		if(referrerId == null){
		var referrerId ='';
		}
		QS_Utils.deleteCookie('Referrer');                 
		            
		$.ajax({
			url:'OrderPrepare',
			data:{
			'storeId':storeId,
			'catalogId':catalogId,
			'langId':langId,
			'orderId':orderId,
			'policyId':policyId,
			'cardBrand':cardBrand,
			'cardNumber':cardNumber,
			'cardHolderName':cardHolderName,
			'cardExpiryMonth':cardExpiryMonth,
			'cardExpiryYear':cardExpiryYear,
			'cardStartMonth':cardStartMonth,
			'cardStartYear':cardStartYear,
			'cardIssue':cardIssue,
			'creditCardPolicyNumber':policyId,
			'city':city,
			'billtoAddressId':billtoAddressId,
			'referrerId':referrerId,
			'verificationNumber':verificationNumber,
			'notifyOrderSubmitted':notifyOrderSubmitted,
			'notify_OrderReceived_EMailSender_recipient':notify_OrderReceived_EMailSender_recipient,
			'notifyShopper':notifyShopper,
			'errorViewName':'qs_jsonStatusError',
			'URL':'OrderProcess?URL=qs_jsonStatusSuccess'
			
		},
		success:function(data){
		if(data.status == 'success'){  
		 basketController.purge(); 
		 successCallback(data,orderId);
		}
		else{
		errorCallback(data.errorMessages);
		}
		}
		});    
},
    
    redeemBookPoints:function( orderItemId ){
        alert('TODO');
    },
    
    undoBookPoints:function( orderItemId ){
       alert('TODO');
    },
    
    
    removeAllFromWishList:function(  successCallback , errorCallback ){
        $.ajax({
            url:'InterestItemDelete',
            data:{
             'storeId':storeId,
             'catalogId':catalogId,
             'langId':langId,
             'listId':'.',
             'catEntryId':'*',
             'errorViewName':'qs_jsonStatusError',
             'URL':'qs_jsonStatusSuccess'
             
            },
            success:function(data){
              if(data.status == 'success'){  
                successCallback(data);
              }
              else{
               errorCallback(data.errorMessages);
              }
            }
          });  
     },
     
     removeFromWishList:function( catEntryId, successCallback , errorCallback ){
         $.ajax({
             url:'InterestItemDelete',
             data:{
              'storeId':storeId,
              'catalogId':catalogId,
              'langId':langId,
              'listId':'.',
              'catEntryId':catEntryId,
              'errorViewName':'qs_jsonStatusError',
              'URL':'qs_jsonStatusSuccess'
              
             },
             success:function(data){
               if(data.status == 'success'){ 
                 successCallback(data);
               }
               else{
                errorCallback(data.errorMessages);
               }
             }
           });  
      },
      
      moveToBasketFromWishList:function( catEntryId, successCallback , errorCallback  ){
          $.ajax({
               url:'OrderItemAdd',
               data:{
                'storeId':storeId,
                'catalogId':catalogId,
                'langId':langId,
                'catEntryId':catEntryId,
                'quantity':'1',
                'orderId':'.',
                'updatePrices':'1',
                'calculationUsageId':'-1',
				'calculationUsageId':'-2',
                'errorViewName':'qs_jsonStatusError',
                'URL':'InterestItemDelete?URL=qs_jsonOrderBeans'
                
               },
               success:function(data){
                 if(data.status == 'success'){    
                   basketController.setOrder(data.order);
                   basketController.refreshMiniBasket();
				   basketController.refreshBookPoints();
                   successCallback(data);
                 }
                 else{
                  errorCallback(data.errorMessages);
                 }
               }
             });    
        },
    
    addToWishList:function( catEntryId, successCallback , errorCallback ){
       $.ajax({
           url:'InterestItemAdd',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'listId':'.',
            'catEntryId':catEntryId,
            'errorViewName':'qs_jsonStatusError',
            'URL':'qs_jsonOrderBeans'
            
           },
           success:function(data){
             if(data.status == 'success'){ 
               basketController.setOrder(data.order);
               basketController.refreshMiniBasket(); 
			   basketController.refreshBookPoints();  
               successCallback(data,catEntryId);
             }
             else{
              errorCallback(data.errorMessages);
             }
           }
         });  
    },
    
    moveToWishList:function( catEntryId, orderItemId, successCallback , errorCallback  ){
      $.ajax({
           url:'OrderItemDelete',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'orderId':'.',
            'listId':'.',
			'updatePrices':'1',
            'calculationUsageId':'-1',
		    'calculationUsageId':'-2',
            'catEntryId':catEntryId,
            'orderItemId':orderItemId,
            'errorViewName':'qs_jsonStatusError',
            'URL':'OrderCalculate?URL=InterestItemAdd?URL=qs_jsonOrderBeans'
            
           },
           success:function(data){
             if(data.status == 'success'){    
               basketController.setOrder(data.order);
               basketController.refreshMiniBasket();
			   basketController.refreshBookPoints();
               successCallback(data);
             }
             else{
              errorCallback(data.errorMessages);
             }
           }
         });    
    },
    
    sendWishList:function( listId, senderName,sender, recipientName ,recipient, message, successCallback, errorCallback ){
      
      
      
      $.ajax({
           url:'InterestItemListMessage',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'listId':listId,
            'sender_name':senderName,
            'sender':sender,
            'recipient_name':recipientName,
            'recipient':recipient,
            'message':message,
            'SendCopy':'0',
            'errorViewName':'qs_jsonStatusError',
            'URL':'qs_jsonStatusSuccess'
           },
           success:function(data){
             if(data.status == 'success'){    
               successCallback(data,recipientName);
             }
             else{
              errorCallback(data.errorMessages);
             }
           }
         });  
         
    },
    
      
     
    submitPromoCode:function( orderId, promoCode, successCallback, errorCallback ){
    	
    	 $.ajax({
             url:'PromotionCodeManage',
             data:{
              'storeId':storeId,
              'catalogId':catalogId,
              'langId':langId,
              'orderId':orderId,
              'taskType':'A',
              'promoCode':promoCode,
              'updatePrices':'1',
              'calculationUsageId':'-1',
              'errorViewName':'qs_jsonStatusError',
              'URL':'OrderCalculate?URL=qs_jsonOrderBeans'
              
             },
             success:function(data){
               if(data.status == 'success'){    
                 basketController.setOrder(data.order);
                 basketController.refreshMiniBasket();
				 basketController.refreshBookPoints();
                 successCallback(data);
               }
               else{
                errorCallback(data.errorMessages);
               }
             }
           });    
      
    },
    
    sendToAFriend:function( title,
    		                author,
    		                ourPrice,
    		                rrp,
    		                save,
    		                urlInEmail,
    		                thumbnail,
    		                fromname, 
    		                toname, 
    		                fromemail, 
    		                toemail, 
    		                emailMessage, 
    		                sendMeACopy,
    		                successCallback, 
    		                errorCallback){
    	$.ajax({
    		url:'ItemInfoNotification',
    		data:{
              'storeId':storeId,
              'catalogId':catalogId,
              'langId':langId,
              'intro':'Send to a Friend',
              'msgType':'NotifyItemInfoEmailFormat',
              'title':title,
              'author':author,
              'ourPrice':ourPrice,
              'rrp':rrp,
              'save':save,
              'urlInEmail':urlInEmail,
              'thumbnail':thumbnail,
	          'fromname':fromname, 
              'toname':toname, 
              'fromemail':fromemail, 
              'toemail':toemail, 
              'emailMessage':emailMessage, 
              'sendMeACopy':sendMeACopy,
              'errorViewName':'qs_jsonStatusError',
              'URL':'qs_jsonStatusSuccess'
    		},
    		success:function(data) {
                if(data.status == 'success'){    
                    successCallback(data);
                  }
                  else{
                   errorCallback(data.errorMessages);
                  }
    		}
    	  }
    			
    	);
    },
     
    postReview:function( productIds,
    		             productId,
    		             itemName,
    		             itemMaker,
    		             productFeature,
    		             reviewStatusRef,
    		             reviewTypeRef,
    		             rating,
    		             foreName,
    		             emailAddress,
    		             reviewTitle,
    		             reviewText,
 		                 successCallback, 
		                 errorCallback){
    	$.ajax( {
    		url:'ManageBookReview',
    		data: {
              'storeId':storeId,
              'catalogId':catalogId,
              'langId':langId,
              'categoryId':categoryId,
              'updateReviewBody':'true',
              'updateReviewProductLink':'true',
              'redirecturl':'qs_jsonStatusSuccess',
              'productIds':productIds,
              'productId':productId,
              'itemName':itemName,
              'itemMaker':itemMaker,
              'productFeature':productFeature,
              'reviewStatusRef':reviewStatusRef,
              'reviewTypeRef':reviewTypeRef,
              'rating':rating,
              'foreName':foreName,
              'surname':'',
              'email':emailAddress,
              'field3':reviewTitle,
              'reviewText':reviewText
    		},
    		success:function(data) {
                if(data.status == 'success'){    
                    successCallback(data);
                  }
                  else{
                   errorCallback(data.errorMessages);
                  }
    		}
    	});
    },
    
    subscribe:function( listName,
    		            title,
    		            firstName,
    					lastName,
    					subscribeEmailAddress,
    					setting,				
    					successCallback,
    					errorCallback) {
    	$.ajax({
    		url:'LyrisMemberUpdateCmd',
    		data:{
              'storeId':storeId,
              'catalogId':catalogId,
              'langId':langId,
              'Title':title,
              'Firstname':firstName,
              'Lastname':lastName,
              'name': (title ? title + " " : "") + firstName + " " + lastName,
              'email':subscribeEmailAddress,
              'list':listName,
              'confirm':'one',
              'showconfirm':'F',
              'errorViewName':'qs_jsonStatusError',
              'URL':'qs_jsonStatusSuccess',
              'mailinginclude':setting,
              'demographics':'mailinginclude'
    	    },
    	    success:function(data) {
    	    	if(data.status == 'success') {
    	    		successCallback(data);
    	    	} else {
    	    		errorCallback(data.errorMessages);
    	    	}
    	    }
    	});

    }

  }
}



function  QS_AccountController(){

 
  return{

    init: function(){

     
      if(sessvars.tvbook_user == null){
        var bypassSync = ($(".QS_bypassSync").size() > 0);
        if(!bypassSync){
         $.ajax({
           url:'qs_jsonUserRegistrationDataBean',
           data:{
            'storeId':storeId,
            'catalogId':catalogId,
            'langId':langId,
            'errorViewName':'qs_jsonStatusError'
           },
           success:function(data){
             if(data.status == 'success'){    
               accountController.setUser(data.user);
               accountController.bind();
               accountController.render();
             }
             else{
            	 sessionController.showErrorOverlay(data.errorMessages);
             }
           }
         }); 
		}   
      }
      else{
        this.bind();
        this.render();
      }
	  
    },
    
    bind:function(){
      $('.QS_AccountController_logOut_button').bind('click',  function(event){
        sessionController.logOut();
      });
    }, 

    render:function(){
      if(this.getUser() == null || this.getUser().status !=  'loggedIn'){
        $('.loggedOut').show();
        $('.loggedIn').hide();
      }
      else{
        $('.QS_userFullName').html(this.getUser().firstName );
        $('.loggedIn').show();
        $('.loggedOut').hide();
      }
    },
    
    purge:function(){
     this.setUser(null);
     sessvars.$.flush();
    },

    getUser:function(){
      return  sessvars.tvbook_user;
    },
    
    setUser:function(user){
      sessvars.tvbook_user = user;
      sessvars.$.flush();
    },
    
    addAddress:function( addressFormName ){
       alert('todo');
    },
    
    updateAddress:function( addressId, addressFormName){
       alert('todo');
    },
    
    deleteAddress:function( addressId){
      alert('todo');
    },
    
    updateUser:function( userFormName ){
       alert('todo');
    },
    
    requestNewPassword:function(logonId, successCallback, errorCallback){
    	
    	$.ajax({
            url:'ResetPassword',
            data:{
             'storeId':storeId,
             'challengeAnswer':'-',
             'catalogId':catalogId,
             'langId':langId,
             'logonId': logonId,
             'errorViewName':'qs_jsonStatusError',
             'URL':'qs_jsonStatusSuccess'
            },
            success:function(data){
              if(data.status == 'success'){    
            	  successCallback(data);
              }
              else{
            	  errorCallback(data.errorMessages);
              }
            }
          });  
    	
    },
    
    reportAjaxErrors:function(errorMessages){
   
      alert(errorMessages);
    }
   
    
  }
}


var QS_AddressController;


function  QS_AddressController(){
	

	var showLookupAddressResultsOverlay = function(addressFragmentId, addressSummaries){
		
		$('#QS_lookupAddressResultsOverlay select').empty();
	
		for (var i=0, addressSummary; addressSummary = addressSummaries[i]; i++ ){
		
			$('#QS_lookupAddressResultsOverlay select').append("<option value='"+ addressSummary.id +"'   >"+ addressSummary.text +"</option>")
		}
		
		$('#QS_lookupAddressResultsOverlay select').bind('dblclick',function(){QS_AddressController.invokeSelectAddressButton();});
		$('#QS_lookupAddressResultsOkButton').attr('name',addressFragmentId);
		
	
	    var api = $("#QS_lookupAddressResultsOverlay").overlay({
	      close: '#QS_lookupAddressResultsCloseButton,#QS_lookupAddressResultsOkButton',
		  closeOnClick: false
	    }); 
	    api.load(); 
	}
	
	var initCountry = function(addressFragmentId, country){
		$("#"+addressFragmentId + " option[value='"+country+"']").attr('selected','selected');
		var postcodeElements = $('#'+addressFragmentId + ' .QS_postcodeElement');
		if($.trim(country) != "GB" ){
			postcodeElements.fadeOut();
			$("#"+addressFragmentId + " input[name='zipCode']").val("");
		}
		else{
			
			postcodeElements.fadeIn();
		}
	}

  return{
  	init:function(){ 
	
      $("#QS_lookupAddressResultsOverlay").overlay({
        close: '#QS_lookupAddressResultsCloseButton,#QS_lookupAddressResultsOkButton',
		closeOnClick: false
      }); 
	  
	
	  var addressFragments = $(".QS_addressFragment");
	  addressFragments.each(function(n){
	  	var addressFragmentId = this.id;
		var initialCountryValue = $("#"+addressFragmentId + " input[name='initialCountryValue']").val();
		if(!initialCountryValue){
		  initialCountryValue ="GB";
		}
		initCountry(addressFragmentId, initialCountryValue);
	  });
	},
  	
	findLookupAddressList:function(addressFragmentId){
	   var postcode = $("#"+addressFragmentId+" dd input[name='zipCode']").val();
	   
	   if(!postcode){
		 sessionController.showErrorOverlay("Unable to find address search results for the following reasons:<br /><br />"+
		                                    "No value for postcode. <br /><br />"+
		                                    "Please enter a UK postcode.");
         return;
	   }
	   
	
	   postcode = new String($.trim(postcode)).toUpperCase();
	   $('#'+addressFragmentId +' input[name=zipCode]').val(postcode);
        
	   
	   if( !(QS_Constants.postcodeRegex().test(postcode)) ){
		 sessionController.showErrorOverlay("Unable to find address search results for the following reasons:<br /><br />"+
		                                    "Invalid postcode value. <br /><br />"+
		                                    "Please enter a valid UK postcode.");
	   }
	   else{
	   
		   $.ajax({
		       url:'qs_jsonLookupAddressSummaryBean',
		       data:{
		        'storeId':storeId,
		        'catalogId':catalogId,
		        'langId':langId,
		        'postcode':postcode,
		        'errorViewName':'qs_jsonStatusError'
		       },
		       success:function(data){
			   	 
		         if(data.status == 'success'){    
	
				  if(data.addressSummaries && data.addressSummaries.length > 0){
				  	showLookupAddressResultsOverlay(addressFragmentId, data.addressSummaries);
				  }
				  else{
				  	sessionController.showErrorOverlay("<strong>No address information found for " + postcode +".</strong><br /><br />"+
														"Please check your postcode and country are correct.<br /><br />"+
														"If this error persists, please enter your address information by hand.<br /><br /><br />");
				  }
		         }
		         else{
		          sessionController.showErrorOverlay(errorMessages);
		         }
		       }
		   }); 
	   }
	},
	

	selectLookupAddress:function(addressFragmentId){
	   var addressId = $('#QS_lookupAddressResultsOverlay select').val();
	    $.ajax({
	       url:'qs_jsonLookupAddressBean',
	       data:{
	        'storeId':storeId,
	        'catalogId':catalogId,
	        'langId':langId,
	        'addressId':addressId,
	        'errorViewName':'qs_jsonStatusError'
	       },
	       success:function(data){
	         if(data.status == 'success'){ 
			   var fragment = $('#'+addressFragmentId);
               fragment.find('input[name=address1]').val(data.address.address1);
			   fragment.find('input[name=address2]').val(data.address.address2);
			   fragment.find('input[name=address3]').val(data.address.address3);
			   fragment.find('input[name=city]').val(data.address.city);
			   fragment.find('input[name=state]').val(data.address.state);
	         }
	         else{
	          sessionController.showErrorOverlay(errorMessages);
	         }
	       }
	   });  
	},
	
	invokeSelectAddressButton:function(){
	  $("#QS_lookupAddressResultsOkButton").click();
	},
	
	addressCountryChanged: function(addressFragmentId, country){	
	   initCountry(addressFragmentId, country);
	}

    
 
  }
}


$(function(){
 QS_AddressController = new QS_AddressController();
 QS_AddressController.init();
});