﻿/* 
    basketController.js 
    responsible for controlling flow when adding items to the basket
*/

// initialise
//  + wgid (long) - the WebGateway id
//  + mmid (long) - the MangoMart id
//  + quantity (int) - quantity    
//  + save (bool) - add as a WishList item?
//  + returnShoppingUrl (string) - return shopping url value
//  + isQuantityOverride (bool) - whether to override the current quantity in the basket
this.basketController = function(wgid, mmid, quantity, save, returnShoppingUrl, isQuantityOverride){

    // public props
    this.wgid = mmid;
    this.mmid = mmid;
    this.quantity = quantity;
    this.save = save;
    this.returnShoppingUrl = returnShoppingUrl;
    this.isQuantityOverride = isQuantityOverride;
    this.basketItemId = '';
    this.productJsonData = null;
    this.isCostQuery = false;
    this.isSuppressAlerts = false;
    
    // enums
    var InStock = 0;
    var OutOfStock = 1;
    var Disabled = 2;
    var Discontinued = 3;
    var Deleted = 4;
    
    // funcs
    
    // do product stock checks
    // + callback (function) - function to execute on success
    this.doStockCheck = function(callback){
    
        // only check on non-wishlist
        if(true == this.save){
            execute(callback);
        }else{
        
            var ctrl = this;

            this.ensureProductData(function(){
            
                if(ctrl.productJsonData == null 
                        || ctrl.productJsonData.StockStatus == Discontinued 
                        || ctrl.productJsonData.StockStatus == Deleted){
                    
                    promptIf(!ctrl.isSuppressAlerts, 'Sorry, this item is no longer available', function(v,m){
                        cancelAction('', ctrl.mmid);
                    });
                    
                }else if(true == ctrl.isCostQuery && ctrl.productJsonData.StockStatus != InStock){
                
                    promptIf(!ctrl.isSuppressAlerts, 'Sorry, this item is not currently in stock', function(v,m){
                        cancelAction('', ctrl.mmid);
                    });
                                        
                }else if(ctrl.productJsonData.StockStatus != InStock){
                
                    if(ctrl.isSuppressAlerts){
                        ctrl.save = true;
                        execute(callback);
                    }else{
                        doPrompt('Sorry, this item is not currently in stock, would you like to add to your saved for later items?',
                            function(){ctrl.save = true;execute(callback);}, 
                            function(){cancelAction('', ctrl.mmid);},
                            false);
                    };
                
                }else{
                    execute(callback);
                };
                
            });
        };
    };
    
    // do quantity checks
    // + callback (function) - function to execute on success
    this.doQuantityCheck = function(callback){
    
        var ctrl = this;
        
        ctrl.quantity = (ctrl.quantity == 0 || ctrl.quantity == "") ? 1 : ctrl.quantity;
        
        $mb.jsonLoader.quantityCheck(this.mmid, ctrl.quantity, ctrl.isQuantityOverride, ctrl.save, function(data){ 
            if(true == $mb.canHandle(data)){
            
                
                var innerData = data.InnerData;
                ctrl.productJsonData = innerData.Product;
                if(data.InnerData.IsQuantityValid){
                
                    execute(callback);
                
                }else{
                
                    if(innerData.SuggestedQuantity > 0){
                    
                        if(true == ctrl.isSuppressAlerts){
                            ctrl.quantity = innerData.SuggestedQuantity;
                            execute(callback);
                        }else{
                            
                            doPrompt(innerData.Message,
                                function(){ctrl.quantity = innerData.UpQuantity;execute(callback);}, 
                                function(){
                                    ctrl.quantity = innerData.DownQuantity;
                                    if(ctrl.quantity <= 0){
                                        cancelAction('', ctrl.mmid);
                                    }else{
                                        execute(callback);
                                    };
                                },
                                false);
                        };
                    
                    }else{
                        promptIf(!ctrl.isSuppressAlerts, innerData.Message, function(v,m){
                            cancelAction('', ctrl.mmid);
                        });
                        return;
                    };
                };
            };
        });
    };
    
    // do price change checks
    // + callback (function) - function to execute on success
    this.doPriceChangeChecks = function(callback){
    
        var q = this.quantity;
        var ctrl = this;

        this.ensureProductData(function(){

            var newPrice = ctrl.productJsonData.GetPrice(q);

            var msg = 'Please note that the price has changed for this item<br/><br/>'
                       + 'The new price for ' + q + ' items is ' + newPrice + '<br/><br/>'
                       + 'Click \'OK\' to continue or \'Cancel\' to cancel';
                       
            doPrompt(msg, 
                function(){execute(callback);}, 
                function(){cancelAction('', ctrl.mmid);}, 
                false, 
                { OK: true, Cancel: false }
            );                       

        });
    
    };
    
    // do quantity checks
    // + callback (function) - function to execute on success 
    //      - this passed a single parameter, data (BasketJsonData)
    this.doAddToBasket = function(callback){
    
        var qs = getRootQueryString(this.wgid) + 
                    '&mmid=' + this.mmid + 
                    '&sfl=' + this.save + 
                    '&ru='  + this.returnShoppingUrl + 
                    '&qo='  + this.isQuantityOverride + 
                    '&qu='  + this.quantity +
                    '&bid=';

        var jsonUrl = $mb.urlBuilder.buildJsonUrl(qs);
        
        var qu = this.quantity;

        $.getJSON(jsonUrl, function(data){
        
            if(true == $mb.canHandle(data)){
                // add QuantityAdded, this may be different to the BasketItem.Quantity
                data.InnerData.ActiveItem.QuantityAdded = qu;
                if(typeof(callback) == 'function') callback(data);
            };
            
        });  
       
    
    };
    
    // ensure that we have product data
    this.ensureProductData = function(callback){
    
        // good ?? from cache
        if(false == this.isProductGood()){
            this.loadProductFromCache();
        };
        
        // good ?? load
        var controller = this;
        if(true == this.isProductGood()){
            execute(callback);
        }else{
            $mb.jsonLoader.loadProduct(this.mmid, function(data){
            
                if(true == $mb.canHandle(data)){
                    controller.productJsonData = data.InnerData;
                    execute(callback);
                };
            });
        };    
    };
    
    // whether the product in memory is good - e.g. we have one and the mmid is correct
    this.isProductGood = function(){
        return null != this.productJsonData && this.productJsonData.MMID == this.mmid;
    };
    
    // load the current product from the cache
    this.loadProductFromCache = function(){
       var result = $mb.getProductData(this.mmid);
       var controller = this;
       if(true == result.isFullProductInfo){
            controller.productJsonData = result;
       };
    };
    
    
    // private funcs
    function cancelAction(msg, mmid){
        $mb.doOnBasketActionCancelled(mmid);
        $mb.setBasketMessage(msg, false);
    }
   
    // execute a callback function
    function execute(callback){
        if(typeof(callback) == 'function') callback();
    };
    
   
    
    // get the root url for BasketAdd functions
    // + egid (long) WebGateway id
    function getRootQueryString(wgid){
        
        var result = '?rak=' + getCookie('rak')
                        + '&rid=' + getCookie('rid')
                        + '&wgid=' + wgid 
                        + '&cmd=BasketAdd';
        
        return result;
    };
    
    // prompt with the message if condition is true (OK only)
    // n.b. cannot use this if the callback is dependent on the user's choice in the prompt
    // + condition (bool) - the condition to meet
    // + msg (string) - the prompt to display
    // + cb (function) - callback to execute, regardless
    function promptIf(condition, msg, cb){
        
        if(true == condition){
            doPrompt(msg,
                        cb, 
                        null,
                        false,
                        {OK: true});
        }else{
            cb();
        };
        
    };
};
