var CONFIG = CONFIG || {};
CONFIG.SEARCH_TIMEOUT = 300; // 検索を開始する秒数（ミリ秒）
CONFIG.SEARCH_MIN_LENGTH = 0; // 検索を開始する文字数

/**
 * 実体参照文字、HTMLタグを含む文字列から、テキスト部分を抽出
 * - 実体参照文字を文字列に変換
 * - HTMLタグを除去
 *
 * @method toText
 * @param  {[type]} string [description]
 * @return {[type]}        [description]
 */
function toText(string) {
  var text;

  text = $('<textarea />').html(string).text();
  return text.replace(/(<([^>]+)>)/ig,"");
}

// var IEuser = null;

// var userAgent = window.navigator.userAgent.toLowerCase();
// // 使用ブラウザ判定
// if( userAgent.match(/(msie|MSIE)/) || userAgent.match(/(T|t)rident/) ) {
//   var IEuser = true;
//   // IEのバージョン
//   // var ieVersion = userAgent.match(/((msie|MSIE)\s|rv:)([\d\.]+)/)[3];
//   // ieVersion = parseInt(ieVersion);
// } else {
//   var IEuser = false;
// }
/**
* エラー一覧
*
* @param arg
* @constructor
*/
var ErrorView = function(arg) {
  this.$el = arg.$el;
  this.template = arg.template;
  this.compiled = _.template(this.template);
};
ErrorView.prototype.render = function(items, error_type) {
  var error_cd_flg;
  // エラーコード列は［表示器］の場合のみ表示（［作画ソフト］のエラー情報にはエラーコードはない）
  error_cd_flg = (error_type === 'displayError');

  this.$el.html(this.compiled({items: items, error_cd_flg: error_cd_flg}));
};

/**
* エラー一覧データ
*
* @param arg
* @constructor
*/
var ErrorModel = function(arg) {
  this.data = arg.data || null;
};
ErrorModel.prototype.find = function(condition,tagcondition) {
  var keyword;
  var tags;
  // var w;
  // var t;
  // 初期値とマージ
  condition = _.merge({
    keyword: null
  }, condition);
  // if(IEuser === true){
  //   w = GetCookie('word=');
  //   t = GetCookie('tag=');
  //   t = JSON.parse(t);
  // }else{
  //   w = localStorage.getItem('searchword');
  //   t = JSON.parse(localStorage.getItem('searchtag'));
  // }
  
  // if(w){
  //   condition.keyword = w
  // }
  // if(t != null){
  //   if(t.length > 0){
  //     tagcondition = t;
  //   }
  // }

  // 検索条件が未指定の場合、全てを取得
  if (! _.isString(condition.keyword) && tagcondition.length == 0) {
    return this.data.collection;
  }

  // エラーコードのタグ一覧取得
  for(var i=0, len=data.collection.length; i<len; i++) {
    var k = 0;
    data.collection[i]["error_t"] = new Array();
    for(var j in data.collection[i]) {
        // タグデータのみ取得
        if(j.indexOf("tag") != -1){
          //空白タグ削除
          if(data.collection[i][j] !==""){
            data.collection[i]["error_t"][k] = data.collection[i][j];
            k++;
          }
        }
    }
    // イメージ画像が存在した時
    if((data.collection[i]['Limitation'].match(/\[IMAGE:.+?\]/g)||[]).length > 0){
      var imag = data.collection[i]['Limitation'].match(/\[IMAGE:.+?\]/g);
      // 画像をHTMLの書式へ変更
      for(var k = 0; k < imag.length; ){
        var imagetag = imag[k].replace("[IMAGE:","<br><img src=img/fig/");
        imagetag     = imagetag.replace("]","><br>");
        data.collection[i]['Limitation'] = data.collection[i]['Limitation'].replace(imag[k],imagetag);
        k++;
      }
    }
  }

  // 絞り込み
  keyword = _.toLower(condition.keyword);
  //検索対象データ判定
  return _.filter(this.data.collection, function(item) {
    // 全角文字は半角へ
    var halfsizeLimitation = zenkakuToHankaku(toText(item['Limitation']));
    var halfsizekeyword    = zenkakuToHankaku(keyword);
    if (
      findtag(item, tagcondition) &&
      (_.includes(_.toLower(halfsizeLimitation), halfsizekeyword))
    ){
      return true;
    }
    return false;
  });

};

/**
 * GETパラメータを取得するメソッド
 * 
 * 1. 「key=value」形式以外のパラメータは認識しない
 * 2. 「tag=◯◯」のパラメータは、"tags"の配列にpush（複数指定する場合は「tag=◯◯&tag=××」）
 * 3. それ以外のキーワードのパラメータは、そのまま保持
 *    （同名のキーワードがあった場合、後に指定したものを保持）
 * 
 * ?tag=Operation%20Log&taggg=Backup%20Memory&hoge[]=fuga&hoge[]=fugafuga&foobar&tag=Data%20Logging
 * ↓
 * [ "tag=Operation%20Log", "taggg=Backup%20Memory", "hoge[]=fuga", "hoge[]=fugafuga", "foobar", "tag=Data%20Logging"]
 * ↓
 * {
 *   hoge[]: "fugafuga",
 *   tags: ['"Operation Log"', '"Data Logging"'],
 * }
 * 
 * @return 配列化されたGETのパラメータ
 */
var getUrlVars = function () {
  var vars = { tags: [] };

  // & で区切った key=value のリストを取得
  var param = location.search.substring(1).split('&');

  for (var i = 0; i < param.length; i++) {
    var keyValue, result, key, value;

    keyValue = param[i];
    result = /^(.+)=(.+)$/.exec(keyValue);

    // 「=」を含まない場合はスキップ
    if (result === null) {
      continue;
    }

    key = result[1];
    value = result[2];

    if (key === 'tag') {
      vars.tags.push(decodeURI('"' + value + '"'));
    } else {
      vars[key] = decodeURI(value);
    }
  }

  return vars;
};

/**
* 選択されたタグと制限事項のタグを比較するメソッド
* @param item 制限事項
* @param tagcondition チェックされたタグ
* @return boolean true:存在する false:存在しない
*/
function findtag(item, tagcondition) {
  if(tagcondition.length > 0){
    var flg;
    for(var i = 0; i < tagcondition.length; i++){
      flg = false;
      for(var j = 0; j < item['error_t'].length; j++){
        // 所持タグと検索条件タグが一致したもののみ取得
        if(tagcondition[i] === toText(item['error_t'][j])){
          flg = true;
          break;
        }
      }
      if(!flg){
        return false;
      }
    }
  }
  return true;
}
/**
* 全角を半角にするメソッド
* @param  対象文字列
* @return 対象文字列を半角に変更した文字
*/
function zenkakuToHankaku(str) {
    var regex = /[Ａ-Ｚａ-ｚ０-９！＂＃＄％＆＇（）＊＋，－．／：；＜＝＞？＠［＼］＾＿｀｛｜｝]/g;

  // 全角を半角の文字に置換
  str = str.replace(regex, function(s) {
    return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
  })
  .replace(/[‐－―]/g, '-') // ハイフンなど
  .replace(/[～〜]/g, '~')  // チルダ
  .replace(/　/g, ' ');  // スペース

  return str;
}
// 1128凍結
// /**
// * 検索の値を保存するメソッド
// */
// function savewebstorage(){
//   var word = app.getCondition();
//   var tag  = app.getTagCondition();
//   if(IEuser === true){
//     document.cookie = 'word=' + encodeURIComponent(word.keyword);
//     document.cookie = 'tag='  + encodeURIComponent(JSON.stringify(tag));
//   }else{
//     localStorage.setItem('searchword',word.keyword);
//     localStorage.setItem('searchtag',JSON.stringify(tag));
//   }
// }
// /**
// * クッキーの値を取得(検索テキストの値)
// * @param  クッキーのキー値
// * @return クッキーに保存された値
// */
// function GetCookie(name)
// {
//     var result = null;
//     var allcookies = document.cookie;
//     var cookieName = name;
//     var position = allcookies.indexOf(cookieName);
//     // 存在した時
//     if( position != -1 )
//     {
//       var startIndex = position + cookieName.length;
//       var endIndex = allcookies.indexOf( ';', startIndex );
//       if( endIndex == -1 )
//       {
//           endIndex = allcookies.length;
//       }
//       result = decodeURIComponent(allcookies.substring( startIndex, endIndex ) );
//     }

//     return result;
// }
// 1128凍結終
var TagView = function(arg) {
    this.$el = arg.$el;
    this.template = arg.template;
    this.compiled = _.template(this.template);
};
// 検索のタグ一覧を作成
TagView.prototype.render = function(items) {
    this.$el.html(this.compiled({items: items}));
};

var TagModel = function(arg) {
    this.data = arg.data || null;
    this.searchData = arg.searchData || null;
};
TagModel.prototype.find = function(condition) {
  var tag;

  // 初期値とマージ
  condition = _.merge({
    tag: null
  }, condition);

  // 検索条件が未指定の場合、全てを取得
  if (! _.isString(condition.tag)) {
     return this.data;
  }

  // 絞り込み
  tag = _.toLower(condition.tag);

  return _.filter(this.data.collection, function(item) {
    if (_.includes(_.toLower(toText(item['error_t'])), tag)) {
      return true;
    }
    return false;
  });
};

/**
 * クエリ文字列からローカライズされたタグを取得
 *
 * @param str クエリ文字列
 * @returns {*}
 */
TagModel.prototype.findTagByQuery = function(str) {
  var i, result = "";

  // tagSearchでのインデックスを取得
  i = _.indexOf(this.searchData, _.trim(str, "\""));

  // tagsからインデックスを指定して取得
  if (i > -1 && i <= this.data.length) {
    result = this.data[i];
  }

  return result;
};

var App = function App(arg) {
  this.$searchForm = arg.$searchForm;
  this.errorModel = arg.errorModel;
  this.errorView = arg.errorView;
  this.tagModel = arg.tagModel;
  this.tagView = arg.tagView;
};

/**
 * 初期化
 */
App.prototype.initialize = function initialize() {
  // 検索処理を実行
  this.filterTag();
  this.search();
};

/**
 * 検索条件を取得
 *
 * @returns {*}
 */
App.prototype.getCondition = function getCondition() {
  return this.$searchForm.serializeObject();
};
/**
 * 検索条件を取得（tags)
 *
 * @returns tags 選択されたタグ（配列）
 */
App.prototype.getTagCondition = function getTagCondition() {
  //チェックされているタグを所得
  var tags = []

  $('[name="tags"]:selected').each(function(index,element) {
        tags.push(element.value)
  })
  return tags;
};
/**
 * ハイライト処理を実行
 *
 * @param condition
 */
App.prototype.highlight = function highlight(condition) {
  $('.limitext').highlight(condition.keyword);
};

// App.prototype.highlightTag = function highlghtTag(condition) {
//   $('#tag-list').highlight(condition.tag, {
//       className: "tag-highlight"
//   });
// };
/**
 * 検索処理を実行
 */
App.prototype.search = function search() {
  var condition, tagcondition, errorData;
  //検索条件を取得
  condition = this.getCondition();
  //タグ検索条件を取得
  tagcondition  = this.getTagCondition();
  //検索結果のエラー情報取得
  errorData = this.errorModel.find(condition,tagcondition);

  this.errorView.render(errorData, _.get(this.errorModel.data, 'error-type'));

  this.highlight(condition);
};

App.prototype.filterTag = function filterTag(){
    var condition, tag, tagSearch;

    // 検索条件を取得
    condition = this.getCondition();

    // タグ情報を絞り込み
    tagData = this.tagModel.find(condition);

    this.tagView.render(tagData);

    var getparameter = new getUrlVars();
    //　GETパラメータに存在する時はテキストにセットする
    if(getparameter['tags'].length > 0){
      for(var j in getparameter['tags']) {
        tagSearch = getparameter['tags'][j];
        tag = this.tagModel.findTagByQuery(tagSearch);

        // タグデータのみ取得
        $('option[value="' + tag + '"]').prop('selected', true);
      }
      $('.chosen-select').trigger('chosen:updated');
    }
    // //IEユーザの場合
    // else if(IEuser === true){
    //   var t = GetCookie('tag=');
    //   t = JSON.parse(t);
    //   if(t != null){
    //     for(var i = 0; i < t.length; i++){
    //       $('option[value=' + t[i] + ']').prop('selected',true);
    //     }
    //   }
    // }else if(JSON.parse(localStorage.getItem('searchtag')) != null){
    //   var t = JSON.parse(localStorage.getItem('searchtag'));
    //   for(var i = 0; i < t.length; i++){
    //     $('option[value=' + t[i] + ']').prop('selected',true);
    //   }
    // }
    
    // this.highlightTag(condition);
};

var app;
$(function() {

  // 初期設定
  configure(data);

  app = new App({
    $searchForm: $('form'),
    errorModel: new ErrorModel({data: data}),
    errorView: new ErrorView({
      $el: $('table'),
      template: $('#template').text()
    }),
    tagModel: new TagModel({
      data: data.tags,
      searchData: data.tagSearch
    }),
    tagView: new TagView({
        $el: $('#tag-list'),
        template: $('#tag-list-template').text()
    })
  });
  // 初期表示
  app.initialize();

  // 検索条件が変更されたときに更新
  $('.js-condition')
    .observeUpdate(CONFIG.SEARCH_TIMEOUT, CONFIG.SEARCH_MIN_LENGTH)
    .bind('change update', function() {
      // savewebstorage();
      app.search();
    });

  $('.js-tagcheck')
    .observeUpdate(CONFIG.SEARCH_TIMEOUT, CONFIG.SEARCH_MIN_LENGTH)
    .bind('change', function() {
      // savewebstorage();
      app.search();
    });

  $('body')
    .on('click','.literal-tag', function(){
      var clicked = $(this).text();
      $('option[value=\"' + clicked + '\"]').prop('selected',true);
      // savewebstorage();
      app.search();
      $('.chosen-select').trigger('chosen:updated');
    });

  // $('.js-tag')
  //   .observeUpdate(CONFIG.SEARCH_TIMEOUT, CONFIG.SEARCH_MIN_LENGTH)
  //   .bind('change update', function() {
  //     app.filterTag();
  //   });
  $(".chosen-select").chosen({no_results_text: "該当無し", search_contains:true});

  //　GETパラメータに存在する時はテキストにセットする
  var getparameter = new getUrlVars();
  if('text' in getparameter){
    $('input[name=keyword]').val(getparameter.text).change()
  }
  // IE使用ユーザの場合
  // else if(IEuser === true){
  //   var w = GetCookie('word=');
  //   $('input[name=keyword]').val(w).change();
  // }
  // else{
  //   var w = localStorage.getItem('searchword');
  //   $('input[name=keyword]').val(w).change();
  // }
});

(function($){ 
    $(function(){
        // スクロールが発生した時に処理を行う
        $(window).scroll(function () {
 
            // var $table = $(".detable");          // テーブルの要素を取得
            // var $thead = $table.children("thead");  // thead取得
            // var toffset = $table.offset();          // テーブルの位置情報取得
            // // テーブル位置+テーブル縦幅 < スクロール位置 < テーブル位置
            // if(toffset.top + $table.height()< $(window).scrollTop()
            //   || toffset.top > $(window).scrollTop()){
            //     // クローンテーブルが存在する場合は消す
            //     var $clone = $("#clonetable");
            //     if($clone.length > 0){
            //         $clone.css("display", "none");
            //     }
            // }
            // // テーブル位置 < スクロール位置 < テーブル位置+テーブル縦幅
            // else if(toffset.top < $(window).scrollTop()){
            //     // クローンテーブルが存在するか確認
            //     var $clone = $("#clonetable");
            //     if($clone.length == 0){
            //         // 存在しない場合は、theadのクローンを作成
            //         $clone= $thead.clone(true);
            //         // idをclonetableとする
            //         $clone.attr("id", "clonetable");
            //         // body部に要素を追加
            //         $clone.appendTo("body");
            //         // theadのCSSをコピーする
            //         StyleCopy($clone, $thead);
            //         // theadの子要素(tr)分ループさせる
            //         for(var i = 0; i < $thead.children("tr").length; i++)
            //         {
            //             // i番目のtrを取得
            //             var $theadtr = $thead.children("tr").eq(i);
            //             var $clonetr = $clone.children("tr").eq(i);
            //             // trの子要素(th)分ループさせる
            //             for (var j = 0; j < $theadtr.eq(i).children("th").length; j++){
            //                 // j番目のthを取得
            //                 var $theadth = $theadtr.eq(i).children("th").eq(j);
            //                 var $cloneth = $clonetr.eq(i).children("th").eq(j);
            //                 // thのCSSをコピーする
            //                 StyleCopy($cloneth, $theadth);
            //             }
            //         }
            //     }
 
            //     // コピーしたtheadの表示形式をtableに変更
            //     $clone.css("display", "table");         
            //     // positionをブラウザに対し絶対値とする
            //     $clone.css("position", "fixed");        
            //     $clone.css("border-collapse", "collapse");
            //     // positionの位置を設定(left = 元のテーブルのleftとする)
            //     $clone.css("left", toffset.left - $(window).scrollLeft());
            //     // positionの位置を設定(topをブラウザの一番上とする)
            //     $clone.css("top", "0px");
            //     // 表示順番を一番優先させる
            //     $clone.css("z-index", 99);
            // }
        });
 
        // CSSのコピー
        function StyleCopy($copyTo, $copyFrom){
            $copyTo.css("width", 
                        $copyFrom.css("width"));
            $copyTo.css("height", 
                        $copyFrom.css("height"));
 
            $copyTo.css("padding-top", 
                        $copyFrom.css("padding-top"));
            $copyTo.css("padding-left", 
                        $copyFrom.css("padding-left"));
            $copyTo.css("padding-bottom", 
                        $copyFrom.css("padding-bottom"));
            $copyTo.css("padding-right", 
                        $copyFrom.css("padding-right"));
 
            $copyTo.css("background", 
                        $copyFrom.css("background"));
            $copyTo.css("background-color", 
                        $copyFrom.css("background-color"));
            $copyTo.css("vertical-align", 
                        $copyFrom.css("vertical-align"));
 
            $copyTo.css("border-top-width", 
                        $copyFrom.css("border-top-width"));
            $copyTo.css("border-top-color", 
                        $copyFrom.css("border-top-color"));
            $copyTo.css("border-top-style", 
                        $copyFrom.css("border-top-style"));
 
            $copyTo.css("border-left-width", 
                        $copyFrom.css("border-left-width"));
            $copyTo.css("border-left-color", 
                        $copyFrom.css("border-left-color"));
            $copyTo.css("border-left-style", 
                        $copyFrom.css("border-left-style"));
 
            $copyTo.css("border-right-width", 
                        $copyFrom.css("border-right-width"));
            $copyTo.css("border-right-color", 
                        $copyFrom.css("border-right-color"));
            $copyTo.css("border-right-style", 
                        $copyFrom.css("border-right-style"));
 
            $copyTo.css("border-bottom-width", 
                        $copyFrom.css("border-bottom-width"));
            $copyTo.css("border-bottom-color", 
                        $copyFrom.css("border-bottom-color"));
            $copyTo.css("border-bottom-style", 
                        $copyFrom.css("border-bottom-style"));
        }
    });
})(jQuery);

