/**
*   Application scope.
*/
app = {
  // main content container
  container: null,
  refreshTimer: $empty,
    
  history: null,
  historyKey: 'page',
  historyModules: {},
    
  barObserver: null,
  menuObserver: null,
    
  /**
    *   onDomready
    */
  ready: function() {
    try {
      this.initHistoryManager();
    } catch(ignore) {}
  },

  initHistoryManager: function() {
    this.container = $('content_container');
    this.history = new HistoryManagerX();
    this.history.initialize();

    this.history.register(
      this.historyKey,
      ['url-' + window.location.pathname],
      this.manageHistory.bind(this),
      false,
      '-([\\w/_-]*)'
      );

    if(this.container) {
      this.addHistoryModule('url', loadPage);
      this.addHistoryModule('order_edit', loadAndRebuildOrderForm);
    }
  },

  /**
    *   onLoad
    */
  load: function() {
    if(this.container) {
      this.history.start();
      this.refresher(window.location.pathname, reloadPage);
    }
  },
    
  addHistoryModule: function(key, callback) {
    this.historyModules[key] = callback;
  },
    
  addHistory: function(key, value) {
    this.history.setValue(this.historyKey, 0, key + '-' + value); // save in history
  },
    
  manageHistory: function(values) {
    var split = values[0].split('-'); // split module name and value to be passed
    this.historyModules[split[0]](split[1]); // invoke the modules callback method
  },

  /**
     *  Pages that shall be refreshed periodically:
     *    - Order show page.
     *    - Customer active orders.
     *    - PrintShop inbox.
     *    - PrintShop active orders.
     */
  refreshPages: [/\/customer/, /\/printshop/],

  /**
     *  Calls +load+ function on timeout if +url+ matches one of +refreshPages+ regexes.
     */
  refresher: function(url, load, bind, args) {
    // disable refresher for now (yanks whitebox shim)
    return;

    if(this.refreshPages.some(function(refreshRegex) {
      return url.match(refreshRegex);
    })) {
      // if this is a page that shall be refreshed by a timer (every 2 minutes)
      this.refreshTimer = load.delay(180000, bind, args);
    } else {
      $clear(this.refreshTimer);
    }
  }

};

/**
* Object in global namespace. Loader to be displayed during ajax requests.
*/
Loader = {
  show: function() {
    if(!$('loader')) new Element('div', {
      id: 'loader'
    }).inject(document.body).grab(new Element('span'));
  },
  hide: function() {
    var loader = $('loader'); if(loader) loader.dispose();
  }
};

Notice = {};

var Hoverizor = new Class({

  Implements: [Options],
    
  options: {
    fileType: 'jpg'
  },

  initialize: function(element, options) {
    this.setOptions(options);
    this.element = $(element);
    this.hoverfix = '_hover.' + this.options.fileType;

    this.element.addEvent('mouseover', this.activateHover.bind(this) );
    this.element.addEvent('mouseout', this.deactivateHover.bind(this) );
  },
    
  activateHover: function() {
    // check if the hoverizor is still active
    if(this.active()) {
      var src = this.element.get('src');
      this.element.store('nativeSrc', src);
      this.element.set('src', src.replace(/\.(jpg|gif|png)?.*$/, this.hoverfix));
    }
  },
    
  deactivateHover: function() {
    if(this.active()) // check if the hoverizor is still active
      this.element.set('src', this.element.retrieve('nativeSrc'));
  },
    
  active: function() {
    return this.element.hasClass('hoverize') || this.element.hasClass('png_hoverize');
  }

});

function tipify(element, options) {
  options = options || {};

  element.tip = new Tips(element, {
    className: 'scout_tip',
    offset: {
      x: (element.get('data-tip_offset') || -67).toInt(),
      y: null
    },
    showDelay: $defined(options.showDelay) ? options.showDelay : 1000,
    fixed: true
  });

  /**
     * This patch makes sure that the tip offset is set so that the tip is hovering entirely over cursor,
     * no mather what height the +tip+ content has.
     */
  element.tip['position'] = function(event) {
    var size = window.getSize(), scroll = window.getScroll(),
    tip = {
      x: this.tip.offsetWidth,
      y: this.tip.offsetHeight
    },
    props = {
      x: 'left',
      y: 'top'
    },
    obj = {};

    // patch
    this.options.offset['y'] = -tip['y'] - 5; // if no 20px buffer, then the tip bottom will land directly on the cursor
    // end patch

    for (var z in props){
      obj[props[z]] = event.page[z] + this.options.offset[z];
      if ((obj[props[z]] + tip[z] - scroll[z]) > size[z]) obj[props[z]] = event.page[z] - this.options.offset[z] - tip[z];
    }

    this.tip.setStyles(obj);
  }.bind(element.tip);

  element.addEvent('click', function() {
    this.tip.hide();
  });
  return element;
};

function printshops_tween(element) {
  var info = element.getElement('.count_info').fade('hide');
  info.set('tween', { 
    duration: 'short'
  });

  element.getElement('.count_number').addEvent('mouseover', function() {
    info.fade('in');
  }).addEvent('mouseout', function() {
    info.fade('out');
  });
};

/**
*   Refreshes the height of the whitebox shim.
*   Useful to call after each modification of a whitbox, as the document height can grow.
*/
recalcShim = function(noBuffer) {
  document.body.retrieve('mask').position();
}

/**
* Function in global namespace to be invoked at every failed ajax request.
*/
requestFailure = function() {
  Loader.hide();
  //alert('Epic fail!');
}
