/**
 * @class Product_Class
 * This class has only properties
 * Result will hold the data that comes from the webservices
 * in JSON format
 * When a product object is created, it is added in the collection by productmanager
 * with Loaded=false
 * when successful response comes from the web service, loaded is set to true
 * so next time, if the user will access the same product, and if ENABLE_PRODUCT_CACHING is
 * set to true, the data will be taken from the memory vs webservice call. This is done to improve the performance
 * and minimize the calls to the server.
 * @constructor 
 */

Core.Product_Class=function () {
    /**
     * Product Code which is prd_code in DB
     */    
    this.ProductCode="";
    /**
     *  The json object reurned via webservices
     */
    this.Result;

    /**
     * Product Name
     */
    this.Name="";

    /**
     * it is set to true if loaded and set to false otherwise.
     */
    this.Loaded=false;
}
/**
 * It registers the Product_Class using registerClass method of MS AJAX Library
 */
 if (IsTypeDefined) {Core.Product_Class.registerClass('Core.Product_Class'); }


/**
 * @class ProductManager_Class
 * This class Manages both Products and Variants
 * It adds a product/variant in the collection,
 * loads the data from webservice and caches the data locally
 * if caching is enabled for both Products and Variants
 * @constructor 
 */

 Core.ProductManager_Class=function() {
    /**
     * The collection of the products to be cached (visited previously by the user)
     */
    this.ProductCollection=new Array();
    /**
     * The collection of Variants Cached (visited previously by the user)
     */
    this.VariantCollection=new Array();
    /**
     * 0 build shade table 
     * 1 Skin Care
     */
    this.Action=0; 

    /** 
     * Holds a reference to the parent control. If this value is present,
     * when attempting to show a new bubble, this control will attempt to hide
     * the parent
     */
    this.parentControlID=null;
    
    this.UseConfirmBubble=false;
    
    this.ConfirmBubbleID="ProductConfirmFavorite_Bubble";
        
    /**
     * Adds a product to the internal product collection
     * @param {object} ProductObject The product object
     */
    this.AddProduct= function (ProductObject) {
        var exist=false;
        if (this.ProductCollection!=null) {
            for (var i=0; i<this.ProductCollection.length; i++) {
                if (this.ProductCollection[i].ProductCode==ProductObject.ProductCode) {
                    this.ProductCollection[i]=ProductObject;
                    exist=true;
                    break;
                }
            }

            if(exist==false) {
                this.ProductCollection[this.ProductCollection.length]=ProductObject;
            }
        }
    }

    /**
     * Retrieve a product to the internal product collection
     * @param {string} ProductCode The product code of the product to retrieve from the ProductCollection
     */
    this.GetProduct=function (ProductCode) {
        for (var i=0;i<this.ProductCollection.length;i++) {
            if (this.ProductCollection[i].ProductCode==ProductCode) {
                  return this.ProductCollection[i];
             }
        }
    }

    /**
     * This method below checks if a copy exist on the Memory, if it does, no need to call web service
     * @param {string} ProductCode The product code of the product to retrieve
     */
    this.LoadProduct=function (ProductCode) {
        _ProductBubble_Class.LockCoordinates();
        _ProductBubble_Class.HideShades();
        _WebServiceAPI.LoadProduct(ProductCode,true,this.OnRequestComplete);
     }

    /**
     * This method will load the product data along with any product recommendations for a diag.
     * @param {string} CurrentCustomerID The current customer ID (GUID)
     * @param {string} ProductCode Product Code(SKU)
     * @param {string} DiagCode The diagnosis code 
     * @param {string} CategoryCode The category code
     * @param {string} RetailerCode The retailer code
     * @param {string} FilterExpression The retailer code
     
     */
    this.LoadProductAndDiag=function (CurrentCustomerID, ProductCode, DiagCode, CategoryCode, RetailerCode,FilterExpression) {
        _ProductBubble_Class.LockCoordinates();
        _ProductBubble_Class.HideShades();
        _WebServiceAPI.LoadProductWithDiagnosisInformation(CurrentCustomerID, ProductCode, DiagCode, CategoryCode, RetailerCode,(typeof(FilterExpression)=='undefined')? "" : FilterExpression, this.OnRequestComplete);
   
    }

    /**
     * Loads the product thumbsnail and also retrieves the diagnosis information to see if these
     * products have been recommended to the customer
     * @param {string} RelativeObjectID The ID of the object to use for relative positioning of the new table
     * @param {int} plusTop The offset for the result object from the top of the RelativeObjectID
     * @param {int} plusLeft The offset for the result object from the left of the RelativeObjectID
     * @param {string} CurrentCustomerID The current customer ID
     * @param {string} ProductCode The product code of the product to retrieve
     * @param {string} DiagCode The diag code to use to determine if this product is recommended
     * @param {string} CategoryCode The cateogyr code 
     * @param {string} RetailerCode The retailer code
     * @param {string} FilterExpression filter criteria
     
     */
    this.LoadProductThumbnailsWithDiag=function(RelativeObjectID, plusTop, plusLeft, CurrentCustomerID, ProductCode, DiagCode, CategoryCode, RetailerCode,FilterExpression) {
        this.Action=0;
        if (DiagCode == null)
        {
            if (typeof(FilterExpression)=='undefined' || FilterExpression=="") {
                this.LoadProduct(ProductCode);
            }
            else {
            
                this.LoadProductFilterVariants(ProductCode,FilterExpression);
            }
            
        }
        else
        {
          
            this.LoadProductAndDiag(CurrentCustomerID, ProductCode, DiagCode, CategoryCode, RetailerCode,FilterExpression);
        }
       // var relativeObject = $get(RelativeObjectID);
       // var bubble = $get(_ProductBubble_Class.Variants_Main_All_Thumbnails);
       // PositionLayerByRelativeObject(relativeObject,bubble,plusTop,plusLeft);
    }

    /**
     * Loads the product thumbsnail
     * @param {string} RelativeObjectID The ID of the object to use for relative positioning of the new table
     * @param {int} plusTop The offset for the result object from the top of the RelativeObjectID
     * @param {int} plusLeft The offset for the result object from the left of the RelativeObjectID
     * @param {string} ProductCode The product code of the product to retrieve
     */
    this.LoadProductThumbnails=function(RelativeObjectID, plusTop, plusLeft, ProductCode) {
        this.LoadProductThumbnailsWithDiag(RelativeObjectID, plusTop, plusLeft, null, ProductCode, null, null, AJAX_DEFAULT_RETAILER,"");
    }

    /**
     * TODO
     * @param {string} ProductCode The product code of the product to retrieve
     */
    this.LoadSkinCareProduct=function(ProductCode, ParentControlID) {
        this.Action=1;
        this.parentControlID = ParentControlID;
        this.LoadProduct(ProductCode);
    }

    /**
     * 
     * @param {string} ProductCode The product code of the product to retrieve
     */
    this.LoadMakeupProduct=function(ProductCode, ParentControlID) {
        this.Action=2;
        this.parentControlID = ParentControlID;
        this.LoadProduct(ProductCode);
    }
   //
   this.LoadMakeupProductFilterVariants=function(ProductCode, ParentControlID,FilterExpression) {
        this.Action=2;
        this.parentControlID = ParentControlID;
         this.LoadProductFilterVariants(ProductCode,FilterExpression);
    }
   //
   this.LoadSkinCareFilterVariants=function(ProductCode, ParentControlID,FilterExpression) {
        this.Action=1;
        this.parentControlID = ParentControlID;
        this.LoadProductFilterVariants(ProductCode,FilterExpression);
    }
   //Loads product from web services  and filter variants
   this.LoadProductFilterVariants=function (ProductCode,FilterExpression) {
        _ProductBubble_Class.LockCoordinates();
        _ProductBubble_Class.HideShades();
        _WebServiceAPI.LoadProductWithFilteredVariants(ProductCode,FilterExpression,this.OnRequestComplete);
    
    }
    /**
     * This method is called after a web Service Call is Completed
     * @param {string} result The result object returned from the web service
     */
    this.OnRequestComplete= function (result) {
        DoDefault();
        if (result != null)    {
                var  _Product=new Core.Product_Class();
                _Product.ProductCode=result.SKU;
                _Product.Result=result;
                _Product.Loaded=true;
                _ProductManager.DoBranching(_Product);
        }
    }


    /**
     * TODO
     * @param {ProductBubble_Class} _Product The product bubble
     */
    this.DoBranching=function(_Product) {
        _ProductBubble_Class.IsMakeupProduct=true;

        switch(this.Action){
            case 0 :
                //this.DisplayShadeTable(_Product);
                 _ProductBubble_Class.Code=_Product.ProductCode;
                 _ProductBubble_Class.PopUp = _CoreModalPopUp;
                _ProductBubble_Class.DisplayShadeTable(_Product);
                break;
            case 1 :
                _ProductBubble_Class.IsMakeupProduct=false;
                _ProductBubble_Class.Code=_Product.ProductCode;
                _ProductBubble_Class.LoadProductRequestComplete(_Product.Result)
                break;
            case 2 :
                _ProductBubble_Class.IsMakeupProduct=true;
                _ProductBubble_Class.Code=_Product.ProductCode;
                _ProductBubble_Class.LoadProductRequestComplete(_Product.Result)
                break;
            default :
                //this.DisplayShadeTable(_Product);
                 _ProductBubble_Class.Code=_Product.ProductCode;
                _ProductBubble_Class.DisplayShadeTable(_Product);
                break;
        }
    }


    // Variant methods:

    /**
     * Adds a variant to the VariantCollection array
     * @param {object} VariantObject The variant object
     */
    this.AddVariant= function (VariantObject) {
        var exist=false;
        if (this.VariantCollection!=null) {
            for (var i=0;i<this.VariantCollection.length;i++) {
                if (this.VariantCollection[i].ProductCode==VariantObject.ProductCode) {
                    this.VariantCollection[i]=VariantObject;
                    exist=true;
                    break;
                }
            }
            if(exist==false) {
                this.VariantCollection[this.VariantCollection.length]=VariantObject;
            }
        }
    }

    /**
     * Retrieves a variant to the VariantCollection array
     * @param {string} VariantCode The variant code to find
     */
    this.GetVariant=function (VariantCode) {
        for (var i=0;i<this.VariantCollection.length;i++) {
            if (this.VariantCollection[i].ProductCode==VariantCode) {
                return this.VariantCollection[i];
            }
        }
    }

    /**
     * Retrieves the variant either from the web service or cache (if enabled) 
     * @param {string} VariantCode The variant code to find
     */
    this.LoadVariant=function (VariantCode) {
        if (ENABLE_VARIANT_CACHING) {
            var _Variant=this.GetVariant(VariantCode)
            if ((_Variant==null) || (typeof(_Variant)=='undefined') || (_Variant.Loaded=false)){
                _Variant=new Core.Product_Class();
                _Variant.ProductCode=VariantCode;
                this.AddVariant(_Variant);
                _WebServiceAPI.LoadProduct(VariantCode,false,this.VariantOnRequestComplete)
            }
            else {
                // this.DisplayShadeTable(_Product);
                this.DoVariantBranching(_Variant);
            }
        }
        else {
            _WebServiceAPI.LoadProduct(VariantCode,false,this.VariantOnRequestComplete)
        }
    }
           
    /**
     * Callback handler from LoadVariant
     * @param {object} result The resulting product object
     */
    this.VariantOnRequestComplete = function (result) {
        DoDefault();
        if (result != null) {
            if (ENABLE_VARIANT_CACHING) {
                var _Variant=_ProductManager.GetVariant(result.SKU);//later use the productid
                _Variant.Result=result;
                _Variant.Loaded=true;
                _ProductManager.AddVariant(_Variant);
                _ProductManager.DoVariantBranching(_Variant);
            }
            else {
                var  _Variant=new Core.Product_Class();
                _Variant.ProductCode=result.SKU;
                _Variant.Result=result;
                _ProductManager.DoVariantBranching(_Variant);
            }
        }
    }

    /**
     * Do variant branching
     * @param {object} _Variant The variant object
     */
    this.DoVariantBranching=function(_Variant) {
        _VariantBubble_Class.parentControlID=this.parentControlID;    
        _VariantBubble_Class.Code=_Variant.ProductCode;
        _VariantBubble_Class.PopulateData(_Variant.Result);
    }

    /**
     * Loads a shade in a bubble
     * @param {string} VariantCode Loads the variant for display
     */
    this.LoadMakeupVariant=function(VariantCode, ParentControlID) {
        this.Action=0;
        this.parentControlID = ParentControlID;
        this.LoadVariant(VariantCode);
    }
       
      /**
     * Used to add a product to a customer's favorite list
     * @param {string} CustomerId The customer ID GUID
     * @param {int} FavoriteProductType The type of favorite list to retrieve
     * @param {string} RetailerCode The current retailer code
     * @param {string} ProductCode The product code to add to the customer's favorite list
     */
     this.AddProductToFavorites=function(FavoriteProductType, RetailerCode, ProductCode) {
       _WebServiceAPI.AddToFavorites(CurrentCustomerID, this.ConvertTypeToInteger(FavoriteProductType), RetailerCode, ProductCode, this.AddProductToFavoritesOnComplete);
     }
     
     /**
     * AddProductToFavoritesOnComplete
     * @param {object} result that comes from web service
     */
     this.AddProductToFavoritesOnComplete=function(result) {
        if (result!=null) {
            if(result==true) {
                var confirmMsgObj=null;
                var productInfoObj=null;
                var confirmMessage=null;

                if (_QuickShop_Class.FromProductBubble != true){
                    confirmMsgObj = $get(VAR_FAVORITE_CONFIRM_ID);
                    productInfoObj = $get(VAR_PRODUCT_INFO_ID);
                    confirmMessage = VAR_FAVORITE_CONFIRM_MESSAGE
                    // ADDED for DT733 to display bubble from MyTips Page as well
                    _CoreModalPopUp._PopupControlID = "ProductConfirmFavorite_Bubble";
                    _CoreModalPopUp.ShowModal();                    
                }else{
                    if(_ProductManager.UseConfirmBubble == true){
                            // use the bubble
                            _CoreModalPopUp._PopupControlID=_ProductManager.ConfirmBubbleID;
                            _CoreModalPopUp.ShowModal();
                            // reset the variable
                            _ProductManager.UseConfirmBubble = false;
                    }else{
                        //confirmMsgObj = $get(_ProductManager.ConfirmBubbleID);
                        productInfoObj=$get(PRD_PRODUCT_INFO_ID);
                        confirmMsgObj = $get(PRD_FAVORITE_CONFIRM_ID);                
                        confirmMessage = PRD_FAVORITE_CONFIRM_MESSAGE;
                    }
                }

                // use the inline message
                if(confirmMsgObj != null){
                    confirmMsgObj.style.display = "block";
                    confirmMsgObj.innerHTML = confirmMessage;                    
                }
                
                if(productInfoObj != null){
                    productInfoObj.style.display = "none";
                }
                
            }else {
                alert('Your request failed to complete. Please try again.');
            }
        }
    }
    
    // GDH 4-20-2007 changed to use the CORE values - they differ from the product types
     this.ConvertTypeToInteger=function(value) {
         switch(value){
            case 'Product':
                return 0;
                break;
            case 'Variant':
                return 0;
                break;
            default:
                return 0;
                break;
        }
     }     
//     this.ConvertTypeToInteger=function(value) {
//        switch(value){
//           case 'Product':
//                    return 1;
//                    break;
//		   case 'Variant':
//		            return 2;
//                    break;
//		  case   'Sample':
//		            return 3;
//                   break;
//		  case    'BoxSet':
//		            return 4;
//                   break;
//		  case     'Packaging':
//		           return 5;
//                   break;
//		 case      'eGift':
//		            return 6;
//                   break;
//		 case      'Document':
//		            return 7;
//                   break;
//		 case      'Message':
//		             return 8;
//                   break;
//		 case      'Flyer':
//		             return 9;
//                    break;
//       default:
//                return 1;
//                break;
//
//        }
//     }
     
}
 /**
 * It registers the  ProductManager_Class using registerClass method of MS AJAX Library
 */
 if (IsTypeDefined) { Core.ProductManager_Class.registerClass('Core.ProductManager_Class'); }

