///
/// 長いから
///
function $( id ) { return document.getElementById(id); }
function $F( e )  {
  if( e.tagName.match( /SELECT/i ) ) return  e.value = e.options[e.selectedIndex].value;
  if( e.tagName.match( /input/i ) && e.type.match(/(radio|checkbox)/i) ){
    if( e.checked )  return e.value;
    else             return '';
  }
  if( !e.name || !e.value) return '';
  return e.value;
}

///
/// 長いから
///
function $C( tag ) { return document.createElement( tag );  }

///
/// 長いから
///
function $T( txt ) { return document.createTextNode( txt ); }

///
/// 長いから
///
function $ST( elm ){ return elm.options[elm.selectedIndex].text; }


///
/// getElemenetsByClassName
///
function $$( nm, elm ){
  if( !elm ) elm = document.body;
  var ret =  [];
  if( elm.className && elm.className.match( nm ) ) ret.push( elm );
  if( elm.childNodes ) {
    for( var i = 0, l = elm.childNodes.length; i < l; i++ )
      ret = ret.concat( $$( nm, elm.childNodes[i] ) );
  }
  ret.each = function( f ){ for( var i = 0, l = this.length; i < l; i++ ) f( this[i] ); }
  return ret;
}

///
/// getElemenetsByName
///
function $$$( nm, elm ){
  if( !elm ) elm = document.body;
  var ret =  [];
  if( elm.name == nm ) ret.push( elm );
  if( elm.childNodes ) {
    for( var i = 0, l = elm.childNodes.length; i < l; i++ )
      ret = ret.concat( $$$( nm, elm.childNodes[i] ) );
  }
  ret.each = function( f ){ for( var i = 0, l = this.length; i < l; i++ ) f( this[i] ); }
  return ret;
}


///
/// 対象テーブルに行を追加する
///
function addRow( tbl ){
  var tbody = tbl.getElementsByTagName('tbody')[0];
  var obj = tbl.rows[ tbl.rows.length -1 ].cloneNode( true )
  tbody.appendChild(  obj );
}

///
/// 対象テーブルから行を削除
///
function removeRow( tbl, row ){
  var tbody = tbl.getElementsByTagName('tbody')[0];
  tbody.removeChild( row );
}

///
/// イベント登録
///
var addListener = (function() {
  if ( window.addEventListener ) {
    return function(el, type, fn) {
      el.addEventListener(type, fn, false);
    };
  } else if ( window.attachEvent ) {
    return function(el, type, fn) {
      var f = function() {
        window.event.target = window.event.srcElement;
        fn.call(el, window.event);
      };
      el.attachEvent('on'+type, f);
    };
  } else {
    return function(el, type, fn) {
      el['on'+type] = fn;
    }
  }
})();

///
/// Ajax
///
var $Ajax = {
  doAhah   : function ( url, id ){
    this.Request(
      url,
      function( res ) { $( id ).innerHTML = res.responseText; }
      );
  } ,
  withJSON : function ( url, fnc  ) {
    this.Request( url , function( res ){
      var data;
      eval( 'data = ' + res.responseText );
      fnc( data );
    });
  } ,
  withXML : function( url, fnc ){
    this.Request( url ,function( res ){ fnc( res.responseXML ); } );
  } ,
  Request  : function ( url, fnc, param, method  ){
    if( !method ) method = 'GET';
    var x = null;
    try{ x = new XMLHttpRequest(); }
    catch(e) {
      try      { x = new ActiveXObject( "Msxml2.XMLHTTP" );    }
      catch(e) { x = new ActiveXObject( "Microsoft.XMLHTTP" ); }
    }
    
    x.onreadystatechange = function(){
      if( x.readyState != 4 ) return;
      fnc( x );
    }
    x.open( method, url, true );
    if( param ){
      x.setRequestHeader("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
      x.send( param );
    } else {
      x.send("");
    }
  }
};

/***********************************
 * FormをQueryString化する
 ***********************************/
function serializeForm( f , json ){
  var inputs    = f.getElementsByTagName( 'input' );
  var selects   = f.getElementsByTagName( 'select' );
  var textareas = f.getElementsByTagName( 'textarea' );
  var targets = [];
  for( var i = 0, l = inputs.length;    i < l; i++ ) targets.push( inputs[i]    );
  for( var i = 0, l = selects.length;   i < l; i++ ) targets.push( selects[i]   );
  for( var i = 0, l = textareas.length; i < l; i++ ) targets.push( textareas[i] );

  var params     = [];
  var params_obj = {};
  for( var i = 0, l = targets.length; i < l; i++ )  {
    if( !targets[i].name ) continue;
    var val =  $F( targets[i] );
    //if( !val )  continue;
    params.push( targets[i].name + '=' + encodeURIComponent( val ) );
    if( params_obj[targets[i].name] != undefined ){
      if( params_obj[targets[i].name].push ){
        params_obj[targets[i].name].push(val);
      } else {
        var buf = params_obj[targets[i].name]
        params_obj[targets[i].name] = [ ];
        params_obj[targets[i].name].push( buf );
        params_obj[targets[i].name].push( val );
      }
    }else {
      params_obj[targets[i].name] = val;
    }
  }
  if( !json )
    return params.join('&');
  else 
    return JSON.Encode( params_obj );
  
}

/***********************************
 * HTMLをエスケープする
 ***********************************/
function escapeHTML( str ){
  var obj = $C( 'div' );
  //return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  obj.appendChild( $T( str ) );
  return obj.innerHTML;
}

//
// OKな場合がfalse
//
function checkALL( objs ){
  var checker = {
    'char' : { fnc : isChar, msg : '%nm%が文字数が多すぎます(%len%文字数以内)'  } ,
    'date' : { fnc : isDate, msg : '%nm%はYYYY/MM/DDの形式で入力して下さい。'   } ,
    'int'  : { fnc : isInt , msg : '%nm%は数値を入力して下さい。'               }
  };
  for( var i = 0; i < objs.length; i++ ){
    var obj = objs[i];
    var chk = checker[obj.data_type];
    try{
      if( obj.not_null && isNull( obj ) ){
        $(obj.name).focus();
        return obj.jp + 'は、必須です。';
      }
      if( !chk.fnc( obj ) ){
        $(obj.name).focus();
        return chk.msg.replace( '%nm%', obj.jp ).replace('%len%', obj.max_length );
      }
      if( obj['reg'] && !isNull( obj ) && !$( obj.name ).value.match( obj['reg'] ) ){
        $(obj.name).focus();
        return obj.jp + 'を正しく入力して下さい。';
      }

      if( obj['ext'] && !isNull( obj ) && obj.ext( $('obj').value ) ){
        $(obj.name).focus();
        return obj.jp + 'を正しく入力して下さい。';
      }
    } catch( e ){
      console.log( obj );
      return 'そもそも' + obj.name + 'エラーっす。';
    }
  }
  return false;

  function isNull( obj ){
    var str = $(obj.name).value;
    return !str;
  }
  function isChar( obj ){
    var str = $(obj.name).value;
    var len = obj.max_length;
    if( !str ) return true;
    return (str.length <= len);
  }
  function isDate( obj ){
    var str = $(obj.name).value;
    if( !str ) return true;
    if( !str.match( /^(\d{4})[\/-]?(0?[0-9]|1[0-2])[\/-]?([0-2]\d|3[01])$/ ) ) return false;
    var d =  new Date(  RegExp.$1, RegExp.$2 - 1 , RegExp.$3 );
    if( !d ) return false;
    if( d.getFullYear() == RegExp.$1     &&
        d.getMonth()    == RegExp.$2 - 1 &&
        d.getDate()     == RegExp.$3 ) return true;
    return false;
  }
  function isInt( obj ){
    var str = $(obj.name).value;
    if( !str ) return true;
    return str.match( /^\d+$/ );
  }
}

/***********************************
 * MessageBoxを作成する
 ************************************/
function createMessageBox( props ){
  var msg_box = $C('div');
  msg_box.id                    = 'msg_box';
  msg_box.style.position        = 'absolute';
  msg_box.style.display         = 'none';

  msg_box.style.backgroundColor = props.backgroundColor;
  msg_box.style.color           = props.color;
  msg_box.style.width           = props.width + 'px';
  msg_box.style.height          = props.height + 'px';
  if( props['position'] ) msg_box.style.position = props.position;
  msg_box.show = function( msg, disable_auto_hide ){
    this.style.display = '';
    this.style.left    = props.fromLeft + 'px';
    if( props['position'] ){
      this.style.top     = props.fromTop  + 'px';
    } else {
      this.style.top   = ( ( document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop ) + props.fromTop ) + 'px';
    }
    this.innerHTML     = msg;
    if( !disable_auto_hide ){
      setTimeout(
        function(){
          $('msg_box').style.display = 'none';
        } , 3000 );
    }
  }
  
  msg_box.hide = function(){
    $('msg_box').style.display = 'none';
  }
  
  return msg_box;
}

/***********************************
 * Disablerを表示する
 ************************************/
function showDisabler(){
  var disabler;
  if( !$('disabler') ){
    disabler       = $C('div');
    disabler.id    = 'disabler';
    if (window.innerWidth == undefined) {
      var setInnerWidth  = function () {
        window.innerWidth  = ( document.body ? document.body : document.Element).clientWidth  || 0;
      }
      var setInnerHeight = function () {
        window.innerHeight = ( document.body ? document.body : document.Element).clientHeight || 0;
      }
      addListener(window, 'resize',  function(){
        setInnerWidth();
        setInnerHeight();
      });
      setInnerWidth();
      setInnerHeight();
    }
    addListener( window, 'resize',  function(){
      disabler.style.width  = window.innerWidth  + 'px';
      disabler.style.height = window.innerHeight + 'px';
    });
    
    disabler.style.position                 = 'absolute';
    disabler.style.display                  = 'none';
    disabler.style.backgroundColor          = 'black';
    disabler.style.width                    = window.innerWidth  + 'px';
    disabler.style.height                   = window.innerHeight + 'px';
    disabler.style.filter                   = 'alpha(opacity=50)';
    disabler.style.MozOpacity               = 0.5;
    disabler.style.opacity                  = 0.5;
    disabler.style.top                      = 0;
    disabler.style.left                     = 0;
    disabler.style.zIndex                   = 500;
    if( document.all ){
      document.body.appendChild( disabler );
    }    else {
      document.documentElement.appendChild( disabler );
    }
    
  } else {
    disabler = $('disabler');
  }
  disabler.style.display = '';
}

/***********************************
 * Disablerを隠す
 ************************************/
function hideDisabler(){
  if( !$('disabler') ) return ;
  $('disabler').style.display = 'none';
}

/*
================================================================================
    Name        :   JSON
    In          :   [none]      
    Out         :   [none]      
    Note        :   JSONユーティリティ群
--------------------------------------------------------------------------------
    Version     :   Ver1.0.0    |   2006/12/04  |   新規作成
                :   Ver1.1.0    |   2007/02/17  |   [JSON.EncodeComplete]を追加
--------------------------------------------------------------------------------
    License     :   MIT license
    URL         :   www.kanasansoft.com
================================================================================
*/

/*--------------------------------------------------------------------------------
    コンストラクタ
--------------------------------------------------------------------------------*/
function JSON(){
}

/*--------------------------------------------------------------------------------
    JSONエンコードを行なう
--------------------------------------------------------------------------------*/
JSON.Encode
=   function(obj){

    var rtn;

    if(obj==null){

        rtn = "null";

    }else{

        switch(obj.constructor){

            case Boolean:
                rtn = obj?"true":"false";
                break;

            case Number:
                rtn = isNaN(obj)||!isFinite(obj)?"null":obj.toString(10);
                break;

            case String:
                rtn = "\""+StringUtility.Encode.JavaScript(obj)+"\"";
                break;

            case Array:
                var buf = [];
                for(var i=0;i<obj.length;i++){
                    //再帰呼出
                    buf.push(arguments.callee(obj[i]));
                }
                rtn = "["+buf.join(",")+"]";
                break;

            case Object:
                var buf = [];
                for(var key in obj){
                    //Object汚染回避判定有
                    if(obj.hasOwnProperty(key)){
                        //再帰呼出
                        buf[buf.length] = arguments.callee(key)+":"+arguments.callee(obj[key]);
                    }
                }
                rtn = "{"+buf.join(",")+"}";
                break;

            default:
                rtn = "null";
                break;

        }

    }

    return rtn;
}

/*--------------------------------------------------------------------------------
    JSONエンコードを行なう
--------------------------------------------------------------------------------*/
JSON.EncodeComplete
=   function(obj){

    var rtn;

    if(obj==null){

        rtn = "null";

    }else{

        switch(obj.constructor){

            case Boolean:
                rtn = obj?"true":"false";
                break;

            case Number:
                rtn = isNaN(obj)||!isFinite(obj)?"null":obj.toString(10);
                break;

            case String:
                rtn = "\""+StringUtility.Encode.JavaScriptComplete(obj)+"\"";
                break;

            case Array:
                var buf = [];
                for(var i=0;i<obj.length;i++){
                    //再帰呼出
                    buf.push(arguments.callee(obj[i]));
                }
                rtn = "["+buf.join(",")+"]";
                break;

            case Object:
                var buf = [];
                for(var key in obj){
                    //Object汚染回避判定有
                    if(obj.hasOwnProperty(key)){
                        //再帰呼出
                        buf[buf.length] = arguments.callee(key)+":"+arguments.callee(obj[key]);
                    }
                }
                rtn = "{"+buf.join(",")+"}";
                break;

            default:
                rtn = "null";
                break;

        }

    }

    return rtn;
}

/*--------------------------------------------------------------------------------
    JSONデコードを行なう
--------------------------------------------------------------------------------*/
JSON.Decode
=   function(str){

    var rtn;

    eval("rtn="+str);

    return rtn;
}


/*
================================================================================
    Name        :   StringUtility
    In          :   [none]      
    Out         :   [none]      
    Note        :   文字列用ユーティリティ群
--------------------------------------------------------------------------------
    Version     :   Ver1.0.0    |   2006/01/16  |   新規作成
--------------------------------------------------------------------------------
    License     :   New BSD license
    URL         :   www.kanasansoft.com
================================================================================
*/

/*--------------------------------------------------------------------------------
    コンストラクタ
--------------------------------------------------------------------------------*/
function StringUtility(){
}

StringUtility.Encode
=   function(){
}

StringUtility.Decode
=   function(){
}

StringUtility.Convert
=   function(){
}

/*--------------------------------------------------------------------------------
    HTMLエンコードを行なう
--------------------------------------------------------------------------------*/
StringUtility.Encode.HTML
=   function(str){
    return          str                                         .
                    replace(    /&/ig   ,   "&amp;"     )       .
                    replace(    /</ig   ,   "&lt;"      )       .
                    replace(    />/ig   ,   "&gt;"      )       .
                    replace(    /"/ig   ,   "&quot;"    )       .
                    replace(    / /ig   ,   "&nbsp;"    )       ;
}

/*--------------------------------------------------------------------------------
    HTMLデコードを行なう
--------------------------------------------------------------------------------*/
StringUtility.Decode.HTML
=   function(str){
    return          str                                         .
                    replace(    /&nbsp;/ig  ,   " "     )       .
                    replace(    /&quot;/ig  ,   "\""    )       .
                    replace(    /&gt;/ig    ,   ">"     )       .
                    replace(    /&lt;/ig    ,   "<"     )       .
                    replace(    /&amp;/ig   ,   "&"     )       ;
}

/*--------------------------------------------------------------------------------
    HTMLエンコードを行なう(Bookmarklet用)
--------------------------------------------------------------------------------*/
StringUtility.Encode.HTMLforBookmarklet
=   function(str){
    return          str                                         .
                    replace(    /&/ig   ,   "&amp;"     )       .
                    replace(    /</ig   ,   "&lt;"      )       .
                    replace(    />/ig   ,   "&gt;"      )       .
                    replace(    /"/ig   ,   "&quot;"    )       ;
}

/*--------------------------------------------------------------------------------
    JavaScriptエンコードを行なう
--------------------------------------------------------------------------------*/
StringUtility.Encode.JavaScript
=   function(str){
    return          str                                         .
                    replace(    /\\/ig  ,   "\\\\"      )       .
/*                  replace(    /\b/ig  ,   "\\b"       )       .*/
                    replace(    /\f/ig  ,   "\\f"       )       .
                    replace(    /\n/ig  ,   "\\n"       )       .
                    replace(    /\r/ig  ,   "\\r"       )       .
                    replace(    /\t/ig  ,   "\\t"       )       .
                    replace(    /'/ig   ,   "\\'"       )       .
                    replace(    /"/ig   ,   "\\\""      )       ;
}

/*--------------------------------------------------------------------------------
    tabをspaceに変換する
--------------------------------------------------------------------------------*/
StringUtility.Convert.TabToSpace
=   function(str,tabNumber){

    var linesRN                         =   str.split("\r\n");
    for(var lineCntRN=0;lineCntRN<linesRN.length;lineCntRN++){
        var linesN                      =   linesRN[lineCntRN].split("\n");
        for(var lineCntN=0;lineCntN<linesN.length;lineCntN++){
            var linesR                  =   linesN[lineCntN].split("\r");
            for(var lineCntR=0;lineCntR<linesR.length;lineCntR++){
                var wordsT              =   linesR[lineCntR].split("\t");
                for(var wordsCntT=0;wordsCntT<wordsT.length-1;wordsCntT++){
                    wordsT[wordsCntT]   +=  StringUtility.getRepeatString(
                                                " "                                                                     ,
                                                tabNumber-(StringUtility.getLengthByBite(wordsT[wordsCntT])%tabNumber)  )
                }
                linesR[lineCntR]        =   wordsT.join("");
            }
            linesN[lineCntN]            =   linesR.join("\r");
        }
        linesRN[lineCntRN]              =   linesN.join("\n");
    }
    var rtn                             =   linesRN.join("\r\n");

    return rtn;

}

/*--------------------------------------------------------------------------------
    改行コードを"<br />"に変換する
--------------------------------------------------------------------------------*/
StringUtility.Convert.NewLineCodeToTag
=   function(str){
    return          str                                             .
                    replace(    /\r\n/ig    ,   "<br />"    )       .
                    replace(    /\r/ig      ,   "<br />"    )       .
                    replace(    /\n/ig      ,   "<br />"    )       ;
}

/*--------------------------------------------------------------------------------
    文字バイト長取得
--------------------------------------------------------------------------------*/
StringUtility.getLengthByBite
=   function(str){
    var count   =   0;
    for(var i=0;i<str.length;i++){
        var code    =   str.charCodeAt(i);
        while(code!=0){
            count++;
            code>>>=8;
        }
    }
    return count;
}

/*--------------------------------------------------------------------------------
    繰り返し文字取得
--------------------------------------------------------------------------------*/
StringUtility.getRepeatString
=   function(str,num){
    var rtn =   "";
    for(var i=0;i<num;i++){
        rtn +=  str;
    }
    return rtn;
}

