
$(function() {
  videoManager.enableVideoLinks();
  $('.slider-container').presentation();

  $('#wishListTermsLink, .terms-apply').click(function(){
    var myOptions = {"width":700,"height":500};
    myOptions = $.extend({},modalDefault, myOptions);

    $('#wishListTermsContent').dialog(myOptions);
    return false;
  });

  $('input.txt-search').watermark("Enter Author, Title, ISBN, or Keyword",{useNative: false});

  $('input.txt-search.promo-off').watermark("Enter Author, Title, ISBN, or Keyword",{useNative: false})

  $('.click-here, .get-started-trigger').bind('click', function (e) {
    e.preventDefault();
    $('.promo-overlay').dialog({

      title : 'First e-textbook is free',
      modal :true,
      width:720,
      height:500,
      resizable : false,
      show: "fade",
      draggable: false

    });

    return false;
  });

  $('.click-here.promo-off, .get-started-trigger.promo-off').bind('click', function (e) {
    e.preventDefault();
    $('.promo-overlay').dialog({

      title : 'Kno is Easy to Use and Works on the Web and iPad',
      modal :true,
      width:720,
      height:500,
      resizable : false,
      show: "fade",
      draggable: false

    });

    return false;
  });

  $('.promo-overlay').hover(function(){
    $('input#popup-search').blur(); 
  });
  
  $('img.promoOffMoreInfo').click(function(){

    $('#promoOffMoreInfoDialog').dialog({
      title: 'How to Redeem Your Invite Code',
      modal :true,
      width:500,
      resizable : false,
      show: "fade",
      draggable: false
    });
    
    
  });
  
});

$.widget('kno.presentation', {
    _create : function () {
      this._createUI();
      this._bindEvents();
     /* this.jumpTo(this.options.current);*/
     this.play();
    },
    _renderSlide : function () {
      var opts = this.options;
      var ele = this.element;
      var idx = parseInt(opts.current, 10);
      var $slides = this.$slides;
      var $links = this.$links;
      
      var active = $slides.removeClass('go-out go-in').filter('.active');
      $slides.not('.active').hide();
      active.addClass('go-out');

      setTimeout(function () {
        active.removeClass('active').hide();
        var currentSlide = $slides[idx];
        $(currentSlide).show().addClass('active go-in');
        
      }, 300);
      $links.filter('.active').removeClass('active');
      var currentLink = $links[idx];
      $(currentLink).addClass('active');
    },
    _createUI : function () {
      var opts = this.options;
      this.$slides = this.element.find(opts.slideSelector);
      var container = '<ul class="sl-controls">[ITEMS]</ul>';
      var template = '<li><a href="#slide" data-index="[INDEX]"><span>[NUMBER]</span></a></li>';

      var html = '';

      for (var i = 0, len = this.$slides.length; i < len; i++) {
        html += template.replace('[INDEX]', i).replace('[NUMBER]', i + 1);
      }
      
      container = container.replace('[ITEMS]', html);

      this.$controls = $(container).appendTo(this.element);
      this.$links = this.$controls.find('a');
    },
    _bindEvents: function () {
      var me = this;
      this.$controls.bind('click.presentation', function (e) {
        var $link = $(e.target).closest('a');
        if ($link.length > 0 && !$link.is('.active')) {
          var idx = parseInt($link.attr('data-index'), 10);
          me.jumpTo(idx);
          me.stop();
        }
        return false;
      });
    },
    jumpTo : function (idx) {
      if (this.$slides.length == 0) return;
      if (idx >= this.$slides.length) {
        idx = this.$slides.length - 1;
      }
      if (idx < 0) {
        idx = 0;
      }
      this.options.current = idx;
      this._renderSlide();
    },
    next : function () {
      if (this.$slides.length == 0) return;
      this.options.current++;
      this.options.current = this.options.current % this.$slides.length;
      this._renderSlide();
    },
    previous : function () {
      if (this.$slides.length == 0) return;
      this.options.current--;
      if (this.options.current < 0) {
        this.options.current = this.$slides.length - 1;
      }
      this._renderSlide();
    },
    play : function () {
      var me = this;

      me.first = me.first || this.options.current;
      this.jumpTo(this.options.current);

      this.interval = setInterval (function (){
        me.next();
        if (me.options.current == me.first) {
          me.stop();
          return;
        }
      }, 8000);
      //init auto transition
    },
    stop : function () {
      //stop auto transition
      clearInterval(this.interval);
    },
    options : {
      slideSelector : '.anim-slide',
      current : 0,
      autoPlay: false
    }
});


var videoManager = {
  count : 0,
  enableVideoLinks : function () {
    $('.video-container').bind('click.video', function (e) {
      var video = $(e.target).closest('.video-trigger');
      if (video.length == 0 ) return false;

      var type = $.trim(video.attr('data-video-provider'));
      if (type == '') {
        type = 'vimeo';
      }

      var aFuncCall = videoLayer[type];
      if (typeof aFuncCall != 'function') return false;
      
      var elementId = $.trim(video.attr('data-video-element-id'));
      if (elementId == '') {
        elementId = (new Date()).getTime() + '_' + videoManager.count;
        videoManager.count++;
        video.attr('data-video-element-id', elementId);
      }
      var videoId = $.trim(video.attr('data-video-id'));
      var title = $.trim(video.attr('data-video-title'))

      var params = {
        videoId: videoId,
        title: title,
        elementId: elementId
      }

      aFuncCall.call(videoLayer, params);
      return false;
    });
  }
};


(function($){
  //Add filter to browsers doesnt support it
  
  if (!Array.prototype.filter)
  {
    Array.prototype.filter = function(fun /*, thisp */)
    {
      "use strict";

      if (this === void 0 || this === null)
        throw new TypeError();

      var t = Object(this);
      var len = t.length >>> 0;
      if (typeof fun !== "function")
        throw new TypeError();

      var res = [];
      var thisp = arguments[1];
      for (var i = 0; i < len; i++)
      {
        if (i in t)
        {
          var val = t[i]; // in case fun mutates this
          if (fun.call(thisp, val, i, t))
            res.push(val);
        }
      }

      return res;
    };
  }

  if(typeof Array.prototype.map !== 'function') {
    Array.prototype.map = function(fn) {
      for (i=0, r=[], l = this.length; i < l; r.push(fn(this[i++])));
        return r;
    };
  }
  
  var kno = window.kno || {};
  //avoid to redefine the kno object if the file has been included several times
  if (kno.isInitialized) 
    return;
  var flags = {
    supportsLocalStorage : null
  };
  
  $.extend(kno, {
    now : function () {
      var fn = Date.now;
      if (fn) {
        return Date.now(); 
      }
      return (new Date()).getTime();
    },
   /**
    * return a string formatted with the passed arguments
    * @example
    *
    * var s = $a.format('Some {0} with a {1} mood {2}', 'String', 'good', 'arrived');
    * //output
    * //s = 'Some String with a good mood arrived'
    */
    format : function () {
      var pattern = /\{\d+\}/g;
      //safer way to convert a pseudo array to an object array
      var args = Array.prototype.slice.call(arguments);
      var s = args.shift();
      return s.replace(pattern, function(c) {
        var replacement = args[c.match(/\d+/)] ;
        if (kno.isNull(replacement)) {
          replacement = "";
        }
        return replacement;
      });
    },
    /**
     * given an object and a key (in a string format separated by dots) return the object value
     */
    getValue : function (obj, key) {
      var tokens = key.replace(/\{|\}/g, '').split(".") || [],
      currVal = obj || {};
      for (var ix = 0, len = tokens.length; ix < len; ix++) {
        if ((typeof currVal == 'undefined') || (currVal === null)) {
          break;
        }
        var currentToken = tokens[ix];
        currVal = currVal[currentToken];
      }
      return currVal;
    },
    /**
     * debounce returns a new function than when called will
     * execute the function and prevent any other calls to be executed
     * if they happen inside the threshold
     *
     * This is useful to execute just the first call of a series of calls inside a
     * threshold
     *
     * @param {Function} f      the function to debounce
     * @param {Integer} ms      the number of miliseconds to wait. If any other call
     *                          is made before that theshold it will be discarded.
     * @param {Object} ctx      the context on which this function will be executed
     *                          (the this object inside the function wil be set to this context)
     */
    debounce: function(f, ms, ctx){
      //just return the wrapper function
      return function(){
        //if this is the first time of the sequence of calls to this function 
        if (f.timer == null) {
          //store the original arguments used to call this function
          var args = arguments;
          //execute it inmediately
          (function(){
            //call the function with the ctx and the original arguments
            f.apply(ctx, args);
            //set the timer
            f.timer = setTimeout(function(){
              //to make sure the next set of calls will be executing the first call as soon as possible
              f.timer = null;
            }, ms || 1);
          })();
          return;
        }
      };
    },
    /**
     * throttle returns a new function than when called will cancel any previous not executed
     * call reseting the timer again for a new period of time.
     *
     * This is usfeful to execute only the last call of a series of call within a time interval
     *
     * @param {Object} f
     * @param {Object} ms
     * @param {Object} ctx
     */
    throttle: function(f, ms, ctx){
      return function(){
        var args = arguments;
        clearTimeout(f.timer);
        f.timer = setTimeout(function(){
          f.timer = null;
          f.apply(ctx, args);
        }, ms || 0);
      }
    },
    /**
     * define a namespace object
     * @param {Object} ns
     */
    ns: function(ns){
      if (!ns) 
        return;
      var nsParts = ns.split(".");
      var root = window;
      for (var i = 0, len = nsParts.length; i < len; i++) {
        if (typeof root[nsParts[i]] == "undefined") {
          root[nsParts[i]] = {};
        }
        root = root[nsParts[i]];
      }
      return root;
    },
    events : {
      DOWN : !kno.isiPad ? 'mousedown.events' : 'touchstart.events',
      UP: !kno.isiPad  ? 'mouseup.events' : 'touchend.events',
      MOVE : !kno.isiPad ? 'mousemove.events' : 'touchmove.events'
    },
    isNull : function (val) {
      return typeof val == "undefined" || val == null;
    },
    localStorageEnabled : function () {
      if (kno.isNull(flags.supportsLocalStorage)) {
         w = kno.w || window;
         try {
          flags.supportsLocalStorage =  'localStorage' in w && w['localStorage'] !== null;
        } catch (e) {
          flags.supportsLocalStorage = false;
        }
      } 
      return flags.supportsLocalStorage;
    },
    /**
     * return a random number between a min and a max value
     */
    rand : function() {
      var min, max, args = arguments;
      //if only one argument is provided we are expecting to have a value between 0 and max
      if (args.length == 1) {
        max = args[0];
        min = 0;
      }
      //two arguments provided mean we are expecting to have a number between min and max
      if (args.length >= 2) {
        min = args[0];
        max = args[1]
  
        if (min > max) {
          min = args[1];
          max = args[0];
        }
      }
      return min + Math.floor(Math.random() * (max - min));
    },
    escapeHTML : function (html) {
      var text = "";
      html = $.trim(html);
      if (html != "") {
        text = $('<pre />').text(html).html();
      }
      return text;
    },
 
    getString : function (key) {
      key = $.trim(key);
      
      if (key != '')  {
        window.__i18n = window.__i18n || {};
        str = $.trim(window.__i18n[key]);
        if (str == '') {
          str = window.__i18n[key] = key;
        }
      }
      //safer way to convert a pseudo array to an object array
      var args = Array.prototype.slice.call(arguments);
      if (args.length > 1) {
        args = args.slice(1);
        args = [str].concat(args);
        str = kno.format.apply(kno, args);
      }
      return str;
    },

    isiPad : window.isiPad || /^(iPad)$/.test(navigator.platform)
  });
  
  window.kno = kno;

 // Stub out console object if it's not available
  if (!window.console) {
    var nilf = function(){
    };
    window.console = {};
    $.each('assert count debug dir dirxml error group groupEnd info log profile profileEnd profiles time timeEnd trace warn'.split(/\s+/), function(i, k){
      console[k] = nilf;
    });
  };
  window.__logEnabled = false; //set to false to mute log and debug calls
  if (window.console) {
    
    oldLog = window.console.log;
    oldDebug = window.console.debug;

    window.console.log = function () {
      if (window.__logEnabled) {
        oldLog.apply(window.console, arguments);
      }
    }

    window.console.debug = function () {
      if (window.__logEnabled) {
        oldDebug.apply(window.console, arguments);
      }
    }
  }
  
  //alias for kno.getString
  window.__e = kno.getString;
  
  //fix for firefox styles
  
  $(function () {
    var userAgent = navigator.userAgent.toLowerCase();
    $.browser.chrome = /chrome/.test(navigator.userAgent.toLowerCase()); 
    var $html = $('html');
    var isFF = $.browser.mozilla;
    
    if (isFF) {
      $html.addClass('ff');
    }
    if(kno.isiPad) {
      $html.addClass('ipad');
    }

    if ($.browser.chrome) {
      $html.addClass('chrome');
      $.browser.safari = false;
    }

    if ($.browser.safari) {
      $html.addClass('safari');
    }
  });
  
})(jQuery);

(function($){
  var TOUCH_START_EVENT = kno.isiPad ? 'touchstart' : 'mousedown';
  var TOUCH_END_EVENT = kno.isiPad ? 'touchend' : 'mouseup';
  var CLICK_EVENT = kno.isiPad ? 'click' : 'click';
  var TOUCH_MOVE_EVENT = kno.isiPad ? 'touchmove' : 'mousemove';
  
  $.widget('ui.ipadDraggable', {
    /**
     * Creates the ui and initialize dependencies
     */
    _create: function(){
      var target = this.element;
      var handle = $.trim(this.options.handle);
      
      var ele = null;
      if (this.element.length > 0) {
        ele = this.ele = this.element[0];
      }
      var me = this;
      
      target.bind(TOUCH_START_EVENT, function(e){
        if (handle == '' || $(e.target).closest(handle).length > 0) {
          me._trigger('start', {});
          me.isDragging = true;
        }
      });
      var onMove = function(e){
        try {
          if (!me.isDragging) 
            return;
          if (!ele) 
            return;
          var evt = e.originalEvent;
          if (kno.isiPad) {
            evt = evt.touches[0];
          }
          me.x = evt.clientX;
          me.y = evt.clientY;
          
          var lastX = me.lastX || me.x;
          var lastY = me.lastY || me.y;
          
          var dx = lastX - me.x;
          var dy = lastY - me.y;
          
          
          var transform = window.getComputedStyle(ele).webkitTransform;
          var matrix,x,y;
          if (transform != 'none') {
            matrix = new WebKitCSSMatrix(transform);
            matrix.e -= (dx);
            matrix.f -= (dy);
            x = matrix.e;
            y = matrix.f;
          }
          else {
            x = 0;
            y = 0;
          }
          
          
          ele.style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px,0)';
          me.lastX = me.x;
          me.lastY = me.y;
          me._trigger('drag', {});
        } 
        catch (e) {
          console.error('move', e.message);
        }
      };
      
      onMove = kno.debounce(onMove, 0);
      
      $(document).bind(TOUCH_MOVE_EVENT, function(e){
        onMove(e);
      }).bind(TOUCH_END_EVENT, function(e){
        me.isDragging = false;
        me.lastX = null;
        me.lastY = null;
        me._trigger('stop', {});
        
      });
    },
    
    reset : function () {
      this.ele.style.webkitTransform = '';
    },
    
    destroy: function(){
    
    }
  });
  
  $.extend($.ui.ipadDraggable, {
    /* defaults */
    defaults: {
      handle: null
    }
  });

})(jQuery);

