// jquery
if ('jQuery' in window){
  jQuery.noConflict();
  window.j = jQuery;
}

// mootools
window.$ = document.id;

// clickout event
Element.Events.clickout = {
  
  base : 'click',
  
  condition : function(ev) {
    var trg = ev.target;
    if(!(trg.get('data-dynamic') || trg.getParent('[data-dynamic]') || trg.get('data-popup-remote') || trg.getParent('[data-popup-remote]'))) {
      ev.stopPropagation();
      return false;
    }
  },

  onAdd: function(fn){
    this.getDocument().addEvent('click', fn);
  },
  
  onRemove: function(fn){
    this.getDocument().removeEvent('click', fn);
  }
  
};

var LearnBoost = {};

LearnBoost.Dynamic = {

    init: function() {
      var self = this;
      j('form[data-dynamic]').live('submit', function(ev){self.process(ev, $(this));});
      j('[data-dynamic]').live('click', function(ev){
        if ($(this).get('tag') !== 'form') self.process(ev, $(this));
      });
      j('[data-popup-remote]').live('click', function(ev){self.process(ev, $(this));});
      j('input[type=submit]').live('click', function(ev){
        if (!ev.clientX && !ev.clientY) return true;
        var form = $(this).getParent('form[data-dynamic]');
        if (form && String($(this).get('data-name')).length){
          j(form).find('input[type=hidden][name='+ $(this).get('data-name') +']').remove();
          form.adopt(new Element('input', {type: 'hidden', name: $(this).get('data-name'), value: $(this).get('value')}))
        }
      });
    },

    process: function(ev, el){
      if(ev.isPropagationStopped()) return null; // <- validation block

      if (el.get('data-popup-remote') === 'false' || el.get('data-dynamic') === 'false') el.submit();
      else {
        if (!ev.isPopupRemote) ev.preventDefault();

        if (el.retrieve('dynamic-handler')){
          el.retrieve('dynamic-handler')._send();
        }
        else el.store('dynamic-handler', new LearnBoost.Dynamic.Handler(ev, el));
      }
    }
  };

  LearnBoost.Dynamic.Handler = new Class({

    Implements: Options,

    options: {
      addCssClass: true
    },

    initialize: function(ev, el, options){
      this.setOptions(options);
      this._init(ev, el);
      this._send();
    },

    _init: function(ev, el) {
      var self = this;
      this.element = el;
      this.ev = ev;

      this.prps = {
        type: ev.type,
        link: (ev.isPopupRemote) ? ev.href : (ev.type == 'click') ? el.get('href') : el.get('action'),
        method: (ev.type == 'click') ? 'get' : (el.get('method') ? el.get('method') : 'post')
      };

      if (el.get('tag') !== 'form' && el.get('tag') !== 'a') this.prps.link = el.get('data-dynamic') || el.get('data-popup-remote');

      if (el.get('data-popup-remote')){
        this._popupDelay = (function(){
          if (!this.dialog) this.dialog = new LearnBoost.Dialog();
        }).delay(100, this);
      }

      this.ajxs = new LearnBoost.Request.JSON({
        onRequest: function() {
          self.element.addClass('loading');
        },

        onComplete: function(){
          self.element.removeClass('loading');
        },

        onFailure: function(x){
          if (self._popupDelay) clearTimeout(self._popupDelay);
          if (self.dialog) self.dialog.hide();
        },

        onSuccess: function(jdata, html) {
          if (jdata === null) self.popup(html);
          else $each(jdata, function (value, key){self[key.camelCase()](value);});
          if (navigator.platform == "iPad")
            j('input.date').attr('readonly', 'readonly');
        }
      })
    },

    _listMarkup: function(el, msgs, options) {
      var
        thms = '',
        fnName = {'top': 'First', 'bottom': 'Last', 'after': 'Next', 'before': 'Previous'},
        prevMsg = options.injectTo[0]['get' + fnName[options.injectTo[1]]]('ul');

      if(prevMsg && !el) prevMsg.dispose();

      $splat(msgs).each(function(msg) {thms = '<li>' + msg + '</li>' + thms;});
      if (el) return el.set('html', thms);
      return new Element('ul', {
        'class': options.cssClass,
        html: thms
      }).inject(options.injectTo[0], options.injectTo[1]);
    },

    _send: function() {
      var el = this.element, ev = this.ev;
      this.prps = {
        type: ev.type,
        link: (ev.isPopupRemote) ? ev.href : (ev.type == 'click') ? el.get('href') : el.get('action'),
        method: (ev.type != 'submit') ? 'get' : (el.get('method') ? el.get('method') : 'post')
      };

      if (el.get('tag') !== 'form' && el.get('tag') !== 'a') this.prps.link = el.get('data-dynamic') || el.get('data-popup-remote');

      if(this.element.get('data-popup-remote')){
        this.addSpinner = true;
        if(this.dialog){
          (function(){
            this.dialog.show();
          }).delay(100, this);
        }
      };
      if (this.ajxs) this.ajxs.cancel();
      this.ajxs.options.url = this.prps.link;

      if(this.element.retrieve('validator-handler')) {
        if(this.element.retrieve('validator-handler').isOk) this._sendNow();
      }
      else this._sendNow();
    },

    _sendNow: function () {

      if (LearnBoost.JSONPost && LearnBoost.JSONPost.data !== false){
        this.ajxs.options.urlEncoded = false;
        this.ajxs.headers.set('Content-Type', 'application/json');
        this.ajxs.options.data = LearnBoost.JSONPost.data;

        this.ajxs[this.prps.method](this.prps.link);
        return;
      } else {
        this.ajxs.options.urlEncoded = true;
      }


      if(this.element.get('data-dynamic') == 'transporting') {
        this.element.getElements('input[type=text], input[type=password], textarea').each(function (field, iF) {
          if(!this.ajxs.options.data) this.ajxs.options.data = {};
          this.ajxs.options.data[field.get('name')] = field.get('tag') == 'input' ? field.get('value') : field.get('text');
        }, this);

      }

      this.ajxs[this.prps.method](this.prps.type == 'click' || this.element.get('data-dynamic') == 'transporting' ? this.prps.link : this.element);

    },

    // *** response events ***

    /*
    * redirect
    */
    redirect: function (url) {
      window.location = url;
    },

    /*
    * Replaces each #selector (document.getElement) with the supplied HTML
    *
    *   'replace': {
    *     '#selector-1': '<html-1>',
    *     '#selector-2': '<html-2>'
    *     ...
    *     '#selector-n': '<html-n>'
    *   }
    */
    replace: function(params) {
      $each(params, function (html, el){
        $(el).set('html', html);
      });
    },

    /*
    * 'popup': '<html>'
    * if overlay not exist, creates a popup with the html content. if exist, just set html code.
    */
    popup: function(html) {
      if(html != false) {
        if(!this.dialog) this.dialog = new LearnBoost.Dialog();
        else this.dialog.show();
        this.dialog.decorate(html);
      }
    },

    /*
    * 'popup-remote': '/url/'
    *  Shows an overlay dialog fetching the submitted url
    */
    popupRemote: function(url) {
      new LearnBoost.Dynamic.Handler({
        isPopupRemote: true,
        type: 'click',
        href: url,
        method: 'get'
      }, this.element);
    },

    fireEvent: function(params){
      if (typeof params == 'string'){
        LearnBoost.fireEvent(params);
      } else {
        LearnBoost.fireEvent(params[0], params.slice(1));
      }
    },

    /*
     * fireEventRemote: 'params'
     * fire an event in element specificated
     *
     * params: {
     *            el: - string selector
     *            data: - send data
     *            name: (optional) - event name. defect is 'fireEventRemote'
     * }
     */
    fireEventRemote: function (params) {
      $(params.el).fireEvent(params.name ? params.name : 'fireEventRemote', params.data);
    },

    /*
     * storeRemote: 'params'
     * store data in element specified.
     *
     * params: {
     *            el: - string selector
     *            name: - name of key
     *            name: (optional) - store name. defect is 'store-remote'
     * }
     */
    storeRemote: function (params) {
      $(params.el).store(params.name ? params.name : 'store-remote', params.data);
    },

    /*
     * functionRemote: '{data}'
     * data: {
     *          method: - method name
     *          params: - parametros papa !!. que otra cosa va ser !
     * }
     *
     * execute a remote function stored in LearnBoost.Dynamic
     */
    functionRemote: function (data) {
      LearnBoost.Dynamic[data.method](data.params);
    },

    /*
     * 'close-popup': 'selector'
     *
     * force to close overlay dialog.
     * - if selector = 'this' seach overlay dialog that contains the element that fired the event.
     */
    closePopup: function (selector){
      var dialog = document.getElement('div.dialog');
      if (dialog && dialog.retrieve('LB-dialog')) dialog.retrieve('LB-dialog').hide();
    },

    /*
    * 'clear': true
    *  Calls form.reset() if true
    */
    clear: function(clear) {
      if (clear) this.element.reset();
    },

    /*
    * 'global-errors': [...]
    * Adds a <ul class="global-errors"> at the top of the form with <li> with each error in the array.
    * If it's not an array and it's a string, it's converted to array first ($splat)
    */
    globalErrors: function(global_errors) {
      global_errors = $splat(global_errors);

      if (global_errors.length) {
        this._listMarkup(this.element.getElement('.global-errors'), global_errors, {
          cssClass: 'global-errors',
          injectTo: [this.element, 'top']
        });
      }
      else if (this.element.getElement('.global-errors')) this.element.getElement('.global-errors').dispose();
    },

    /*
   * 'errors': { 'field_name': ['Error message'], ... }
   * Creates <ul class="errors"> after input[name={field_name}] with the error messages as <li>
   */
    errors: function(errors) {
      $each(errors, function(field_errors, name) {
        var field = this.element.getElement('[name=\''+name+'\']');

        if (field_errors.length) {
          field.addClass('error');
          this._listMarkup(field.getNext('.errors'), field_errors, {
            cssClass: 'errors',
            injectTo: [field, 'after']
          });
        }
        else  {
          field.removeClass('error');
          if (field.getNext('.errors')) field.getNext('.errors').dispose();
        }
      }, this)
    },

    /*
   * 'errors': { 'field_name': ['Error message'], ... }
   * Creates <ul class="errors"> after input[name={field_name}] with the error messages as <li>
   */
    msgs: function(msgs) {
      var self = this;
      $each(msgs, function(field_oks, name) {
        var field = self.element.getElement('[name=\''+name+'\']');
        if (field_oks.length) {
          self._listMarkup(field.getNext('.msgs'), field_oks, {
            cssClass: 'msgs',
            injectTo: [field, 'after']
          });
        }
        else if (field.getNext('.msgs')) field.getNext('.msgs').dispose();
      });
    },

    /*
    * 'success-msgs': []
    * Same as global_errors, but with class="success-msgs"
    */
    successMsgs: function (msgs) {
      msgs = $splat(msgs);

      if (msgs.length) {
        var list = this._listMarkup(this.element.getElement('.success-msgs'), msgs, {
          cssClass: 'success-msgs',
          injectTo: [this.element, 'top']
        }).adopt(
          new Element('a', {'class': 'close'}).addEvent('click', function(){
            list.destroy();
          })
        );
      }
      else if (this.element.getElement('.success-msgs')) this.element.getElement('.success-msgs').dispose();
    }
    // *** end response events ***
  });

LearnBoost.AutoFocus = function(el){
  var elem = el ? $(el) : $('body');
  try {
    if(elem.getElement('[focus]') && elem.getElement('[focus]').focus) elem.getElement('[focus]').focus();
  } catch(e){}
}

  LearnBoost.Spinner = {

    _shown: 0,

    _init: function(){
      this.text = new Element('span', {text: 'Please wait'});
      this._spinner = new Element('div', {id: 'global-spinner'}).adopt(this.text).inject(document.body);
    },

    show: function(type){
      if (!this._spinner) this._init();
      if (++this._shown == 1){
        this._shower = function(){
          this._spinner.fade('show');
        }.delay(50, this);
      }
      if (type == 'post') this.text.set('text', 'Please wait');
    },
    
    hide: function(){
      var self = this;
      if (--self._shown == 0){
        (function(){
          clearTimeout(self._shower);
          self._spinner.fade('hide');
        }).delay(500);
      }
    }
  };



LearnBoost.Dialog = new Class({
    Implements: Options,

    options: {
      cssClass:{
        mask: 'dialog-mask',
        dialog: 'dialog',
        container: 'dialog-container'
      },
      autoShow: true,
      autoSpinner: true,
      zIndex: 1000,
      injectTo: ['#wrap', 'bottom']
    },

    initialize: function(content, options){
      var self = this;
      this.setOptions(options);
      this.showSpinner = this.options.autoSpinner;

      this.els = {};
      this.shown = false;
      
      this.create();

      this.els.dialog.addEvent('click:relay(.action-button)', function (ev) {
        if($(this).get('exec-function')) LearnBoost.Dialog[$(this).get('exec-function').camelCase()](self);
      });
    },

    create: function(){
      var self = this;
      this.els.mask = new Element ('div', {
        'class': this.options.cssClass.mask,
        'styles': {'z-index': this.options.zIndex},
        events: {click: function (ev) {if($(ev.target) === $(this)) self.hide()}}
      }).adopt (
        this.els.container = new Element ('div', {
          'class': this.options.cssClass.container,
          events: {
            'click:relay(.dialog-btn-close)': function(ev){
              ev.preventDefault();
              self.hide();
            }
          }
        })
      );

      this.createSpinner();

      if(this.showSpinner) this.addSpinner();
      if(this.options.autoShow) this.show();

      this.els.dialog= new Element('div', {
        'class': this.options.cssClass.dialog
      }).store('LB-dialog', this);
    },

    show: function(){
      var self = this;
      if(!self.shown){
        self.shown = true;
        self.els.mask.inject($(self.options.injectTo[0], self.options.injectTo[1]));
        if(self.showSpinner) self.addSpinner();
      }
    },

    calcMarginTop: function(){
      return j(document).scrollTop() + 100;
    },

    hide: function(){
      this.shown = false;
      this.els.mask.dispose();
      this.clear();
      if(this.showSpinner) this.hideSpinner();
    },

    clear: function(){
      this.els.dialog.empty();
    },

    createSpinner: function(){
      this.els.spinner = new Element('div', {
        'class': 'popup-loading',
        html: '<p>Loading</p>'
      });
    },

    addSpinner: function(){
      this.els.spinner.inject(this.els.container);
    },

    hideSpinner: function(){
      this.els.spinner.dispose();
    },

    decorate: function(html){
      var js = '';
      html = html.stripScripts(function(script){
        js = script;
      });
      this.hideSpinner();
      this.els.dialog.set('html', html).inject(this.els.container);
      this.els.container.setStyle('margin-top', this.calcMarginTop());
      LearnBoost.AutoFocus(this.els.container);
      $exec(js);
    }
  });


//var login = function () {
//
//  var elems = {
//    header: $('header')
//  }
//
//  if (elems.header.getElement('.login')) {
//
//    var
//      shown = false,
//      elLogin = elems.header.getElement('.login').addEvents({
//        click: function (ev) {
//          ev.preventDefault();
//          toggle();
//        }
//      }),
//
//      elLoginBox = elems.header.getElement('#loginbox').addEvents({
//        clickout: function(ev) {
//          if(shown && !elLoginBox.hasChild(ev.target) && !ev.target.getParent('#header')) hide();
//        }
//      }),
//
//      show = function() {
//        elLoginBox.setStyle('display', 'block');
//        elLogin.addClass('shown');
//        if(elLoginBox.getElement('input').focus) elLoginBox.getElement('input').focus();
//        shown = true;
//      },
//
//      hide = function() {
//        elLoginBox.setStyle('display', 'none');
//        elLogin.removeClass('shown');
//        shown = false;
//      },
//
//      toggle = function(){
//        if(elLoginBox.getStyle('display') == 'block') hide();
//        else show();
//      };
//  }
//}


window.addEvent('domready', function(){
  
  LearnBoost.Dynamic.init();
  LearnBoost.AutoFocus()

  login();
  
  (function(){
    var initialize = function(options){
      this.parent(options);
      
      var self = this,
          timer,
          failed = false,
          fail = function(){
            if (!failed){
              self.cancel();
              //var dialog = new LearnBoost.Dialog(),
              var type = self.status == 401 ? 'security' : 'warning'
                  title = self.status == 401 ? 'Oops! Your session expired' : 'Oops! There was a problem',
                  text = self.status == 401 
                  ? '<p>Your session has expired, or maybe you logged out in a different window or tab</p>' 
                  + '<p>Please refresh the page or <a href="/login">click here</a> to log in.</p>'
                  : '<p>Sorry, we are having a problem loading this page. We have logged this issue and '
                  + 'will alert the team.</p><p>Try refreshing the page and perform the action again</p>';
              /*dialog.show();
              dialog.decorate('<div class="dialog-notice '+ type +'"><div class="dialog-head"><h1><span class="icon"></span> '
                            + title + '</h1><div class="dialog-btn-close"><b></b></div></div><div class="dialog-content">'
                            + '<form><fieldset>'+ text +'<p class="note">If ' 
                            + 'the problem persists, click <a href="http://learnboost.com/help" target="_blank">here</a> to open '
                            + 'LearnBoost help in a new window/tab.</p></fieldset><div class="buttons"><a href="#" class="dialog-btn-close'
                            + ' action-button">Close</a></div></form></div></div>');
              */
              failed = true;
            }
          };
      
      this.addEvents({
        onRequest: function(){
          timer = setTimeout(function(){
            fail();
            self.fireEvent('failure');
          }, 15000);
          LearnBoost.Spinner.show(self.options.method);
        },
        onComplete: function(){
          clearTimeout(timer);
          LearnBoost.Spinner.hide();
        },
        onCancel: function(){
          clearTimeout(timer);
          LearnBoost.Spinner.hide();
        },
        onFailure: fail
      });
    },
    
    onSuccess = function(){
      this.parent.apply(this, arguments);
    };
    
    LearnBoost.Request = {};
    LearnBoost.Request = new Class({
      Extends: Request,
      initialize: initialize,
      onSuccess: onSuccess
    });

    LearnBoost.Request.HTML = new Class({
      Extends: Request.HTML,
      initialize: initialize,
      onSuccess: onSuccess
    });

    LearnBoost.Request.JSON = new Class({
      Extends: Request.JSON,
      initialize: initialize,
      onSuccess: onSuccess
    });
    
    Element.Properties.send = {

      get: function(options){
        if (options || !this.retrieve('send')){
          if (options || !this.retrieve('send:options')) this.set('send', options);
          this.store('send', new LearnBoost.Request(this.retrieve('send:options')));
        }
        return this.retrieve('send');
      }

    };
    
  })();
})

LearnBoost.Dynamic.goingApp = function () {
  (function() { LearnBoost.Spinner.show();}).delay(400);
  (function() { LearnBoost.Spinner.show();}).delay(500);
}


