var PRODUCT_JSON_URL = "/rpc/jsonrpc.tmpl";

var g_prodcatMethod = 'prodcat';
var g_prodcatQueryParams = [{
			"suppress_bad_skus" : 1,	
			
			"category_fields" : ["CATEGORY_ID",
				"CATEGORY_NAME",
				"products"],

		    "product_fields" : [ "PRODUCT_ID",
		        "DEFAULT_CAT_ID",
		        "PARENT_CAT_ID",
		        "PROD_RGN_NAME",
				"PROD_RGN_SUBHEADING", 
				"SUB_LINE",
		        "DESCRIPTION",
		        "SHORT_DESC",
		        "PROD_SKIN_TYPE",
		        "PROD_SKIN_TYPE_TEXT",
		        //"IMAGE_NAME",
		        //"DISPLAY_ORDER",
		        "SMALL_IMAGE",
		        "LARGE_IMAGE",
		        "THUMBNAIL_IMAGE",
		        "PRODUCT_USAGE",
		        "AVERAGE_RATING",
		        "TOTAL_REVIEW_COUNT",
		        "RATING_IMAGE",
		        "FORMULA",
		        "ATTRIBUTE_COVERAGE",
		        "ATTRIBUTE_BENEFIT",
		        //"BRUSH",
		        "SKIN_CONCERN_ATTR",
		        "SKIN_CONCERN_LABEL", 
		        "SKIN_CONCERN_1",
		        "SKIN_CONCERN_2",
		        "SKIN_CONCERN_3",
		        "skus",
		        "shaded",
		        "sized",
		        "url"],
	
			"sku_fields" : ["SKU_ID",
                "SKU_BASE_ID",
				"PRODUCT_ID",
				//"DISPLAYNAME",
				"SHADENAME",
				"SHADE_DESCRIPTION",
				"SKIN_TYPE",
				"SKIN_TYPE_TEXT",
				"PRODUCT_SIZE",
				//"shopping_id",
				"STRENGTH",
				"PRICE",
				"SMOOSH_DESIGN",
				"SMOOSH_PATH_STRING",
				"INVENTORY_STATUS",
				"isShoppable",
				"REFILLABLE",
				"PRICE",		
				"formattedPrice",
				"formattedInstallmentPrice",
				"formattedUnitPrice",
				"UNIT_SIZE",
				"UOM",
				"formattedTaxedPrice",
				"HEX_VALUE",
				"HEX_VALUE_STRING",
				"FINISH",
				"ATTRIBUTE_COLOR_FAMILY"
                ]
            }];


var g_tacdorpMethod = 'prodcat';
var g_tacdorpQueryParams = [{
			"suppress_bad_skus" : 1,	
			
			"sku_fields" : ["SKU_ID",
                "SKU_BASE_ID",
				"PRODUCT_ID",
				//"DISPLAYNAME",
				"SHADENAME",
				"SHADE_DESCRIPTION",
				"SKIN_TYPE",
				"SKIN_TYPE_TEXT",
				"PRODUCT_SIZE",
				//"shopping_id",
				"STRENGTH",
				"PRICE",
				"SMOOSH_DESIGN",
				"SMOOSH_PATH_STRING",
				"INVENTORY_STATUS",
				"isShoppable",
				"REFILLABLE",
				"PRICE",		
				"formattedPrice",
				"formattedInstallmentPrice",
				"HEX_VALUE",
				"HEX_VALUE_STRING",
				"FINISH",
				"ATTRIBUTE_COLOR_FAMILY"
                           ],

		    "product_fields" : [ "PRODUCT_ID",
		        "DEFAULT_CAT_ID",
		        "PARENT_CAT_ID",
		        "PROD_RGN_NAME",
		        "DESCRIPTION",
		        "SHORT_DESC",
		        "PROD_SKIN_TYPE",
		        "PROD_SKIN_TYPE_TEXT",
		        //"IMAGE_NAME",
		        //"DISPLAY_ORDER",
		        "SMALL_IMAGE",
		        "LARGE_IMAGE",
		        "THUMBNAIL_IMAGE",
		        "PRODUCT_USAGE",
		        "AVERAGE_RATING",
		        "TOTAL_REVIEW_COUNT",
		        "RATING_IMAGE",
		        "FORMULA",
		        "ATTRIBUTE_COVERAGE",
		        "ATTRIBUTE_BENEFIT",
		        //"BRUSH",
		        "SKIN_CONCERN_ATTR",
		        "SKIN_CONCERN_LABEL", 
		        "SKIN_CONCERN_1",
		        "SKIN_CONCERN_2",
		        "SKIN_CONCERN_3",
		        "skus",
		        "shaded",
		        "sized",
		        "url"],
				
			"category_fields" : ["CATEGORY_ID",
				"CATEGORY_NAME"]

			}];

var ProductMultiBox = Class.create({

    initialize: function(args) {
        
        // Init defaults for class variables
		this.productIds = [];
		this.productImages = [];
		this.categoryIds = [];
		this.skuIds = [];
		this.catprodData = null;
		this.queryParams = [];
		this.productsPerRow = 1;
		this.maxProducts = 0;
		this.containerId = 'elm_' + generateGuid();
		this.prodcatMethod = g_prodcatMethod;
		this.callbackDataLoaded = function(){};
		this.callbackCompleted  = function(){};
		
		// Possible display modes:
		// 0 == thumb
		// 1 == small product
		// 2 == large product
		this.mode = 0;

		// Load up passed params
        Object.extend(this, args || {});
	},
	
	addProduct: function(productId,productImage) {
		this.productIds.push(productId);
		if ( productImage ) {
			this.productImages[productId] = productImage;
		}
	},
	
	addCategory: function(categoryId) {
		this.categoryIds.push(categoryId);
	},
	
	addSku: function(skuId) {
		this.skuIds.push(skuId);
	},
	
	setContainer: function(containerId,productsPerRow) {
		this.containerId = containerId;
		this.productsPerRow = productsPerRow || this.productsPerRow;
	},
	
	loadMultiBox: function() {
		
		if ( this.containerId && 
			 ( this.productIds.length > 0 || this.categoryIds.length > 0 || this.skuIds.length > 0 ) ) {
			
			// For now, we ONLY support EITHER sku-based (tacdorp) or product/cat based (prodcat) query
            // CHANGE FOR PERLGEM API IS IN PROGRESS
			if ( this.skuIds.length > 0 ) {
				// Make a sku-based query (tacdorp)
				this.prodcatMethod = g_tacdorpMethod;
				this.queryParams = $A(g_tacdorpQueryParams).clone();
				this.queryParams[0]["skus"] = this.skuIds.toArray();
                this.queryParams[0]["get_product"] = 1;
                this.queryParams[0]["get_category"] = 1;
			} else {
				// Make a prodcat query
				this.prodcatMethod = g_prodcatMethod;
				this.queryParams = $A(g_prodcatQueryParams).clone();
				
				if ( this.productIds.length > 0 ) {
					this.queryParams[0]["products"] = this.productIds.toArray();
				}
				if ( this.categoryIds.length > 0 ) {
					this.queryParams[0]["categories"] = this.categoryIds.toArray();
				}
			}
			
	        generic.jsonrpc.fetch({
	            method: "prodcat",
	            params: this.queryParams,
	            onSuccess: this.callbackMultiBox.bind(this),
	            onError: function (jsonRpcResponse) {
	                console.log("prodcat fail");
	                console.log(jsonRpcResponse);
	                //args.callback(jsonRpcResponse.getError());
	            }
	        });
			
		}
	},
	
	callbackMultiBox: function(jsonRpcResponse) {
		
		var responseData = jsonRpcResponse.getValue();
	    var prods = [];
	    var productPageArgs = {
	        containerID: "",
	        maxItems: this.maxProducts,
	        startIndex: 0,
	        cellsPerRow: 1,
	        mode: 0,
	        productImages: []
	    };

	    // Did user ask for specific skus?
		if ( this.skuIds.length > 0 ) {
			
			// Make sure response actually has something to look at.
			if ( responseData.skus && responseData.products ) {
				
				// This is a little messy.
				// The data for the requested skus comes in a separate array from the products.
				// But the products list has ALL the skus for that products, not just the ones we requested.
				// So... Here's what we need to do:
				//  - Loop thru the sku id's that the user requested.
				//  - Look up the product id for each sku and find the returned product object.
				//  - Reset the product object's sku list with only the sku data we have.
				//  - Add that resulting product object to our "prods" list.

				// Need to do this in the user's requested order.
				this.skuIds.each(function(skuid){
					
					// Get sku object from the response
					var responseSkuObj = responseData.skus.find(function(rsku){
						return rsku.SKU_ID == skuid;
					});
					
					if ( responseSkuObj ) {
						// Did we create this product already?
						var tprod = $A(prods).find(function(lprod){
							return lprod.PRODUCT_ID == responseSkuObj.PRODUCT_ID;
						});
						
						if ( tprod ) {
							// Just add this sku to the product's sku list
							tprod.skus.push(responseSkuObj);
						}
						else {
							// Haven't see this prod.  Look it up in the response object
							var responseProdObj = responseData.products.find(function(rprod){
								return rprod.PRODUCT_ID == responseSkuObj.PRODUCT_ID;
							});
							
							// Null the product's sku list and start over.
							responseProdObj.skus = [];
							responseProdObj.skus[0] = responseSkuObj;
							prods[prods.length] = responseProdObj;
						}
					}
					
				}, this);
			}
			else {
	            console.log("productmpbox: requested skuids not returned");
			}
		} 
		else {
			// User must have asked for products or categories...
			
	    	// If products were given but no categories, then pull the prods
	    	// in the order listed.  Otherwise, just pull them all and the
	    	// display-order will take precedence.
	    	if ( this.productIds.length > 0 && !this.categoryIds.length ) {
	    		
	    		// Make sure we got data back
	    		if ( responseData.products ) {
	    			this.productIds.each(function(prodid){
	    			
                    	var tprod = responseData.products.find( function(product) {
                        	return product.PRODUCT_ID == prodid;
                    	});
	    				if ( tprod ) prods[prods.length] = tprod;

	    			}, this);
	    		}
	    		else {
	            	console.log("productmpbox: requested product ids not returned");
	    		}
	    		
	    	} 
	    	else {
	    		// Just load up whatever we got back

	    		if ( responseData.categories ) {
	    			$A(responseData.categories).each(function(catData){
	    				$A(catData.products).each(function(prodData){
	    					if ( prodData ) prods.push(prodData);
	    				}, this);
	    			}, this);
	    		}
	    		else	    		
	    		if ( responseData.products ) {
					$A(responseData.products).each(function(prodData){
						if ( prodData ) prods.push(prodData);
					}, this);
				}
	    	}
		}
	    
	    productPageArgs.containerID = this.containerId;
	    productPageArgs.tableData = prods;
	    productPageArgs.cellsPerRow = this.productsPerRow;
	    productPageArgs.mode = this.mode;
	    productPageArgs.productImages = this.productImages;
        productPageArgs.quickshopImage = this.quickshopImage;
        productPageArgs.productImageStyle = this.productImageStyle;

		// Optional notification that data is loaded but not yet displayed.
		// (Requested by coremetrics)
		this.callbackDataLoaded(prods);

	    var myTable =
	    	( this.mode == 0 ? new productPage.miniThumbTable(productPageArgs) :
	    	  this.mode == 1 ? new productPage.ProductsTable(productPageArgs) :
	    	  				   new productPage.ProductsTable(productPageArgs) );

		// Fire callback.
		this.callbackCompleted(prods);
	}
});


