﻿'use strict';

define([], function () {
  String.prototype.customReplace = function (index, len, str, repeat, repeatTimes) {
    var _defaultStr = '*';
    str             = typeof str === 'undefined' ? _defaultStr : (typeof str === 'bool' ? _defaultStr : str);
    repeat          = typeof repeat === 'undefined' ? true : (typeof str === 'bool' ? str : repeat);
    repeatTimes     = typeof repeatTimes === 'undefined' ? (repeat ? len : 0) : repeatTimes;
    var _str        = '';
    if (repeat)
      for (var i = 0; i < repeatTimes; i++)
        _str += str;
    return _self.substr(0, index) + _str + _self.substr(len + repeatTimes, _self.length);
  };

  /*
   * e.g.
   * var d=new Date();
   * var str=d.Format("yyyy-MM-dd  hh:mm:ss");
   * console.log(str);
   */
  Date.prototype.Format = function (formatStr) {
    var str  = formatStr;
    var Week = ['日', '一', '二', '三', '四', '五', '六'];

    str       = str.replace(/yyyy|YYYY/, this.getFullYear());
    str       = str.replace(/yy|YY/, (this.getYear() % 100) > 9 ? (this.getYear() % 100).toString() : '0' + (this.getYear() % 100));
    var month = this.getMonth() + 1;
    str       = str.replace(/MM/, month > 9 ? month.toString() : '0' + month);
    str       = str.replace(/M/g, month);

    str = str.replace(/w|W/g, Week[this.getDay()]);

    str = str.replace(/dd|DD/, this.getDate() > 9 ? this.getDate().toString() : '0' + this.getDate());
    str = str.replace(/d|D/g, this.getDate());

    str = str.replace(/hh|HH/, this.getHours() > 9 ? this.getHours().toString() : '0' + this.getHours());
    str = str.replace(/h|H/g, this.getHours());
    str = str.replace(/mm/, this.getMinutes() > 9 ? this.getMinutes().toString() : '0' + this.getMinutes());
    str = str.replace(/m/g, this.getMinutes());

    str = str.replace(/ss|SS/, this.getSeconds() > 9 ? this.getSeconds().toString() : '0' + this.getSeconds());
    str = str.replace(/s|S/g, this.getSeconds());
    str = str.replace(/fff/g, this.getMilliseconds());
    return str;
  };

  var Utils = function () {

    var _self = this;

    var _vTag = '[v]';

    var _opTipsContent = '<p></p><p class="text-center text-warning"><i class="glyphicon glyphicon-info-sign"></i>&nbsp;&nbsp;处理中，请稍后。请勿关闭窗口。</p>';

    var _modalConfig = {
      status: {
        success: {
          title: 'success',
          style: 'text-success',
          icon: 'glyphicon-ok'
        },
        failed: {
          title: 'failed',
          style: 'text-danger',
          icon: 'glyphicon-remove'
        },
        warning: {
          title: 'warning',
          style: 'text-warning',
          icon: 'glyphicon-exclamation-sign'
        },
        info: {
          title: 'info',
          style: 'text-primary',
          icon: 'glyphicon-info-sign'
        }
      },
      tmpl: {
        icon: '{{icon}}',
        style: '{{style}}',
        msg: '{{msg}}',
        getTmpl: function () {
          return '<p></p><p class="text-center ' + this.style + '"><i class="glyphicon ' + this.icon + '"></i>&nbsp;&nbsp;' + this.msg + '</p>';
        },
        getContent: function (style, icon, msg) {
          var tmpl = this.getTmpl();
          return tmpl.replace(this.style, style).replace(this.icon, icon).replace(this.msg, msg);
        }
      },
      evt: {
        show: 'show',
        hide: 'hide',
        onShow: 'show.bs.modal',
        onHide: 'hide.bs.modal'
      }
    };

    var _formVerifyStatusStyle = {
      success: 'has-success',
      error: 'has-error'
    };

    var _dateConfig = {
      regex: {
        iso: /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/,
        ms: /^\/Date\((d|-|.*)\)[\/|\\]$/
      },
      format: {
        date: 'date',
        millionseconds: 'millionseconds'
      }
    };

    var _commonModalID = '#common-modal';

    var _getTimestamp = function () {
      return (new Date()).getTime();
    };

    var _getSiteProtocol = function () {
      return window.location.protocol;
    };

    var _getTs = function (ts, ver) {
      var _ts = '';
      if (typeof ts === 'undefined' || ts === true)
        _ts = _self.getTimestamp();
      if (ts === false)
        _ts = ver;

      return ('?' + _self.vTag + '=' + _ts);
    };

    var _formatNumber = function (value, decimal) {
      if (typeof decimal === 'undefined')
        decimal = 2;
      //console.log('value:', value);
      if (value === '' || isNaN(Number(value)) || value.indexOf('0') === 0) return '';

      if (value.indexOf('.') !== -1) {
        var arr = value.split('.');
        value   = arr[0] + (decimal > 0 ? ('.' + arr[1].substr(0, decimal)) : '');
      }

      //var dotIndex = value.indexOf('.');
      //if (dotIndex !== -1 && value.substring(dotIndex).length > 2) {
      //  value  = value.substr(0, dotIndex + 3);
      //}

      return value;
    };

    var _validateIDCard = function (value) {
      //身份证的地区代码对照
      var aCity     = {
        11: "北京",
        12: "天津",
        13: "河北",
        14: "山西",
        15: "内蒙古",
        21: "辽宁",
        22: "吉林",
        23: "黑龙江",
        31: "上海",
        32: "江苏",
        33: "浙江",
        34: "安徽",
        35: "福建",
        36: "江西",
        37: "山东",
        41: "河南",
        42: "湖北",
        43: "湖南",
        44: "广东",
        45: "广西",
        46: "海南",
        50: "重庆",
        51: "四川",
        52: "贵州",
        53: "云南",
        54: "西藏",
        61: "陕西",
        62: "甘肃",
        63: "青海",
        64: "宁夏",
        65: "新疆",
        71: "台湾",
        81: "香港",
        82: "澳门",
        91: "国外"
      };
      //获取证件号码
      var person_id = value;
      //合法性验证
      var sum       = 0;
      //出生日期
      var birthday;
      //验证长度与格式规范性的正则
      var pattern   = new RegExp(/(^\d{15}$)|(^\d{17}(\d|x|X)$)/i);
      if (!pattern.exec(person_id))
        return false;

      //验证身份证的合法性的正则
      pattern = new RegExp(/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/);
      if (pattern.exec(person_id)) {
        //获取15位证件号中的出生日期并转位正常日期
        birthday = "19" + person_id.substring(6, 8) + "-" + person_id.substring(8, 10) + "-" + person_id.substring(10, 12);
      } else {
        person_id = person_id.replace(/x|X$/i, "a");
        //获取18位证件号中的出生日期
        birthday  = person_id.substring(6, 10) + "-" + person_id.substring(10, 12) + "-" + person_id.substring(12, 14);

        //校验18位身份证号码的合法性
        for (var i = 17; i >= 0; i--) {
          sum += (Math.pow(2, i) % 11) * parseInt(person_id.charAt(17 - i), 11);
        }
        if (sum % 11 != 1) {
          return false;
        }
      }
      //检测证件地区的合法性
      if (aCity[parseInt(person_id.substring(0, 2))] == null) {
        return false;
      }
      var dateStr = new Date(birthday.replace(/-/g, "/"));

      if (birthday != (dateStr.getFullYear() + "-" + _self.appendZero(dateStr.getMonth() + 1) + "-" + _self.appendZero(dateStr.getDate()))) {
        return false;
      }

      return true;
    };

    var _appendZero = function (temp) {
      if (temp < 10) {
        return "0" + temp;
      } else {
        return temp;
      }
    };

    var _adjustParentIframeHeight = function (iframeTagId, offset) {
      offset       = offset || 30;
      var theFrame = $(iframeTagId, parent.document.body);
      if (AdjustParentIframeHeight.arguments[1])
        theFrame.height(parseInt(AdjustParentIframeHeight.arguments[1]) + offset);
      else
        theFrame.height($(document.body).height() + offset);
    };

    var _getItemIndex = function (elm, item) {
      return $(elm).index(item);
    };

    var _buildModalContent = function (data) {
      var _status = _modalConfig.status;
      var set, msg;
      if (typeof data === 'object') {
        set = data.Code < 0 ? _status.failed : _status.success;
        msg = data.Msg;
      } else {
        set = _status.info;
        msg = data;
      }

      return _modalConfig.tmpl.getContent(set.style, set.icon, msg);
    };

    var _setModalContent = function (modalID, data) {
      var content = _buildModalContent(data);
      $(modalID).find('.modal-body').html(content);
    };

    var _showModal = function (modalID, onShow, onHide) {
      $(modalID).unbind()
        .on(_modalConfig.evt.onShow, function (e) {
          if (typeof onShow === 'function')
            onShow();
        })
        .on(_modalConfig.evt.onHide, function (e) {
          if (typeof onHide === 'function')
            onHide();
        })
        .modal(_modalConfig.evt.show);
    };

    var _hideModal = function (modalID, onHide) {
      $(modalID)
        .on(_modalConfig.evt.onHide, function (e) {
          if (typeof onHide !== 'undefined')
            onHide();
        })
        .modal(_modalConfig.evt.hide);
    };

    var _bindModalEvent = function (modalID, event, func) {
      var e = '';
      switch (event) {
        case modelEvent.show:
          e = _modalConfig.evt.onShow;
          break;
        case modelEvent.hide:
          e = _modalConfig.evt.onHide;
          break;
      }
      if (e != '' && typeof func === 'function') {
        $(modalID).off(e)
          .on(e, func());
      }
    };

    var _tabSwitch = function (elm, active, ext) {
      var _active = typeof active === 'string' ? active : 'active';
      if (typeof ext === 'undefined')
        if (typeof active === 'function')
          ext = active;
      $(elm).off('click').on('click', function () {
        $(this).addClass(_active).siblings(elm).removeClass(_active);
        if (typeof ext !== 'undefined')
          ext();
      });
    };

    var _formVerify = function (elm, container, hasError, ext) {
      var addClass     = _formVerifyStatusStyle.success,
          removeClasss = _formVerifyStatusStyle.error;
      if (hasError) {
        addClass     = _formVerifyStatusStyle.error;
        removeClasss = _formVerifyStatusStyle.success;
      }
      var $elm       = typeof elm === 'object' ? elm : $(elm);
      var $container = container === '' ? $elm : $elm.closest(container);
      $container.removeClass(removeClasss).addClass(addClass);
      var $errMsgContainer = $container.find('.err-msg');
      if ($errMsgContainer) {
        if (!hasError)
          $errMsgContainer.html('');
      }

      if (ext)
        ext();
    };

    var _removeFormVerifyStatus = function () {
      $('.has-success,.has-error').removeClass('has-success has-error');
    };

    var _showBtnPlaceholder = function (elm) {
      elm.hide().siblings('.btn-placeholder').css('display', 'inline-block');
    };

    var _hideBtnPlaceholder = function (elm) {
      elm.show().siblings('.btn-placeholder').hide();
    };

    var _getUrlPath = function () {
      return window.location.pathname.toLowerCase();
    };

    var _removeAppendOption = function (elm) {
      elm.find('option:gt(0)').remove();
    };

    var _appendOption = function (elm, value, text) {
      $("<option></option>").prop({value: value, text: text}).appendTo(elm);
    };

    var _dateParser = function (value, format) {
      format = format || _dateConfig.format.millionseconds;
      if (typeof value === 'string') {
        var a = _dateConfig.regex.iso.exec(value);
        if (a)
          return format === _dateConfig.format.millionseconds ? value : new Date(value);

        a = _dateConfig.regex.ms.exec(value);
        if (a) {
          var b = a[1].split(/[-+,.]/);
          var v = b[0] ? +b[0] : 0 - +b[1];
          return format === _dateConfig.format.millionseconds ? v : (new Date(v));
        }
      }
      return value;
    };

    this.vTag          = _vTag;
    this.commonModalID = _commonModalID;

    this.getTimestamp = function () {
      return _getTimestamp();
    };

    this.getSiteProtocol = function () {
      return _getSiteProtocol();
    };

    this.getTs = function (ts, ver) {
      return _getTs(ts, ver);
    };

    this.formatNumber = function (value, decimal) {
      return _formatNumber(value, decimal);
    };

    this.validateIDCard = function (value) {
      return _validateIDCard(value);
    };

    this.appendZero = function (temp) {
      return _appendZero(temp);
    };

    this.adjustParentIframeHeight = function (iframeTagId, offset) {
      _adjustParentIframeHeight(iframeTagId, offset);
    };

    this.getItemIndex = function (elm, item) {
      return _getItemIndex(elm, item);
    };

    this.setModalContent = function (modalID, data) {
      _setModalContent(modalID, data);
    };

    this.setCommonModalContent = function (data) {
      this.setModalContent(this.commonModalID, data);
    };

    this.showModal = function (modalID, data, onShow, onHide) {
      this.setModalContent(modalID, data);
      _showModal(modalID, onShow, onHide);
    };

    this.showCommonModal = function (data, onShow, onHide) {
      this.showModal(this.commonModalID, data, onShow, onHide);
    };

    this.hideModal = function (modalID, onHide) {
      _hideModal(modalID, onHide);
    };

    this.bindModalEvent = function (modalID, event, func) {
      _bindModalEvent(modalID, event, func);
    };

    this.buildModalContent = function (data) {
      return _buildModalContent(data);
    };

    this.animate = function (elm, opt, duration, callback) {
      elm.animate(opt, duration, function () {
        if (callback)
          callback();
      });
    };

    this.tabSwitch = function (elm, active, ext) {
      _tabSwitch(elm, active, ext);
    };

    this.formVerify = function (elm, container, hasError, ext) {
      _formVerify(elm, container, hasError, ext);
    };

    this.removeFormVerifyStatus = function () {
      _removeFormVerifyStatus();
    };

    this.showBtnPlaceholder = function (elm) {
      _showBtnPlaceholder(elm);
    };

    this.hideBtnPlaceholder = function (elm) {
      _hideBtnPlaceholder(elm);
    };

    this.getUrlPath = function () {
      return _getUrlPath();
    };

    this.apiFailed = function (rst) {
      console.log('api failed');
    };

    this.removeAppendOption = function (elm) {
      _removeAppendOption(elm);
    };

    this.appendOption = function (elm, value, text) {
      _appendOption(elm, value, text);
    };

    this.dateParser = function (value, format) {
      return _dateParser(value, format);
    };

    this.getSelectedOptionText = function (elm) {
      return elm.find('option:selected').text();
    };

    this.showAddCartEffect = function (cart, img) {
      var css = {
        'opacity': '0.5',
        'position': 'absolute',
        'height': '150px',
        'width': '150px',
        'z-index': '100'
      };
      if (img) {
        var imgclone = img.clone()
          .offset({
            top: img.offset().top,
            left: img.offset().left
          })
          .css(css)
          .appendTo($('body'))
          .animate({
            'top': cart.offset().top + 10,
            'left': cart.offset().left + 10,
            'width': 75,
            'height': 75
          }, 1000, 'easeInOutExpo');

        // setTimeout(function () {
        //   cart.effect("shake", {
        //     times: 2
        //   }, 200);
        // }, 1500);

        imgclone.animate({
          'width': 0,
          'height': 0
        }, function () {
          $(this).detach()
        });
      }
    };

    this.getChkedItemValueArray = function (chk) {
      return $(chk + ':checked').map(function () {
        return $(this).val();
      }).get();
    };

    this.getElmsData = function (elm, dataName) {
      return $(elm).map(function () {
        return $(this).data(dataName);
      }).get();
    };

    this.getChkedItemValueStr = function (chk) {
      return this.getChkedItemValueArray(chk).join(',');
    };

    this.sum = function (item, data) {
      var t = 0;
      $(item).each(function () {
        t += $(this).data(data);
        // console.log('item-t:', t);
      });
      return t;
    };

    this.quantityCtrlEventListener = function (elm, callback, userService) {
      var _utils = this;
      $(elm).on('click', function () {

        console.log(userService);

        var $this = $(this);

        var v  = $this.data('v'),
            id = $this.data('id');

        var qCtrl = $this.siblings('input.quantity');
        var q     = Number(qCtrl.val());
        if ($this.hasClass('minus')) {
          if (q === 1)
            return;
          q--;
        } else {
          q++;
        }


        userService.updateCart(id, q).then(function (rst) {

          qCtrl.val(q);
          var newTp = q * v;
          $(elm + '-' + id).data('tp', newTp);
          $('#cart-quantity-' + id).data('tp', newTp);

          callback(id, newTp);

        }, function (rst) {
          _utils.apiFailed(rst);
        });

      });
    };

    this.quantityInputEventListener = function (elm, regex, callback, userService) {
      $(elm).on('blur', function () {
        var $this = $(this);
        var q     = $this.val();

        if (regex.test(q)) {

          var v   = $this.data('v'),
              id  = $this.data('id'),
              max = $this.data('max'),

              q   = Number(q);
          if (q === 0) {
            $this.val(1);
            q = 1;
          } else {

          }

          userService.updateCart(id, q).then(function (rst) {

            var newTp = q * v;
            $this.siblings('.ctrl-symbol').data('tp', newTp);
            $this.data('tp', newTp);

            callback(id, newTp);

          }, function (rst) {
            _utils.apiFailed(rst);
          });

        }

      });
    };

    this.setAwardStep = function (currentIndex) {
      $('.award-step:eq(' + currentIndex + ')').addClass('current').siblings().removeClass('current');
      $('.award-step:lt(' + currentIndex + ')').addClass('done');
    };

    this.htmlCountdown = function (elm, v) {
      $(elm).html(this.appendZero(v));
    };

    this.commonCountdown = function (v, elm, duration, callback) {

      var o = this;

      var v_min = v.min, v_sec = v.sec, v_ms = v.ms;

      var elm_min = elm.min, elm_sec = elm.sec, elm_ms = elm.ms;

      o.htmlCountdown(elm_min, v_min);
      o.htmlCountdown(elm_sec, v_sec);
      o.htmlCountdown(elm_ms, v_ms);

      var msInterval = window.setInterval(function () {

        v_ms--;

        if (v_ms < 0) {

          v_sec--;

          if (v_sec < 0) {

            v_min--;
            // console.log('min:', v_min, 'sec:', v_sec, 'ms:', v_ms);

            if (v_min < 0) {

              v_min = 0;

              if (v_min === 0 && v_sec < 0 && v_ms < 0) {

                console.log('complete');

                o.htmlCountdown(elm_sec, 0);
                o.htmlCountdown(elm_ms, 0);
                clearInterval(msInterval);

                if (callback) {
                  callback();
                }

                return;
              }
            }

            o.htmlCountdown(elm_min, v_min);
            v_sec = 59;

          }

          o.htmlCountdown(elm_sec, v_sec);
          v_ms = 99;

        }

        o.htmlCountdown(elm_ms, v_ms);

      }, duration);

    };

    this.checkRange = function (q, max) {
      return q > max;
    };

    this.validateIptRange = function (elm) {
      var q = elm.val();
      if (!/^[0-9]*$/.test(q)) {
        q = 1;
        elm.val(q);
      }
      q = Number(q);
      if (q === 0) {
        q = 1;
        elm.val(q);
      }
      var max = Number(elm.data('max'));
      if (q > max) {
        elm.val(max);
      }
    };

    this.addQuantityChangeEventListener = function (minusCtrlElm, plusCtrlElm, qIptElm, callback) {
      var _u = this;
      $(qIptElm).on('keyup', function () {
        _u.validateIptRange($(this));
      }).on('blur', function () {
        var $this = $(this);
        if ($this.val() == '')
          $this.val(1);

        if (callback) {
          callback($this.data('id'), $this.val(), $this.data('v'));
        }

      });
      $(minusCtrlElm).on('click', function () {
        var qElm = $(this).siblings('.quantity');
        var q    = Number(qElm.val());
        // var max = Number(qElm.data('max'));
        if (q <= 1)
          return;
        q--;
        qElm.val(q);

        if (callback) {
          callback($(this).data('id'), q, $(this).data('v'));
        }

      });
      $(plusCtrlElm).on('click', function () {
        var qElm = $(this).siblings('.quantity');
        var q    = Number(qElm.val());
        var max  = Number(qElm.data('max'));
        q++;
        if (q > max)
          return;
        qElm.val(q);

        if (callback) {
          callback($(this).data('id'), q, $(this).data('v'));
        }

      });
    };

    this.convertMSTime = function (timeStr) {
      return new Date(eval('(' + timeStr.replace(/\/Date\((\d+)\)\//gi, "new Date($1)") + ')'));
    };

    this.request = function (requestContext, success, failed) {
      requestContext.then(function (rst) {
        if(Number(rst.Code) < 0){

          if (failed) {
            failed(rst);
          } else {
            alert(rst.Msg);
          }

          return false;

        }

        success(rst);

      }, function (rst) {

      });
    }

  };

  return new Utils();
});
