/**
 * Biladi Voyages custom scripts
 *
 * Requires Prototype 1.6.
 *
 * @author Julien Vignolles <julien@ciblo.net>
 * @legals © 2008-2009 Ciblo SA.
 */

var CART_NOTIFICATION_DURATION = 3;
var SEARCHBOX_PLACEHOLDER = 'Rechercher…';
var gAuthenticityToken = null;
var gAjaxSearchCompletion = null;

function ajaxifyCartFormAdder(e) {
  if (e.stopped) return;
  e.stop();
  this.request({
    onFailure: function(res) { alert(res.responseText); }
  });
}

function ajaxifyCartLinkAdders(e) {
  var link = e.findElement('a.cartAdder');
  if (!link) return;
  e.stop();
  new Ajax.Request(link.href, {
    method: 'post', parameters: { authenticity_token: gAuthenticityToken },
    onFailure: function(res) { alert(res.responseText); }
  });
}

function bindDatePickers() {
  var dators = $$('input.date');
  if (0 == dators.length) return;
  var ignoreFocus = false, dontHide = false, curCal;

  function popDate(e) {
    if (ignoreFocus) return;
    var editor = e.findElement('input.date');
    if (!editor) return;
    if (editor.disabled) return;
    var opts = {
      buttons: false, popup: 'force',
      onchange: function() { document.fire('ui:date:changed', { field: editor }); },
      before_show: function() { ignoreFocus = true; },
      after_close: function() { ignoreFocus = false; dontHide = false; curCal = null; }
    };
    var years = (editor.readAttribute('year-range') || '').match(/^(\d+)-(\d+)$/);
    if (years) {
      opts.minYear = parseInt(years[1], 10);
      opts.maxYear = parseInt(years[2], 10);
    }
    //editor.writeAttribute('readonly', true);
    curCal = new CalendarDateSelect(editor, opts);
    // The trick below makes sure any element inside the calendar getting the mouse
    // won't trigger hideCal when clicked (despite its click causing the input's blur event)
    // This way, blur events will close the calendar only when keyboard-originated, as in quick nav-tabbing.
    curCal.calendar_div
      .observe('mouseover', function() { dontHide = true; })
      .observe('mouseout', function() { dontHide = false; });
  };
  
  function hideCal() {
    curCal && !dontHide && curCal.close();
    curCal = null;
    dontHide = false;
  }
  
  dators.invoke('addClassName', 'jsEnabled')
    .invoke('observe', 'focus', popDate)
    .invoke('observe', 'blur', hideCal);
  document.observe('click', popDate);
} // bindDatePickers

var DateSyncs = { syncs: {} };

function bindDateSync(from, to, opts) {
  from = Object.isString(from) ? from : $(from).identify();
  DateSyncs.syncs[from] = DateSyncs.syncs[from] || [];
  DateSyncs.syncs[from].push([to, opts || {}]);
}

document.observe('ui:date:changed', function(e) {
  var field = e.memo.field;
  if (!field.id || field.id.blank()) return;
  var baseDate = Date.parseFormattedString(field.getValue());
  var syncs = DateSyncs.syncs[field.id] || [], sync, offset;
  for (var index = 0, len = syncs.length; index < len; ++index) {
    sync = $(syncs[index][0]);
    if (!sync || sync.present() && syncs[index][1].onlyBlank) continue;
    offset = syncs[index][1].offset || 0;
    sync.setValue(new Date(baseDate.getTime() + 86400000 * offset).toFormattedString()).
      highlight({ duration: 0.5, keepBackgroundImage: true });
  }
});

function bindIE6Submenus() {
  if (!Prototype.Browser.IE6) return;

  var activeMenu;
  
  function showSubMenu(e) {
    var menu = e.findElement('li').down('ul.submenu');
    if (!menu) return;
    if (activeMenu) hideSubMenu();
    menu.setStyle('display: block;');
    activeMenu = menu;
  }
  
  function hideSubMenu() {
    activeMenu && activeMenu.setStyle('display: none;');
    activeMenu = null;
  }
  
  $('menuHorizontal').select('li.withSubMenu').
    invoke('observe', 'mouseenter', showSubMenu).
    invoke('observe', 'mouseleave', hideSubMenu);
}

function bindSizes() {
  var menu = $('fontSizes');
  menu && menu.observe('click', function(e) {
    var activator = e.findElement('a');
    if (!activator) return;
    e.stop();
    document.body.addClassName(activator.id);
    menu.select('a').each(function(link) {
      if (link == activator) {
        link.addClassName('selected');
      } else {
        link.removeClassName('selected');
        document.body.removeClassName(link.id);
      }
    });
  });
} // bindMenu

function bindSpecTogglers() {
  var links = $('tabsContent');
  if (!links || links.hasClassName('tabs') || links.hasClassName('notPreloaded')) return;
  var activeLink = links.select('li a.active').first();

  function handleSpecEditorClick(e) {
    e.stop();
    var link = e.findElement('a');
    link.blur();
    if (link == activeLink) return;
    activeLink.removeClassName('active');
    link.addClassName('active');
    $(activeLink.readAttribute('href').substring(1)).hide();
    $((activeLink = link).readAttribute('href').substring(1)).show();
  } // handleSpecEditorClick

  links.observe('click', handleSpecEditorClick);
} // bindSpecTogglers

function ensureIEVersionFlagIsDefined() {
  if (Prototype.Browser.IE && !('IE6' in Prototype.Browser)) {
    // Cargo-cult'd from prototype-ui.js (which will redefine it if loaded, but who cares?)
    Prototype.Browser.IEVersion = parseFloat(navigator.appVersion.split(';')[1].strip().split(' ')[1]);
    Prototype.Browser.IE6 =  Prototype.Browser.IEVersion == 6;
    Prototype.Browser.IE7 =  Prototype.Browser.IEVersion == 7;
  }
}

function hookCartAdders() {
  var notif = $('cartNotification');
  if (!notif) return;
  var form = $$('form#addToCart').first();
  form && form.observe('submit', ajaxifyCartFormAdder);
  var link = $(document.body).down('p.baseCart a');
  link && document.observe('click', ajaxifyCartLinkAdders);
  notif.down('.closer').observe('click', function(e) {
    e.stop();
    notif.hide();
  });
}

function initSearchCompletions() {

  var searchBox = $('searchBox');
  if (!searchBox) return;
  
  function addPlaceholder() {
    if ($F(searchBox).blank())
      searchBox.setValue(SEARCHBOX_PLACEHOLDER).addClassName('placeholder');
  }
  
  function removePlaceholder() {
    if ($F(searchBox) == SEARCHBOX_PLACEHOLDER)
      searchBox.setValue('').removeClassName('placeholder');
  }

  addPlaceholder();
  searchBox.observe('focus', removePlaceholder);
  searchBox.observe('blur', addPlaceholder);
  searchBox.up('form').observe('submit', removePlaceholder);
  
  var opts = {
    method:   'get',
    callback: function(element) { return $(element).up('form').serialize(); },
    select:   'productName',
    onShow:   function(element, update){ 
      if (!update.style.position || update.style.position == 'absolute') {
        update.style.position = 'absolute';
        Position.clone(element, update, { setHeight: false, setWidth: false, offsetTop: element.offsetHeight });
      }
      Effect.Appear(update, { duration: 0.15 });
    }
  };
  
  new Ajax.Autocompleter('searchBox', 'searchBoxCompletions', gAjaxSearchCompletion, opts);
  if ($('edtMatch'))
    new Ajax.Autocompleter('edtMatch', 'edtMatchCompletions', gAjaxSearchCompletion, opts);
} // initSearchCompletions

function initCartShim() {
  var notif = $('cartNotification');
  if (!notif || !Prototype.Browser.IE) return;
  notif.insert({ top:
    '<iframe id="cartNotificationShim" style="position:absolute;left:0;top:0;width:100%;height:100%;_filter:alpha(opacity=0)" ' +
    'frameborder="0" scrolling="no"></iframe>'
  });
}

function showCartNotification() {
  var notif = $('cartNotification');
  if (!notif) throw 'Missing cart notification pad';
  notif.show();
}

document.observe('dom:loaded', function() {
  ensureIEVersionFlagIsDefined();
  bindIE6Submenus();
  initCartShim();
  hookCartAdders();
  initSearchCompletions();
  bindSizes();
  bindSpecTogglers();
  bindDatePickers();
});
