/* VoteCheckForm Class
*
*  バリデーションアクション一覧
*      isNotEmpty
*          空の判定
*
*      isNum
*          数字文字列の判定
*
*      isAlphaLatin
*          半角英数の判定
*
*      isDate
*          日付文字列の判定
*          デフォルトでは「yyyy/mm/dd」形式にて判定
*
*      isURLbyCocolog
*          ココログ投票用URLの判定
*          カンマ区切りのURLリストを判定
*
*      isIntegerInRange
*          数値範囲の判定
*          必須パラム：Nmax,Nmin
*
*      isStringInRange
*          文字数範囲の判定
*          必須パラム: Smax
*
*      isChecked
*          ラジオボタンの選択判定
*
*      isFutureDate
*          日付の未来判定
*/


// コンストラクタ
var VoteCheckForm = function() {
    this.initialize();
    this.actionSetup();
};

// 初期設定 //
VoteCheckForm.prototype.initialize = function (){
    this.error_array = [];
    this.rules_array = [];
    this.eString_prefix = "";
    this.eString_suffix = "";
    this.eRecord_prefix = "";
    this.eRecord_suffix = "\n";
    this.e = true;
}
VoteCheckForm.prototype.actionSetup = function (){
    // アクションの定義、アクションコードとのマッピング
    this.action_code_list = {"isNotEmpty":1, 
                             "isAlphaLatin":2, 
                             "isNum":3, 
                             "isDate":4, 
                             "isURLbyCocolog":5, 
                             "isIntegerInRange":6, 
                             "isStringInRange":7, 
                             "isChecked":8, 
                             "isFutureDate":9, 
                             "isURL":10};

    // エラーメッセージ定義、actioｎ名とのマッピング
    this.message_list = { 1:"%key%は必須入力です。", 
                          2:"%key%は半角英数のみです。", 
                          3:"%key%は数字を入力してください。", 
                          4:"%key%は日付書式不正です。", 
                          5:"%key%はURL書式不正です。", 
                          6:"%key%は入力範囲不正です。", 
                          7:"%key%は入力範囲不正です。", 
                          8:"%key%が選択されていません。", 
                          9:"%key%が過去に設定されています。", 
                         10:"%key%はURL書式不正です。"};
}

/*--------------------------------------------------------------------------
*  入力値チェックメソッド
*
*  戻り値：
*    Successフラグ、ステータスを下記ハッシュ形式で返す
*    {isSuccess:[true or false], action_code:[数値]}
*/

// nullチェック
VoteCheckForm.prototype.isNotEmpty = function (str){
    var flg = !/^[\s|　]*$/.test(str);
    return {isSuccess:flg, action_code:this.action_code_list.isNotEmpty};
}

// 半角英数チェック
VoteCheckForm.prototype.isAlphaLatin = function(str, param){
    var notNull = this.paramNotNullCheck(param);

    var ret = this.isNotEmpty(str);
    if (! ret.isSuccess){
        return this.notNullChange(ret, notNull)
    }

    alphaRegExp = /^[0-9a-z]+$/i
    var flg = alphaRegExp.test(str);
    return {isSuccess:flg, action_code:this.action_code_list.isAlphaLatin};

}

// 数字チェック
VoteCheckForm.prototype.isNum = function (str, param){
    var notNull = this.paramNotNullCheck(param);

    var ret = this.isNotEmpty(str);
    if (! ret.isSuccess){
        return this.notNullChange(ret, notNull)
    }

    var flg = /^[0-9]+$/.test(str);
    return {isSuccess:flg, action_code:this.action_code_list.isNum};
}

// 日付書式チェック
VoteCheckForm.prototype.isDate = function(date, param){
    var notNull = this.paramNotNullCheck(param);

    var ret = this.isNotEmpty(date);
    if (! ret.isSuccess){
        return this.notNullChange(ret, notNull)
    }

    // RegExpformat = /^\d{4}\/(0\d|[1][0-2])\/([0-2]\d|[3][0-1])$/;
    RegExpformat = /^\d{4}\/(0[1-9]|1[0-2]|[1-9])\/([1-9]|[1-2][0-9]|3[0-1]|0[1-9])$/;

    var flg = RegExpformat.test(date);
    if(this.splitDate(date) == undefined){
        flg = false;
    }

    return {isSuccess:flg, action_code:this.action_code_list.isDate};
}

// 日付整合性チェック
VoteCheckForm.prototype.isFutureDate = function(date, param){
    var notNull = this.paramNotNullCheck(param);

    var ret = this.isNotEmpty(date);
    if (! ret.isSuccess){
        return this.notNullChange(ret, notNull)
    }

    var ret = this.isDate(date);
    if (! ret.isSuccess){
        return ret;
    }

    var nowDate = new Date();
    var n_year = nowDate.getFullYear();
    var n_month = nowDate.getMonth();
    var n_date = nowDate.getDate();

    var getDate = this.splitDate(date)
    var g_year = getDate.getFullYear();
    var g_month = getDate.getMonth();
    var g_date = getDate.getDate();

    var flg = false;
    if (n_year < g_year ||
        n_year == g_year && n_month < g_month ||
        n_year == g_year && n_month == g_month && n_date <= g_date){
        flg = true;
    }

    return {isSuccess:flg, action_code:this.action_code_list.isFutureDate};
}

// URLチェック（ココログ投票）
VoteCheckForm.prototype.isURLbyCocolog = function(str, param){
    var notNull = this.paramNotNullCheck(param);

    var ret = this.isNotEmpty(str);
    if (! ret.isSuccess){
        return this.notNullChange(ret, notNull)
    }

    var flg = true;
    str = str.toLowerCase();
    var url_array = str.split(",");
    urlRegExp = /^((http(s?))\:\/\/)\S+$/
    for(var i=0;i<url_array.length && flg;i++){
        flg = urlRegExp.test(url_array[i]);
    }

    return {isSuccess:flg, action_code:this.action_code_list.isURLbyCocolog};
}

// 数値レンジチェック
VoteCheckForm.prototype.isIntegerInRange = function (str, param){
    var notNull = this.paramNotNullCheck(param);

    if (param == undefined || param.Nmin == undefined || param.Nmax == undefined){
        return undefined;
    }
    var Nmin = param.Nmin;
    var Nmax = param.Nmax;

    var ret = this.isNotEmpty(str);
    if (! ret.isSuccess){
        return this.notNullChange(ret, notNull)
    }

    ret = this.isNum(str);
    if (! ret.isSuccess){
        return ret;
    }

    var num = Number(str)
    var flg = true;
    if(num != Math.round(num)){
        flg = false;
    }
    flg = (num >= Nmin && num <= Nmax);

    return {isSuccess:flg, action_code:this.action_code_list.isIntegerInRange};
}

// 文字数レンジチェック
VoteCheckForm.prototype.isStringInRange = function (str, param){
    var notNull = this.paramNotNullCheck(param);

    if (param == undefined || param.Smax == undefined){
        return undefined;
    }

    if (param.Smin == undefined){
        var Smin = 1;
    }else{
        var Smin = param.Smin;
    }
    var Smax = param.Smax;

    var ret = this.isNotEmpty(str);
    if (! ret.isSuccess){
        return this.notNullChange(ret, notNull)
    }

    var strNum = str.length
    flg = (strNum >= Smin && strNum <= Smax);

    return {isSuccess:flg, action_code:this.action_code_list.isIntegerInRange};
}

// ラジオボタン選択確認
// 引数はID名文字列
VoteCheckForm.prototype.isChecked = function(name){
    var redio_array = document.getElementsByName(document.getElementById(name).name);
    var flg = false;
    for (var i=0;i<redio_array.length;i++){
        if (redio_array[i].checked){
            flg = true;
        }
    }
    return {isSuccess:flg, action_code:this.action_code_list.isChecked}
}

// URLチェック（一般）
VoteCheckForm.prototype.isURL = function(str, param){
    var notNull = this.paramNotNullCheck(param);

    var ret = this.isNotEmpty(str);
    if (! ret.isSuccess){
        return this.notNullChange(ret, notNull)
    }

    str = str.toLowerCase();
    urlRegExp = /^((http(s?))\:\/\/)\S+$/
    var flg = urlRegExp.test(str);

    return {isSuccess:flg, action_code:this.action_code_list.isURL};
}

/*--------------------------------------------------------------------------
*
*  操作メソッド
*
*/

// フォームエレメント値取得ファンクション
function getValue(s){
    if (document.getElementById(s) == undefined){
        return undefined;
    }else{
        if (document.getElementById(s).disabled){
            return undefined;
        }else{
            return document.getElementById(s).value;
        }
    }
}

// バリデートルールの設定
VoteCheckForm.prototype.setRules = function (rules){
    this.rules_array = rules;
}


// バリデーション実行結果の取得メソッド
VoteCheckForm.prototype.getErrorList = function (){
    return this.error_array;
}

// 個別エラーメッセージ取得メソッド
VoteCheckForm.prototype.getErrorMessage = function (action_code, key){
    var errorStr = this.message_list[action_code];
    return errorStr.replace("%key%", key);
}

// バリデーション実行結果文字列生成メソッド
VoteCheckForm.prototype.getErrorString = function (prefix, suffix, rPrefix, rSuffix){
    if(prefix  == undefined) {prefix  = this.eString_prefix;}
    if(suffix  == undefined) {suffix  = this.eString_suffix;}
    if(rPrefix == undefined) {rPrefix = this.eRecord_prefix;}
    if(rSuffix == undefined) {rSuffix = this.eRecord_suffix;}

    var eString = prefix;
    for (i in this.error_array){
        eString = eString + rPrefix + this.error_array[i].error_message + rSuffix; 
    }

    return eString + suffix;
}

// バリデートルール実行メソッド
VoteCheckForm.prototype.check = function (){
    this.error_array = [];
    this.e = true;

    for(var i=0;i<this.rules_array.length;i++){
        var rule        = this.rules_array[i];
        var valStr      = getValue(rule.id);
        if (valStr == undefined){ continue; }
        var action      = rule.action;
        var message_key = rule.message_key;
        var param       = rule.param;

        if (action == "isChecked"){
            valStr = rule.id;
        }

        valStr = valStr.replace("\"","\\\"");

        var com = "this." + action + "(\"" + valStr + "\", param);" ;

        if (this.action_check(action)){
            var ret = eval(com);
            if (ret == undefined){
                return undefined;
            }
        }else{
            return undefined;
        }

        if(!ret.isSuccess){
            var errorStr = this.message_list[ret.action_code];

            if (message_key){
                ret["error_message"] = errorStr.replace("%key%", message_key);
            }else{
                ret["error_message"] = errorStr.replace("%key%", rule.id);
            }

            this.error_array[rule.id] = ret;
            this.e = false;
        }
    }
    return this.e;
}

// check、エラー文言生成、htnl貼り付け複合処理
VoteCheckForm.prototype.setChecktoHTML = function (id, prefix, suffix, rPrefix, rSuffix){
    if(rSuffix  == undefined) {rSuffix  = "<br/>"}

    var success = this.check();
    if(!success){
        var eString = this.getErrorString(prefix, suffix, rPrefix, rSuffix);
        document.getElementById(id).innerHTML = eString;
    }

    return success;
}

/*--------------------------------------------------------------------------
*
*  内部メソッド
*
*/

// 日付文字列→Date変換メソッド
VoteCheckForm.prototype.splitDate = function (date){
    var dateArray  = date.split("/");
    var date = new Date(dateArray[0], dateArray[1] - 1, dateArray[2]);

    if (date.getDate() == dateArray[2] && date.getMonth() == dateArray[1] - 1 && date.getFullYear() == dateArray[0]){
        return date;
    }else{
        return undefined;
    }
}

// アクション存在確認メソッド
VoteCheckForm.prototype.action_check = function (action){
    if(this.action_code_list[action]){
        return true;
    }else{
        return false;
    }
}

// notNullパラム確認メソッド
VoteCheckForm.prototype.paramNotNullCheck = function (param){
    if (param == undefined || param.notNull == undefined){
        var notNull = true;
    }else{
        var notNull = param.notNull;
    }

    return notNull;
}

// notNull変換メソッド
VoteCheckForm.prototype.notNullChange = function (ret, notNull){
    if (notNull){
        return ret;
    }else{
        ret.isSuccess = true;
        return ret;
    }
}

/*--------------------------------------------------------------------------*/

