/**
 * Library with functions to set up and handle the product refine pages.
 *
 * Version 0.9 (21/03/2009)
 * @requires jQuery v1.2.6 or later
 * Copyright (c) 2008-2009 <GX> Creative Online Development
 *
 * Known issues:
 *	-
 *
 */

var sortRemember = '';
var selectedProducts = new Array();
var general_refine_tooltip_maxcompare_alert = 'Max is 3.';
var totalCount = 0;
var documentUrl = new QueryStringBuilder();
setUpQueryStringBuilder();
	
function showAmount(amount){
  totalCount = amount;
}

function buildViewAreaSearch(imagePath, numberOfSearchResultsFoundText, showAllFoundProductsText) {
  if (totalCount == 0) {
  	totalCount = applicationData.prdproducts.prdproduct.length;
  }

  $(".pager").append('<p><strong>' + applicationData.prdproducts.prdproduct.length +
     '</strong>&nbsp;' +  numberOfSearchResultsFoundText + ':</p>');

  buildViewArea(imagePath, true, true);
  
  if (totalCount == 2 && applicationData.prdproducts.prdproduct.length > totalCount) {
    $("div.pager").append('<p><a href="/" onclick="document.location.href = document.location.href + \'&showProd=all\';' +
  	' return false;">' + showAllFoundProductsText + '</a></p>');
  }
}

function buildViewArea(imagePath, isSearchResult, hideCompare, shopLink, buyText, overlayLink, overlayText) {

  var l = applicationData.prdproducts.prdproduct.length;
  
  // Use an array to increase performance(this increases the performance dramatically in IE)
  var html = new Array(l);

  // Use 'for'-loop instead of the JQuery '$.each'. Should increase performance (However it does
  // not seem to help much)
  for (q=0; q < l; q++) {
    var productDiv = new Array();

    if (!isSearchResult || (isSearchResult && q < totalCount)) {
      productid = applicationData.prdproducts.prdproduct[q]['id'];
      productcode = applicationData.prdproducts.prdproduct[q]['code'];
      productname = applicationData.prdproducts.prdproduct[q]['name'];
      productimage = applicationData.prdproducts.prdproduct[q]['image1'];
      
      if (productimage == '') {
      	  productimage = applicationData.prdproducts.prdproduct[q]['image'];
      }

      if (productimage == '') {
      	  productimage = imagePath + '/globals/no-img.gif';
      }

      productdetaillink= applicationData.prdproducts.prdproduct[q]['detaillink'];
      properties = applicationData.prdproducts.prdproduct[q]['prdproperties'];

      productDiv.push('<div class="sort-column">');

      if (!isSearchResult&&!hideCompare) {
        productDiv.push('<fieldset>')
        productDiv.push('<input type="checkbox" id="check_' + productid + '" class="comparecheck check_' + productid + '" name="' + productname.replace("'", "''") + '" />');
        productDiv.push('</fieldset>');
      };

      productDiv.push('<span class="thumb-img">');
      if (shopLink === undefined) {
        productDiv.push('<a href="' + getProductDetailLink(productdetaillink) + '">');
      }
      productDiv.push('<img src="' + imagePath + 'globals/border-86x65.png" alt="" class="border-thumbs" />');
      productDiv.push('<img src="' + productimage +'" alt="" />');
      if (shopLink === undefined) {
        productDiv.push('</a>');
      }
      productDiv.push('</span>');
      if (shopLink === undefined) {
        productDiv.push('<h2><a href="' + getProductDetailLink(productdetaillink) + '" class="sorttitle">' + productname + '</a></h2>');
      } else {
        productDiv.push('<h2>' + productname + '</h2>');
      }
      productDiv.push('<dl>');

      $.each(properties, function(j,val) {
          if (j<=4) {
            propid = val.id;
            propname = val.name;
            propval = val.value;
            productDiv.push('<dd class="sortprop_' + propid + '">');
            productDiv.push('<em>' + propname + ':</em>'); 
            productDiv.push('<em>');
            if (propval=='No') {
              productDiv.push('-');
            } else {
              if (propval=='Yes') {
                productDiv.push('<span class="present">&nbsp;</span>');
              } else {
                productDiv.push(propval);
              }
            }
            productDiv.push('</em>');
            productDiv.push('</dd>');
          };
      });

      productDiv.push('</dl><dl>');

      // Double loop. Is not needed!
      $.each(properties, function(j,val) {
          if (j>4) {
            if (val) {
              propid = val.id;
              propname = val.name;
              propval = val.value;
              productDiv.push('<dd class="sortprop_' + propid + '">');
              productDiv.push('<em>' + propname + ':</em>'); 
              productDiv.push('<em>');
              if (propval=='No') {
                productDiv.push('-');
              } else {
                if (propval=='Yes') {
                  productDiv.push('<span class="present">&nbsp;</span>');
                } else {
                  productDiv.push(propval);
                }
              }
              productDiv.push('</em>');
              productDiv.push('</dd>'); 
            }
          }
      });

      // Create links for external shop integrators
      if (shopLink !== undefined) {
        var articleVariables = 'vogelsArticleID=' + escape(productid);
        articleVariables += '&vogelsArticleCode=' + escape(productcode);
        articleVariables += '&vogelsArticleName=' + escape(productname);
        productDiv.push('<dd class="buylink"><em>');
        productDiv.push('<a href="' + shopLink + articleVariables + '">' + buyText + '</a>');
        productDiv.push('</em></dd>');
        
        productDiv.push('<dd class="related_overlay"><em>');
        productDiv.push('<a href="' + overlayLink + '&dbid=' + productid + '" title="' + productname.replace('"', '&quot;') + '">' + overlayText + '</a>');
        productDiv.push('</em></dd>');
      }
      productDiv.push('</dl></div>');
      html[q] = productDiv.join('');
    }
  };

  // Wrap an extra div around the product divs. Should increase performance.
  $(".pager").append('<div>' + html.join('') + '<div>');

  // PNG fix for IE
  $('img[src$=.png],ul#sub-tabs li a, .home h2, ul#innerfade_list li.current a, ul#random_images li span, #random_images dt, .product-overview h2 a').ifixpng();

  // Bind click event to the compare boxes.
  $(".comparecheck").bind('click', function(e) {
    setSelectedProduct($(this).attr('class'), $(this).attr('name'));
  });

  // Bind click to uncheck all checkboxes.
  $(".deselect.").bind('click', function(e) {
    $('.comparecheck').attr('checked', false);
    $('dd.selectedproduct').remove();
    // Reset the selected products.
    selectedProducts = new Array();
  });
  
  // Bind external shop links
  $("dd.buylink a").bind('click', function(e) {
    window.opener.location.href = $(this).attr('href');
    window.close();
    e.preventDefault();
  });
  $("dd.related_overlay a").fancybox({
    'hideOnContentClick': false,
    'callbackOnShow': function() {
      $('#fancy_ajax .fragement .buyarticle_link').each(function() {
        var relatedVariables = 'vogelsArticleID=' + escape($(this).children("input[@name='articleid']").attr("value"));
        relatedVariables += '&vogelsArticleCode=' + escape($(this).children("input[@name='articlecode']").attr("value"));
        relatedVariables += '&vogelsArticleName=' + escape($(this).children("input[@name='articlename']").attr("value"));
        var a = $(this).children('a');
        a.text(buyText);
        a.attr('href', shopLink + relatedVariables);
        a.bind('click', function(e) {
          window.opener.location.href = shopLink + relatedVariables;
          window.close();
          e.preventDefault();
        });
      });
    }
  });

  setCheckboxes();
}

/**
 * Function to set the appropriate checkboxes for the product compare.
 */
function setCheckboxes() {
  // Reset the layover with the selected products.
  $('dd.selectedproduct').remove();

  // Set all the checkboxes to unchecked.
  $('.comparecheck').attr('checked', false);

  // Determine the number of selected products. The selected products are set in a global variable.
  var numberOfProducts = selectedProducts.length;
  var removeArray = [];

  // Set checkboxes to checked for the selected products. When using a refinement it can happen
  // the selected product is not in the scope anymore. We remove it from the 'selectedProducts'-array,
  // because they are not valid anymore.
  if (numberOfProducts > 0) {
    for (i=0;i<numberOfProducts;i++) {
      // Check whether the product is still in the scope.
      if ($('.check_' + selectedProducts[i]).length>0) {
        $('.check_' + selectedProducts[i]).attr('checked', true);
        $('.selectedproducts').append('<dd class="selectedproduct selectedproduct_' + selectedProducts[i] + '"><a href="#">' + $('.check_' + selectedProducts[i]).attr('name') + '</a></dd>');
      } else {
        // Add product to remove array when it is not in the scope anymore.
      	removeArray.push(selectedProducts[i]);
      }
    };
  }

  // Remove selected.
  for (j=0;j<removeArray.length;j++) {
    selectedProducts = $.grep(selectedProducts, function(val) { return val != removeArray[j]});
  }
}

function clearViewArea() {
  $("div.sort-column").remove();
}

function setupSort(options) {

  $('dl.sort-horizontal dd').each(function() {

    sortMethod = $(this).attr('id');
    $(this).bind('click', {'newMethod': sortMethod}, function(event) {

      var funcName = event.data['newMethod'];
      var funcParam = "";

      if ($(this).attr('class')=='sort-up') {
          funcParam = '\'asc\'';
          $('dl.sort-horizontal dd').removeClass('sort-up');
        $('dl.sort-horizontal dd').removeClass('sort-down');
          $(this).addClass('sort-down');
        } else {
        funcParam = '\'desc\'';
        $('dl.sort-horizontal dd').removeClass('sort-up');
        $('dl.sort-horizontal dd').removeClass('sort-down');
          $(this).addClass('sort-up');
        }

        if (funcName.indexOf('_')>-1) {
          funcNameParam = funcName.split('_');
        funcName = funcNameParam[0];
        funcParam = funcParam + ',' + funcNameParam[1];
      }

      //Create the function call from function name and parameter.
      var funcCall = funcName + "(" + funcParam + ");";

      //Call the function
      var ret = eval(funcCall);
      sortRemember = funcCall;

      // Keep the selected number of pages.
      numPerPages = $('dl.numberofpagesgroup').find('dd').find('a.current').filter(':first').text();

      if (numPerPages=='') {
        numPerPages = 8;
      }
      
      if (options) {
      	options.numPerPage = numPerPages;
      } else {
      	options = new Object();
	options.numPerPage = numPerPages;
      }
      $('div.pager').divPager(options);
    });
  })
}

function sort() {
  var options = {};

  // Default sort by title.
  if (sortRemember!='') {
    eval(sortRemember);
      // Setup the divPager with the selected number of pages.
      numPerPages = $('dl.numberofpagesgroup').find('dd').find('a.current').filter(':first').text();
    
      if (numPerPages=='') {
        numPerPages = 10;
      }
      options = {numPerPage: + numPerPages};
  } else {
    // Sort is done server side.
    //sortTitle('asc');
  }

  $('div.pager').divPager(options);
}

function pageBinder(options) {
	numPerPages = $('dl.numberofpagesgroup').find('dd').find('a.current').filter(':first').text();

	if (numPerPages=='') {
		numPerPages = 10;
	}
	options.numPerPage = numPerPages;
	$('div.pager').divPager(options);
}

function sortTitle(order) {
  options = {order: + order};
  $("div.sort-column").tsort("h2>a",{order:order});
}

function sortProp(order, propid) {
  // 'dl>dd.sortprop_' + propid
  selector = '.sortprop_' + propid;
  $("div.sort-column").tsort(selector,{order:order});
}

function showCompare(message, baseUrl) {
  if (selectedProducts.length>0) {

    var params;
    params = setupServletRequest();

    var serial = [];
    for (var name in params) {
    	// Filter out the typeofpage and dbid.
    	if (name != 'typeofpage' && name != 'dbid') {
    		serial.push(encodeURIComponent(name) + '=' + encodeURIComponent(params[name]));
    	}
    }
    serial.push('selectprods=' + selectedProducts.join(','));
    if (baseUrl.indexOf('?') >-1) {
      baseUrl = baseUrl + '&' + serial.join('&');
    } else {
      baseUrl = baseUrl + '?' + serial.join('&');
    }
    document.location = baseUrl;
  } else {
    alert(message);
  }
}

function setSelectedProduct(productValue, productName) {
  var productId = productValue.replace('comparecheck ', '').replace('check_', '');

  if ($.inArray(productId, selectedProducts) >-1) {
    var valueToRemove = productId;
    selectedProducts = $.grep(selectedProducts, function(val) { return val != valueToRemove; });
    $('.selectedproduct_' + productId).remove();
  } else {
    if (selectedProducts.length>=3) {
      alert(general_refine_tooltip_maxcompare_alert + '.');
      $('.check_' + productId).attr('checked', false);
    } else {
      selectedProducts.push(productId);
      $('.selectedproducts').append('<dd class="selectedproduct selectedproduct_' + productId + '"><a href="#">' + productName + '</a></dd>');
    }
  }
}

// selectedValueName : name of the global variable we store the selected in.
function buildRefineBlock(selectedValueName, dlId, allId, prefix, jsonPath, allLinkText, removeCriteriaText, noOptionsText, valueToShow, idIsValue, checkForDoubleValues) {
  // Only rebuild when the type is not yet selected or it was not build before(passed on from qs).
  if (eval(selectedValueName)=='' || ($('dl#' + dlId).find('dd').length==0)) {
    $('dl#' + dlId).find('dd').remove();

    // NOTE: does not need to be rebuild. Could find out other way for performance reasons.
    $('#' + allId).children().remove();
    $('dl#' + dlId).append('<dd><a href="#" class="selected' + dlId + 'Placeholder" style="display:none"></a></dd>');

    j = 0;
    e = 0;
    more = false;
    uniqueItemArray = new Array();
    var overlayArr = new Array();
      
    if (!eval(jsonPath) || eval(jsonPath)=='') {
      $('dl#' + dlId).append('<dd>' + noOptionsText + '</dd>');
    } else {
      $.each(eval(jsonPath),function(i,val) {
	// Get the id of the JSON object.
        objectid = val.id;

    	// Determine which property to show from the JSON object. It defaults to 'name'.
        if (valueToShow != '') {
          objectvalue = eval('val.' + valueToShow);
        } else {
          objectvalue = val.name;
        }

        // Only show unique items in the refine boxes.
        addItem = true;
        if (checkForDoubleValues) {
           if (contains(uniqueItemArray, objectvalue, 'value')) {
           	addItem = false;
           }
         }

        if (addItem) {
          // Create an object to store a 'id'/'value' combination.
          var idValue = new Object();
          idValue.value = objectvalue;

          // Check whether we need the value as identifier(for example used for 'size'-refinements
          // which do not have a separate id.)
          if (idIsValue) {
            idValue.id = objectvalue;
          } else {
            idValue.id = objectid;
          }
	  uniqueItemArray[e] = idValue;
	  e++;
        }
      });

      // Sort the items.
      uniqueItemArray.sort(compareObjects);
          
      var numberOfUniqueItems = uniqueItemArray.length;
      var numberInVisibleList = 6;
      var numberOfColumnsInOverlay = 5;
      var numberOfMoreItems = numberOfUniqueItems - numberInVisibleList;
      var numberOfItemsPerColumn = 0;
      
      if (numberOfMoreItems > 0) {
        numberOfItemsPerColumn = Math.round(numberOfMoreItems / numberOfColumnsInOverlay);	
        var overlayArr = new Array(numberOfMoreItems);
        if ((numberOfMoreItems % numberOfColumnsInOverlay) != 0) {
          numberOfItemsPerColumn++;
        }        
      }
      
      var itemInColumnCounter = 0;
      var opened = false;      
      
      for (j=0;j<numberOfUniqueItems;j++) {
        if (j < numberInVisibleList) {
	  $('dl#' + dlId).append('<dd><a href="#" class="' + dlId + 'click" id="'+ prefix+ '_' + (uniqueItemArray[j]['id']+'') + '">' + uniqueItemArray[j]['value'] + '</a></dd>');
        } else {
	  // Set the remaining ones.
	  more = true;
	  
	  if (itemInColumnCounter == 0) {
	    overlayArr.push('<ul class="alphabetic">');
	    var opened = true;      
          }
          
	  overlayArr.push('<li><a href="#" class="' + dlId + 'click" id="' + prefix + '_' + (uniqueItemArray[j]['id']+'') + '">' + uniqueItemArray[j]['value'] + '</a></li>');
	  itemInColumnCounter++;

	  if (itemInColumnCounter == numberOfItemsPerColumn) {
 	    itemInColumnCounter = 0;
 	    var opened = false; 
	    overlayArr.push('</ul>');
          }
        }
      }
      if (opened) {
        overlayArr.push('</ul>');
      }
      $('#' + allId).append(overlayArr.join(''));  
    }
        

    // Setup the more link when needed.
    if (more) {
      $('dl#' + dlId).append('<dd class="bullet-refine"><a href="#TB_inline?keepThis=true&amp;&inlineId=overlay' + allId + '&amp;height=430&amp;width=960" class="thickbox" id="' + allId + 'link">' + allLinkText + '</a></dd>');
      tb_init('a.thickbox, area.thickbox, input.thickbox');
    }

    $('.' + dlId + 'click').bind("click", function() {
      // Remove the lightbox when needed.
      tb_remove();
      var selValue = $(this).attr('id').split('_')[1];
      // Add the selected value to the querystring.   
      buildQuery(dlId, selValue);
     
      $(this).attr('href', documentUrl.GetFullString());

    });

    // When a value is selected it should be added to the criteria area.
    var selectedValue = eval(selectedValueName);
    
    if (selectedValue != '' ) {
    	setCriteria(selectedValueName, dlId, selectedValue, removeCriteriaText, prefix);
    }
  }
}

function getDocumentBaseUrl() {
  var locationBase = document.location + '';
  if (locationBase) {
  	locationBase = locationBase.replace("#","");
  }
  return locationBase;
}

function setCriteria(selectedValueName, dlId, selectedValue, removeCriteriaText, prefix) {

      $('dl#' + dlId).find('dd').children().not('.selected' + dlId + 'Placeholder').hide();

      // Set the selected in the placeholder.
      showSelector = 'a[id=' + prefix + '_' + selectedValue + ']';
      selectedText = $(showSelector).text();

      $('.selected' + dlId + 'Placeholder').text(selectedText);
      $('.selected' + dlId + 'Placeholder').show();

      // Add to the criteria area.
      $('#criterium').append('<dd id="producttypecriteria"><a href="#">' + selectedText + '</a><span><a href="#" class="remove' + dlId + '" title="' + removeCriteriaText + '">' + removeCriteriaText + '</a></span></dd>');

      // Add remove event on the criteria.
      $('.remove' + dlId).bind('click', function(e) {
          // Reset the global variable.
          eval(selectedValueName + ' = \'\'');

          deleteFromQuery(dlId);
      	  $(this).attr('href', documentUrl.GetFullString());
      });
}

// Some helper functions. move to the global package.
/**
 * Function to check an array for the existence of an object. An 'expr' is passed to
 * indicate the property which will be used to check the objects.
 *
 * @param a     Array with objects.
 * @param value The value that needs to be checked.
 * @param expr  Property of the objects that leeds to the value we need to compare with the 'value' parameter.
 *
 * @returns true or false. True when the array already contains the object. False when the array does not
 *            contain the object.
 */
function contains(a, value, expr) {
  var i = a.length;
  while (i--) {
    if (eval('a[i][\'' + expr + '\']') == value) {
      return true;
    }
  }
  return false;
}

/**
 * Function to compare two objects. It can be used to sort an array of objects. The
 * comparing is done on the 'value' property of the objects in the array.
 *
 * @param a Object 1 (must have a property 'value').
 * @param b Object 2 (must have a property 'value').
 *
 * @returns -1, 0 or 1.
 */
function compareObjects(a, b) {
  if (a['value'] < b['value']) {return -1};
  if (a['value'] > b['value']) {return 1};
  return 0;
}

/**
 *
 */
function QueryStringBuilder() {
  this.Url = '';
  this.Pairs = new Array();

  QueryStringBuilder.prototype.GetFullString = function() {
    var queryString = (this.Url.length > 0) ? this.Url + "?" : '';
    
    for(var key in this.Pairs) {
    	if (escape(this.Pairs[key]) != '') {
        	queryString += escape(key) + "=" + escape(this.Pairs[key]) + "&";
        }
    }
    
    return queryString.substring(0, queryString.length - 1);
  }
}

/**
 * Add value to the querystring object.
 */
function buildQuery(name,value) {
  documentUrl.Pairs[name] = value;
}

/**
 * Reset a value in the querystring object.
 */
function deleteFromQuery(name) {
  documentUrl.Pairs[name] = '';
}

/**
 * setUp the QueryStringBuilder with the initial values. (should be private)
 */
function setUpQueryStringBuilder() {
	
  var startUrl = getDocumentBaseUrl() + '';
  // Check whether the startUrl has already querystring parameters. If so add them to the
  // QueryStringBuilder.
  documentUrl.Url = startUrl.split('?')[0];

  if(typeof(startUrl.split( "?" )[1]) != "undefined"){
	qs = startUrl.split( "?" )[1].replace(/\+/g, ' ').split('&');
	$.each(qs, function(i){
		var currentArg = this.split('=');
		if(currentArg.length == 2) {
			buildQuery(unescape(currentArg[0]),unescape(currentArg[1]));
		}

	});
  }
}

function getProductDetailLink(detailLink) {
  var link = detailLink.replace("'", "''")
  
  if (documentUrl.Pairs['channel'] && documentUrl.Pairs['channel'] == 'iframe') {
    // Pass on the channel to the detaillink.
    if (link.indexOf('?') >-1) {
      link = link + '&channel=iframe';
    } else {
      link = link + '?channel=iframe';
    }	  
  }
  return link;
}
