/**
 * UI scripting for product pages (see /v2/apps/frontend/modules/product)
 *
 * P.S. INTERTUBE HACKERS THIS C0D3 IS COPYRIGHT SO DON'T MAKE ME GET OUT THE LAWYERBOT OK
 * 
 * $Id$
 */

// $H is shorthand for: new Hash()
// for more info on Hashes, see http://www.prototypejs.org/api/hash
prodImages = $H();
prodSizes = $H();
prodImageLoadStatus = $H();

function prodSetImages(json)
{
  prodImages = $H(json);
}

function prodSetSizes(sizes)
{
  prodSizes = $H(sizes);
}

function prodUpdatePicDisplay(colorCode, alt)
{
  if (typeof alt == 'undefined')
  {
    var selectedThumb = $('thumb~'+colorCode+'~main');
    var imageCollection = $H($H(prodImages.get(colorCode)).get('main'));
    var imageDesc = $H(prodImages.get(colorCode)).get('color_name');
  }
  else
  {
    var selectedThumb = $('thumb~'+colorCode+'~'+alt.replace(/\s/g, '_'));
    var imageCollection = $H($H($H(prodImages.get(colorCode)).get('alt')).get(alt));
    var imageDesc = $H(prodImages.get(colorCode)).get('color_name')+': '+alt;
  }

  // if this thumb is already selected, no need to do anything
  if (typeof selectedThumb != 'undefined' && selectedThumb.className == 'thumb_selected')
  {
    return;
  }

  // reset any selected thumbs to unselected state
  thumbs = $$('img.thumb_selected');
  for (var i = 0; i < thumbs.length; i++)
  {
    thumbs[i].className = 'thumb';
  }

  // set newly selected thumb to selected state
  selectedThumb.className = 'thumb_selected';

  // hide legacy image, show new image
  $('photo_legacy_img').hide();
  $('photo_medium_img').show();

  // show 'loading' spinner
  prodShowMediumLoader(imageCollection.get('medium'));

  // update main product picture
  $('photo_medium_img').src = imageCollection.get('medium');

  // update main product picture description
  $('pic_desc').innerHTML = imageDesc;

  // update link from main product picture
  $('photo_large_link').href = imageCollection.get('large');
  $('photo_large_link').title = selectedThumb.parentNode.title;

  // meow
  $('help_cat').innerHTML = 'Click to zoom';
}

function prodUpdatePicDisplayLegacy(type)
{
  if (type == 'sale')
  {
    // if the image doesn't exist, stop
    if (typeof prodImageLegacySale == 'undefined')
    {
      return;
    }

    var selectedThumb = $('thumb~legacy~sale');
    var mediumHref = prodImageLegacySale;
  }
  else
  {
    // if the image doesn't exist, stop
    if (typeof prodImageLegacyCurrent == 'undefined')
    {
      return;
    }

    var selectedThumb = $('thumb~legacy~current');
    var mediumHref = prodImageLegacyCurrent;
  }

  // if this thumb is already selected, no need to do anything
  if (selectedThumb.className == 'thumb_selected')
  {
    return;
  }

  // reset any selected thumbs to unselected state
  thumbs = $$('img.thumb_selected');
  for (var i = 0; i < thumbs.length; i++)
  {
    thumbs[i].className = 'thumb';
  }

  // set newly selected thumb to selected state
  selectedThumb.className = 'thumb_selected';

  // hide legacy image, show new image
  $('photo_medium_img').hide();
  $('photo_legacy_img').show();

  // show 'loading' spinner
  prodShowMediumLoader(mediumHref);

  // update main product picture
  $('photo_legacy_img').src = mediumHref;

  // update main product picture description
  $('pic_desc').innerHTML = 'Other views';

  // can't touch this
  $('help_cat').innerHTML = 'Zoom unavailable';
}

function prodShowMediumLoader(img_src)
{
  if (typeof loadingFadeEffect != 'undefined')
  {
    loadingFadeEffect.cancel();
    delete loadingFadeEffect;
  }

  // only show loader if the image has not yet completed loading
  if (typeof prodImageLoadStatus.get(img_src) == 'undefined')
  {
    loadingAppearEffect = new Effect.Appear('photo_medium_loading', { duration: 0.5 });
  }
}

function prodHideMediumLoader()
{
  if (typeof loadingAppearEffect != 'undefined')
  {
    loadingAppearEffect.cancel();
    delete loadingAppearEffect;
  }

  //loadingFadeEffect = new Effect.Fade('photo_medium_loading', { duration: 0.25 });
  $('photo_medium_loading').hide();
}

/**
 * update height of container div so it will never again be smaller than the current image
 * (prevents text from appearing to jump around the page)
 * this is called via onLoad on photo_medium_img
 */
function prodUpdatePicContainer()
{
  if (typeof $('photo_medium_img_container').style.height == 'undefined' || $('photo_medium_img_container').style.height.replace(/px/i,"") < $('photo_medium_img').height)
  {
    new Effect.Morph('photo_medium_img_container', { style: 'height: '+$('photo_medium_img').height+'px', duration: 0.5});
  }
  else if (typeof $('photo_medium_img_container').style.height == 'undefined' || $('photo_medium_img_container').style.height.replace(/px/i,"") < $('photo_legacy_img').height)
  {
    new Effect.Morph('photo_medium_img_container', { style: 'height: '+$('photo_legacy_img').height+'px', duration: 0.5});
  }
}

function prodUpdateAttr1Select(attr1)
{
  if ($('attr_1_select') == undefined)
  {
    return;
  }

  var select = $('attr_1_select');

  // only proceed if this option isn't already selected
  if (attr1 != select.value)
  {
    // find the correct list option and select it
    for (var i = 0; i < select.options.length; i++) {
      if (select.options[i].value == attr1) {
        select.options[i].selected = true;
        break;
      }
    }

    // update attribute 2 drop-down
    prodPopulateAttr2Select(attr1);

    // if there is an existing highlight animation in progress, stop and reset it
    if (typeof highlightEffect != 'undefined')
    {
      highlightEffect.cancel();
      $('add2cart').style.backgroundColor = '#eaf7ff';
    }

    // highlight animation to let the user know content in the box has changed
    highlightEffect = new Effect.Highlight('add2cart', { startcolor: '#bbe6ff', restorecolor: '#eaf7ff' });
  }
}

function prodPopulateAttr2Select(attr1)
{
  if ($('attr_2_select') == undefined)
  {
    return;
  }

  // iterate through each color group in prodSizes.
  prodSizes.each(
    function(pair)
    {
      // once the correct color is found...
      if (pair.key == attr1)
      {
        var select = $('attr_2_select');

        // preserve originally selected size
        var orig_size = select.value;

        var i = 1;

        // remove any existing options from the select
        select.length = 1;

        // iterate through each size
        $H(pair.value).each(
          function(pair2)
          {
            // add the size option to the select
            select.options[i] = new Option(pair2.value, pair2.key);

            // restore originally selected size if possible
            if (orig_size == pair2.key)
            {
              select.options[i].selected = true;
            }

            i++;
          }
        );

      }
    }
  );
}

prodThumbEvent = {

    timeoutObj : null,
    timeoutLength : 200, /* milliseconds */

    handleMouseOver : function(colorCode, desc)
    {
      clearTimeout(this.timeoutObj);
      this.timeoutObj = setTimeout(function()
        {
          prodUpdatePicDisplay(colorCode, desc);
          prodUpdateAttr1Select(colorCode);
        },
      this.timeoutLength);
    },

    handleMouseOverLegacy : function(type)
    {
      clearTimeout(this.timeoutObj);
      this.timeoutObj = setTimeout(function()
        {
          prodUpdatePicDisplayLegacy(type);
        },
      this.timeoutLength);
    },

    handleMouseOut : function()
    {
      clearTimeout(this.timeoutObj);
    }    
}

function prodHandleAttr1SelectChange(newValue)
{
  prodPopulateAttr2Select(newValue);

  if ($H(prodImages.get(newValue)).get('main'))
  {
    prodUpdatePicDisplay(newValue);
  }
  else if ($H(prodImages.get(newValue)).get('legacy') == 'sale')
  {
    prodUpdatePicDisplayLegacy('sale');
  }
  else
  {
    prodUpdatePicDisplayLegacy('current');
  }
}

function prodHandleMediumImageDoneLoading(img_src)
{
  // remember that this image has finished loading, so we don't need to show a loader again
  // strip off the domain to make a relative URL
  prodImageLoadStatus.set(img_src.replace(/https?:\/\/[a-z\-.]+/, ''), true);

  prodUpdatePicContainer();
  prodHideMediumLoader();
}

function prodHandleCartBeginLoading()
{
  addthis_close();
  if (BrowserDetect.browser == 'Explorer')
  {
    $('minicart').show();
  }
  else
  {
    new Effect.Appear('minicart', { duration: 0.5 });
  }

  $('minicart_content').hide();
  $('minicart_loader').show();
}

function prodHandleCartDoneLoading()
{
  $('minicart_loader').hide();
  $('minicart_content').show();
  cartStatus.refresh();
}

function prodMiniCartClose()
{
  if (BrowserDetect.browser == 'Explorer')
  {
    $('minicart').hide();
  }
  else
  {
    new Effect.Fade('minicart', { duration: 0.5 });
  }
}

function prodTabBeforeChange(old_container, new_container)
{
  if (old_container.offsetHeight > 0)
  {
    // save old height for animation
    product_tab_last_height = old_container.offsetHeight;
  }
}

function prodTabShow(new_container)
{
  // is this a transition?
  if (typeof product_tab_last_height != 'undefined')
  {
    // need to show() the element (removes 'display: none') and hide it via some other means, for two reasons:
    // 1. can only get the height if it's actually rendered
    // 2. Effect.Morph() won't work unless it's actually rendered
    new_container.setOpacity(0);
    Element.show(new_container);

    // save new height
    new_height = new_container.offsetHeight;

    // start from old height
    new_container.style.height = product_tab_last_height+'px';

    // animate resizing to new height
    new Effect.Morph(new_container, {
      style: { height: new_height+'px' },
      duration: 0.5,
      queue: { position: 'front', scope: 'tabchange' }
    });

    // fade in contents
    new Effect.Opacity(new_container, {
      from: 0, to: 1,
      duration: 0.5,
      queue: { position: 'end', scope: 'tabchange' }
    });
  }
  // this is the first tab that's ever been shown - no transition.
  else
  {
    Element.show(new_container);
  }
}


/**
 * Utilities
 */

// from http://snippets.dzone.com/posts/show/89
function isImageDoneLoading(img) {
    // During the onload event, IE correctly identifies any images
    // that weren't downloaded as not complete. Others should too.
    // Gecko-based browsers act like NS4 in that they report this
    // incorrectly: they always return true.
    if (!img.complete) {
        return false;
    }

    // However, they do have two very useful properties: naturalWidth
    // and naturalHeight. These give the true size of the image. If
    // it failed to load, either of these should be zero.
    if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
        return false;
    }

    // No other way of checking: assume it's ok.
    return true;
}
