/**
 * Product description.
 *
 * Requires Prototype 1.6.
 */

var SECS_FOR_CROSSFADE   = 0.5;
var gFetchExtraViewsPath = null;
var gFetchZoomPath       = null;

function bindAlerts() {
  var box = $('alertRequest'), sending = false;
  if (!box) return;
  
  $('addToCart').observe('click', function(e) {
    var trigger = e.findElement('a.alert');
    if (!trigger) return;
    e.stop(); trigger.blur();
    $('hidAlertPropertySetId').setValue($F('hidPropertySetId'));
    var propLabel = this.select('select').invoke('getValue').join(' - ');
    box.down('p.intro span').update(propLabel);
    box.show();
  });
  
  box.down('form').observe('submit', function(e) {
    e.stop();
    if (sending) return;
    var emailField = $('edtReqAlertEmail');
    if (!emailField.present()) {
      emailField.addClassName('missing').focus();
      return;
    }
    sending = true;
    emailField.removeClassName('missing');
    this.request({
      onSuccess: function() {
        alert("Nous avons bien pris en compte votre demande.");
        box.hide();
      },
      onFailure: function() { alert("Nous n’avons pas pu créer l’alerte de disponibilité."); },
      onComplete: function() { sending = false; }
    });
  });
  box.down('#alertDateRevealer').observe('click', function(e) {
    e.stop();
    e.findElement('p').hide().next('.alertDates').show();
  })
  box.down('p.actions a').observe('click', function(e) { e.stop(); box.hide(); });
}

function initShim(ref) {
  var notif = $(ref);
  if (!notif || !Prototype.Browser.IE6) return;
  notif.insert({ top:
    '<iframe id="' + notif.id + 'Shim" style="position:absolute;left:0;top:0;width:100%;height:100%;_filter:alpha(opacity=0)" ' +
    'frameborder="0" scrolling="no"></iframe>'
  });
}

function bindFullDescription() {
  var links = $('tabsContainer');
  if (!links || links.hasClassName('tabs')) return;

  var descLink = $('fullDescription');
  var link = links.select('li a.tdescription').first();
  if (!descLink || !link) return;

  function handleDescriptionEditorClick(e) {
    var activeLinks = links.select('li a.active');
    var activeLink = activeLinks ? activeLinks.first() : null;
    if (link == activeLink) return;
    link.blur();
    if (activeLink) {
      activeLink.removeClassName('active');
      linkElement = getLinkTarget(activeLink);
      if (linkElement) linkElement.hide();
    }
    link.addClassName('active');
    linkElement = getLinkTarget(link);
    if (linkElement) linkElement.show();
  } // handleDescriptionEditorClick

  descLink.observe('click', handleDescriptionEditorClick );
} // bindFullDescription

function bindSendToAFriend() {
  var trigger = $$('a.friend').first(), box = $('sendToAFriendRequest'), sending = false;
  if (!trigger || !box) return;

  function sendToAFriend(e) { e.stop(); trigger.blur(); box.show(); };
  trigger.observe('click', sendToAFriend).show();

  box.down('form').observe('submit', function(e) {
    e.stop();
    if (sending) return;
    var reqFields = this.select('input[id*="Req"]');
    var firstError;
    reqFields.each(function(f) {
      if (f.present())
        f.removeClassName('missing');
      else {
        f.addClassName('missing')
        if (!firstError) {
          firstError = f;
          f.focus();
        }
      }
    });
    if (firstError) return;
    this.request({
      onSuccess: function() {
        alert("Merci de votre intérêt. Votre message a correctement été envoyé.");
        box.hide();
      },
      onFailure: function() { alert("Impossible d'envoyer l’e-mail. Merci de réessayer ultérieurement."); },
      onComplete: function() { sending = false; }
    });
  });
  box.down('p.actions a').observe('click', function(e) { e.stop(); box.hide(); });
}

function getCurrentImage() {
  return $('photoZone').select('img.photoView').find(function(img) { return img.visible(); });
}

function initCarousel() {
  var base = $('carousel');
  if (!base) return;
  var list = base.down('ul'), item = list.down('li'), thumbWidth = item.getWidth() + parseInt(item.getStyle('padding-right'), 10);
  var width = list.select('li').length * thumbWidth;
  list.setStyle('width: ' + width + 'px; height: ' + item.getStyle('height') + ';');
  var carousel = new UI.Carousel(base, {
    previousButton: '.nav.previous', nextButton: '.nav.next', direction: 'horizontal'
  });
  gCar = carousel;
  var visibleThumbs = (base.getWidth() / thumbWidth).floor();
  if (list.select('li').length > visibleThumbs) base.down('.buttons') && base.down('.buttons').show();
  base.select('.nav').invoke('observe', 'click', function(e) {
    e.stop();
    this.blur();
  });

  var container = $('previewLarge')
  if (!container || !gFetchExtraViewsPath) return;
  
  function bindCarouselThumbnails() {
    var currentEffect = null;
    $('carousel').down('.container').observe('click', function(e) {
      var trigger = e.findElement('a');
      if (!trigger) return;
      e.stop();
      trigger.blur();
      if (currentEffect) return;
      var opts = { duration: SECS_FOR_CROSSFADE };
      var activeView = getCurrentImage();
      var newId = trigger.id.split('_').last();
      var otherView = $('view_' + newId);
      if (!activeView || !otherView || activeView == otherView) return;
      document.fire('ui:imageChanging', { id: newId });
      activeView.fade(opts);
      currentEffect = Effect.Appear(otherView, Object.extend(Object.clone(opts), {
        afterFinish: function() { currentEffect = null; }
      }));
    });
  }

  new Ajax.Updater(container, gFetchExtraViewsPath, {
    method: 'get', insertion: 'bottom', onSuccess: bindCarouselThumbnails
  });
} // initCarousel

function initCustomFields() {
  var cart = $('addToCart'), missingNotice = $('customFieldsMissingNotice');
  if (!cart || !missingNotice) return;
  var fields = cart.select('input[id*="Req"]'), title;
  cart.observe('submit', function(e) {
    missingNotice.hide();
    fields.invoke('removeClassName', 'missing');
    var faultyFields = fields.reject(Field.present);
    if (faultyFields.length == 0) return;
    e.stop();
    faultyFields.invoke('addClassName', 'missing');
    missingNotice.show();
    faultyFields.first().activate();
  });
} // initCustomFields

function initZoom() {
  var photoZone = $('photoZone'), zoomsZone = $('previewZoom'), reticulum = $('reticulum');
  if (!photoZone || !zoomsZone || !reticulum || !gFetchZoomPath) return;
  var zoomsContainer = zoomsZone.down('.container');
  var spinner = zoomsZone.down('.spinner');
  if (!zoomsContainer || !spinner) return;
  if (photoZone.down('img.placeholder')) return; // No actual image!
  $('photo').down('.zoom').setStyle('display: block');

  // Top-left corner of large-thumb for in-image mouse coordinates,
  // zoom zone dimensions, coordinate zoom factors, and maximum possible offsets for bounded movement.
  var refPoint, dims, factorX, factorY, corrections, maxZoomPos;
  var currentImageId = (getCurrentImage() || { id: 'foobar' }).id.split('_').last();
  
  function getZoomFor(id) { return zoomsZone.down('img#zoom_' + id); }
  
  function setupZoom() {
    spinner.hide();
    zoomsZone.activeZoom.show();
    refPoint = photoZone.viewportOffset();
    dims = [getCurrentImage().getDimensions(), zoomsZone.activeZoom.getDimensions()];
    factorX = dims[1].width / dims[0].width;
    factorY = dims[1].height / dims[0].height;
    corrections = zoomsContainer.getDimensions();
    maxZoomPos = [dims[1].width - corrections.width, dims[1].height - corrections.height];
    var retWidth = (corrections.width / factorX).ceil() - 2;
    var retHeight = (corrections.height / factorY).ceil() - 2;
    corrections = [corrections.width / 2, corrections.height / 2]; 
        
    reticulum.setStyle(
      'width: '  + retWidth + 'px; ' +
      'height: ' + retHeight + 'px;');
    photoZone.addClassName('zoomed');
  }

  // Show/hide behavior
  $('photoZone').observe('mouseover', function() {
    zoomsZone.activeZoom = getZoomFor(currentImageId);
    zoomsZone.select('img').without(zoomsZone.activeZoom).invoke('hide');
    zoomsZone.show();
    
    if (zoomsZone.activeZoom)
      setupZoom();
  });
  $('photoZone').observe('mouseout', function() {                                                                                            
    photoZone.removeClassName('zoomed');
    zoomsZone.hide();
  });

  // Zoom setup deferred by Ajax loading + image loading (in case zoom was requested between its carousel click and its being loaded)
  document.observe('ui:zoomLoaded', function(e) {
    if (e.memo.id == currentImageId && zoomsZone.visible()) {
      zoomsZone.activeZoom = getZoomFor(currentImageId);
      setupZoom();
    }
  });

  if (Prototype.Browser.IE6) {
    zoomsZone.insert({ top: '<iframe id="zoomShim" style="position:absolute;left:0;top:0;width:100%;height:100%;_filter:alpha(opacity=0)" frameborder="0" scrolling="no"></iframe>' });
    document.observe('mousemove', Prototype.emptyFunction); // Weird voodoo: this "unlocks" mousemove on #photoZone with shim… %-O
  }
  // Observe mouse movement and react!
  $('photoZone').observe('mousemove', function(e) {
    if (!zoomsZone.activeZoom) return;
    var ref = e.findElement('img.photoView') || e.findElement('#reticulum');
    if (!ref) return;
    var smallPos = [e.clientX - refPoint[0] - 1, e.clientY - refPoint[1] - 1];
    var zoomPos = [smallPos[0] * factorX - corrections[0], smallPos[1] * factorY - corrections[1]].invoke('floor');
    zoomPos[0] = (zoomPos[0] < 0 ? 0 : (zoomPos[0] > maxZoomPos[0] ? maxZoomPos[0] : zoomPos[0]));
    zoomPos[1] = (zoomPos[1] < 0 ? 0 : (zoomPos[1] > maxZoomPos[1] ? maxZoomPos[1] : zoomPos[1]));
    zoomsZone.activeZoom.setStyle('left: -' + zoomPos[0] + 'px; top: -' + zoomPos[1] + 'px;');
    reticulum.setStyle(
      'left: ' + (zoomPos[0] / factorX).floor() + 'px; ' +
      'top: '  + (zoomPos[1] / factorY).floor() + 'px;');
  });
  // Loading behavior
  document.observe('ui:imageChanging', function(e) {
    currentImageId = e.memo.id;
    if (getZoomFor(currentImageId)) return;
    
    function zoomIsLoaded() {
      var zoom = getZoomFor(currentImageId);
      return zoom && zoom.select('img').invoke('isLoaded').all();
    }
    
    spinner.show();
    new Ajax.Updater(zoomsContainer, gFetchZoomPath.sub('%ID%', currentImageId), {
      method: 'get', insertion: 'bottom', onSuccess: function() {
        var tmr = setInterval(function() {
          if (zoomIsLoaded()) {
            clearInterval(tmr);
            document.fire('ui:zoomLoaded', { id: currentImageId });
          }
        }, 100);
      }
    });
  });
} // initZoom

Element.addMethods('IMG', {
  // Based on code by John-David Dalton and others: see http://pastie.org/pastes/185452
  isLoaded: (function() {
      var img = new Image();
      if ('naturalWidth' in img)
        return function(element) { return 0 !== element.naturalWidth; };
      if ('complete' in img)
        return function(element) { return !!element.complete; }
      return function(element) { return element.readyState == 'complete'; };
    })()
});

document.observe('dom:loaded', function() {
  bindFullDescription();
  initCarousel();
  initZoom();
  initCustomFields();
  initShim('alertRequest');
  bindAlerts();
  initShim('sendToAFriendRequest');
  bindSendToAFriend();
});
