
 
if(typeof(CNET) == "undefined")
	CNET = {};
CNET.Comparison = Class.create();

Object.extend(CNET.Comparison.prototype,{
    ACROSS_ALL_PRODUCTS : 0,
    AGAINST_REFERENCE_PRODUCT : 1, 
    compareMode : null,
    jsonCompareData: null,
    cookieManager: null,
                                       
	initialize: function(container,options){
		this.container = $(container);
		this.options = $H({explainOnFirstUsage  : true,
		                   servletURL           : "../SearchResults",
		                   language             : null,
		                   compareMode          : null});
		if(options)
			for(o in options)
				this.options[o] = options[o];
				
		this.cookieManager = new CookieManager();
		},


    // Adds a product to the compare list but only after its category has been retrieved. This behavior is
    // needed to ensure that products in the list are in the same category (CNET or subset of CNET).
    // This method is much slower than addProduct(prodID, categoryID) and should only be used when there is no
    // way to know what the product's category is.
    addProductWithoutCategory: function(_prodID, _IncGST, _ShowInc, _ExGST, _ShowEx, _ItemID) {
            var prod=encodeURIComponent(_prodID);
  		var ajaxRequest = new Ajax.Request();
		    ajaxRequest.setOptions (
		    {method: 'get',
		          parameters: "&lang="+this.options.language+"&what=productcategory&format=JSON&prodid="+prod,                    
		          onSuccess: (function (req) { this.addProductWithoutCategoryCallback(req.responseText, _IncGST, _ShowInc, _ExGST, _ShowEx, _ItemID);}).bind(this)
		          });
  
  	        ajaxRequest.request(this.options.servletURL);
    },
    
    addProductWithoutCategoryCallback: function(response, _IncGST, _ShowInc, _ExGST, _ShowEx, _ItemID)
    {
          eval("var productCategory = "+response);
          var product = productCategory.product;
          var category = productCategory.category;

          if(category=="UNKNOWN") {
               alert("Sorry - this product has no comparable data");
               $(decodeURIComponent(product)).checked = false;
          } else {
             this.addProductWithCategory(product,category, _IncGST, _ShowInc, _ExGST, _ShowEx, _ItemID);
        }  
    },
    
    
    addProductWithCategory: function(_prodID, _categoryID, _IncGST, _ShowInc, _ExGST, _ShowEx, _ItemID) {
    
            var storedCompareInfo = this.cookieManager.getCookie('CNETCompareInfo');
            var jsonedCompareInfo = null;
            if(storedCompareInfo==null) 
            {
               jsonedCompareInfo = {category: _categoryID, products: [_prodID], incGST: [_IncGST], showInc: [_ShowInc], exGST: [_ExGST], showEx: [_ShowEx], itemID: [_ItemID]};
            } else
            {
                try {
                  jsonedCompareInfo = storedCompareInfo.evalJSON(true); 
                } catch (e) 
                { jsonedCompareInfo = {category: _categoryID, products: [_prodID], incGST: [_IncGST], showInc: [_ShowInc], exGST: [_ExGST], showEx: [_ShowEx], itemID: [_ItemID]};
                }

                // if a switch to a new category has happened, wipe out the products list and 
                // reset the category:
                
                if(_categoryID != jsonedCompareInfo.category)
                {
                   jsonedCompareInfo.products.each(function(p) { try { $(p).checked = false;} catch (e) {}});
                   jsonedCompareInfo.category = _categoryID;
                   jsonedCompareInfo.products = [_prodID];
                   jsonedCompareInfo.incGST = [_IncGST];
                   jsonedCompareInfo.showInc = [_ShowInc];
                   jsonedCompareInfo.exGST = [_ExGST];
                   jsonedCompareInfo.showEx = [_ShowEx];
                   jsonedCompareInfo.itemID = [_ItemID];
                } else
                {
                   if(jsonedCompareInfo.products.indexOf(_prodID) == -1) {
                          jsonedCompareInfo.products[jsonedCompareInfo.products.length] = _prodID;
                          jsonedCompareInfo.incGST[jsonedCompareInfo.products.length] = _IncGST;
                           jsonedCompareInfo.showInc[jsonedCompareInfo.products.length] = _ShowInc;
                           jsonedCompareInfo.exGST[jsonedCompareInfo.products.length] = _ExGST;
                           jsonedCompareInfo.showEx[jsonedCompareInfo.products.length] = _ShowEx;
                           jsonedCompareInfo.itemID[jsonedCompareInfo.products.length] = _ItemID;
                      }
                }
            }
            this.cookieManager.setCookie('CNETCompareInfo', Object.toJSON(jsonedCompareInfo), 0);
       },
    
    removeProduct: function(_prodID)
    {
        var storedCompareInfo = this.cookieManager.getCookie('CNETCompareInfo');
        var jsonedCompareInfo = null;
        try {
              jsonedCompareInfo = storedCompareInfo.evalJSON(true); 
              if(jsonedCompareInfo.products.indexOf(_prodID) != -1) 
              {
                 for(k=0;k<jsonedCompareInfo.products.length;k++)
                {
                    if (jsonedCompareInfo.products[k]==_prodID)
                    {
                        jsonedCompareInfo.incGST = jsonedCompareInfo.incGST.without(jsonedCompareInfo.incGST[k]);
                        jsonedCompareInfo.showInc = jsonedCompareInfo.showInc.without(jsonedCompareInfo.showInc[k]);
                        jsonedCompareInfo.exGST = jsonedCompareInfo.exGST.without(jsonedCompareInfo.exGST[k]);
                        jsonedCompareInfo.showEx = jsonedCompareInfo.showEx.without(jsonedCompareInfo.showEx[k]);
                        jsonedCompareInfo.itemID = jsonedCompareInfo.itemID.without(jsonedCompareInfo.itemID[k]);
                        break;
                    }
                }
                 jsonedCompareInfo.products = jsonedCompareInfo.products.without(_prodID);
                 
                 this.cookieManager.setCookie('CNETCompareInfo', Object.toJSON(jsonedCompareInfo), 0);
              }
            } catch (e) {window.alert(e);}    
    },
    
    
    removeProductFromJSON: function(_prodID)
    {
       var productArray = new Array();
       for(i=0;i<this.jsonCompareData.Products.length;i++)
       {
          if(this.jsonCompareData.Products[i].ProdID != _prodID)
            productArray.push(this.jsonCompareData.Products[i]);
       }
       this.jsonCompareData.Products = productArray;
       
    },
    
    removeProductFromDisplayedTable: function(_prodID)
    {
        var unescapedProdID = decodeURIComponent(_prodID);
           try {
              this.removeProduct(unescapedProdID);
              this.removeProductFromJSON(_prodID);
              $(unescapedProdID).checked = false;
              this.redrawTable();
            } catch (e) {}    
    },
    
    getProductList: function()
    {
       var storedCompareInfo = this.cookieManager.getCookie('CNETCompareInfo');
       var jsonedCompareInfo = null;
       var result = "";
       
       try {
              jsonedCompareInfo = storedCompareInfo.evalJSON(true); 
              for(i=0;i<jsonedCompareInfo.products.length;i++)
                result += "'"+encodeURIComponent(jsonedCompareInfo.products[i])+"'"+ ((i==jsonedCompareInfo.products.length-1)?"":",");             
            } catch (e) {alert(e)}   
       return result; 
    },
    
    getSearchComparison: function()
     {
        var productList = this.getProductList();
       
	    if(productList == null || this.options.language == null) 
	    {
	       throw (new exception("Please set prodids/language before calling CNETSearchResults.getSearchComparison()"));
	    } 
	    else 
	    {
		    var ajaxRequest = new Ajax.Request();
		    ajaxRequest.setOptions (
		    {method: 'get',
		          parameters: "&lang="+this.options.language+"&what=searchcomparison&format=JSON&prodids=("+productList+")",                    
		          onSuccess: (function (req) { this.getSearchComparisonCallback(req.responseText);}).bind(this)
		          });
  
  	        
  	        ajaxRequest.request(this.options.servletURL);
        }
      },
                
    getSearchComparisonCallback: function(response) 
      {
           eval("this.jsonCompareData = "+response);
           this.redrawTable();
      },
      
    
    redrawTable: function()
     { 
        var tableElement= this.buildTable(this.jsonCompareData);
        removeAllChildren($('compareTable'));
        $('compareTable').appendChild(tableElement);
        $('compareTableBackground').setStyle({opacity: 0.99}).show();
     },
   
      
   buildTable: function(data)
   {
   
   var storedCompareInfo = this.cookieManager.getCookie('CNETCompareInfo');
    var jsonedCompareInfo = null;
    
    jsonedCompareInfo = storedCompareInfo.evalJSON(true);
    
    var table = document.createElement('table');
    table.className='sortable';
    table.width='100%';
    table.height='100%';
    
    var tbody = document.createElement('tbody');
    
    var arrFields = new Array('Remove','Image','Manufacturer','Title','PartNumber');
    var arrFormat = new Array('chkbox','img','text','text','text');
                
    //START | Create rows, which info do wish wish to display
    for(k=0;k<jsonedCompareInfo.products.length;k++)
    {
        if (jsonedCompareInfo.showEx[k]!=undefined)
        {
            if (jsonedCompareInfo.showEx[k]=='True' && jsonedCompareInfo.showInc[k]=='True')
            {
                var arrFields = new Array('Remove','Image','Price Ex GST','Price Inc GST','Manufacturer','Title','PartNumber');
                var arrFormat = new Array('chkbox','img','PriceEx','PriceInc','text','text','text');
            }
            else if (jsonedCompareInfo.showEx[k]=='True')
            {
                var arrFields = new Array('Remove','Image','Price Ex GST','Manufacturer','Title','PartNumber');
                var arrFormat = new Array('chkbox','img','PriceEx','text','text','text');
            }
            else if (jsonedCompareInfo.showInc[k]=='True')
            {
                var arrFields = new Array('Remove','Image','Price Inc GST','Manufacturer','Title','PartNumber');
                var arrFormat = new Array('chkbox','img','PriceInc','text','text','text');
            }
            break;
        }
    }
    //START | HEADER
    for(var j=0; j<arrFields.length; j++)
    {
        //Start a new row.
        var tr = document.createElement('tr');
            
        //start | Header
        for(var i=0; i<data.Products.length; i++ )
        {
           
            //First product display row header
            if (i==0)
            {
                var td = document.createElement('td');
                if (arrFormat[j] != 'img' && arrFormat[j] != 'chkbox')
                {
                    td.innerHTML=unescape(arrFields[j]);
                }
                tr.appendChild(td);
            }
            
            
            var td = document.createElement('td');
    
            switch(arrFormat[j])
            {
            case 'img':
                var tmplink = document.createElement('a');
                for(k=0;k<jsonedCompareInfo.products.length;k++)
                {
                    if (jsonedCompareInfo.products[k]==data.Products[i].ProdID)
                    {
                        tmplink.setAttribute('href','../browse/'+jsonedCompareInfo.itemID[k]+'001ItemDetail.aspx');
                        break;
                    }
                }
                tmplink.setAttribute('target','_self');
                tmplink.setAttribute('title',data.Products[i].ProdID);
                tmplink.setAttribute('border','0');
                var tmpimg = document.createElement('img');
                tmpimg.src = data.Products[i][arrFields[j]];
                tmpimg.setAttribute('border','0');
                tmplink.appendChild(tmpimg);
                td.appendChild(tmplink);
                td.align="center";
                tr.appendChild(td);
                break    
            case 'chkbox':
                var tmpchkbox = document.createElement("input");
                tmpchkbox.setAttribute("type","checkbox"); 
                tmpchkbox.setAttribute("id", "chk" + data.Products[i].ProdID); 
                tmpchkbox.setAttribute("value", data.Products[i].ProdID); 
                tmpchkbox.defaultChecked = true; 
                tmpchkbox.disabled = (data.Products.length == 1);
                tmpchkbox.onclick =  new Function("compare.removeProductFromDisplayedTable('" + data.Products[i].ProdID + "');compare.getSearchComparison();");
                td.appendChild(tmpchkbox);
                td.align="center";
                tr.appendChild(td);
                break
            case 'PriceEx':
                //if (jsonedCompareInfo.showEx[i]=='True'){
                    for(k=0;k<jsonedCompareInfo.products.length;k++)
                    {
                        if (jsonedCompareInfo.products[k]==data.Products[i].ProdID)
                        {
                            td.innerHTML=unescape('$'+jsonedCompareInfo.exGST[k]);
                            td.align="left";
                            tr.appendChild(td);
                            break;
                        }
                    }
                //}
                break    
            case 'PriceInc':
                //if (jsonedCompareInfo.showInc[i]=='True'){
                    for(k=0;k<jsonedCompareInfo.products.length;k++)
                    {
                        if (jsonedCompareInfo.products[k]==data.Products[i].ProdID)
                        {
                            td.innerHTML=unescape('$'+jsonedCompareInfo.incGST[k]);
                            td.align="left";
                            tr.appendChild(td);
                        }
                    }
                //}
                break       
            default:
                td.innerHTML=unescape(data.Products[i][arrFields[j]]);
                td.align="left";
                tr.appendChild(td);
                break
            }               
            //set align
            
        }
        if (arrFormat[j] != 'img' && arrFormat[j] != 'chkbox')
        {
            tr.className = "compareHeader";
        }
        tbody.appendChild(tr);
    }
    
       
        
        //Need to work out which Product has the most attributes and start with this one
        var iStartProdPos = 0;
        
        var numberOfAttributes = data.Products[0].Attributes.length;
        var currentSection = null; // name of current section
        var currentSectionID = 0;  // number of sections displayed so far; used to refrain from "differentiating" the first section (Header)
                        
        //Next create array of ProdPosition starting with Prod with Max Attributes
        for(var iAtt=0; iAtt<numberOfAttributes; iAtt++ )
        {
           // if we are in a new attribute section, display a new section row 
           var section_attribute = unescape(data.Products[0].Attributes[iAtt]['AtrName']).split("/");
           
           if(section_attribute[0] != currentSection) 
           {
              currentSection = section_attribute[0];
              currentSectionID++;
              var tr = document.createElement('tr');
              var td = document.createElement('td');
              td.colSpan = data.Products[iStartProdPos].Attributes.length+1;
              td.className = "compareSectionHeader";
              td.innerHTML=currentSection;
              tr.appendChild(td);
              tbody.appendChild(tr);
           }
           
           var differenceHighlightingBitset = this.getDifferenceHighlightingBitset(iAtt, data.Products);
           
           for(var iProd=0; iProd<data.Products.length; iProd++ )
           {
                if (iProd==0)
                {
                   //Start a new row.
                   var tr = document.createElement('tr');
                   var td = document.createElement('th');
                   td.innerHTML=unescape(section_attribute[1]);
                   td.className = "compareAttributeName";
                   tr.appendChild(td);
                }
            
                 var td = document.createElement('td');
                 td.innerHTML=unescape(data.Products[iProd].Attributes[iAtt]['AtrValue']);
                 td.align="center";
                 td.className = differenceHighlightingBitset.pop()?"compareDifferent":"compareIdentical";
                 tr.appendChild(td);
           }
        
           tr.className = (iAtt % 2 == 1)?"compareEvenRow":"compareOddRow";
           tr.height = "30px"
            
           tbody.appendChild(tr);   
            
        }
        
    table.appendChild(tbody);
    table.id="table_" + Math.floor ( Math.random ( ) * 100 );
    
    return table;
 },

 getDifferenceHighlightingBitset: function(iAtt, products)
 {
    var bitset = new Array();
    var seenADifference = false;
    var attributeValue = null;
    if(this.options.compareMode == CNET.Comparison.prototype.ACROSS_ALL_PRODUCTS) 
    {
       for (p=0; p<products.length;p++)
       {
          if(p==0)
             attributeValue = products[p].Attributes[iAtt]['AtrValue'];
          seenADifference = seenADifference?seenADifference:(products[p].Attributes[iAtt]['AtrValue'] != attributeValue);
       }
       
       // set the same bit for all products
       for(p=0;p<products.length;p++)
           bitset.push(seenADifference);
   } else
   {
     for (p=0; p<products.length;p++)
       {
          if(p==0)
             attributeValue = products[p].Attributes[iAtt]['AtrValue'];
          seenADifference = seenADifference?seenADifference:(products[p].Attributes[iAtt]['AtrValue'] != attributeValue);
          bitset.push(seenADifference);
       }
   }

   return bitset.reverse(); // reversed because it will be consumed starting with the first product
}
});