/*
 * Copyright 2006 Mask@ Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

function BackgroundLoad(){
}

/* 初期化関数。本ファイルの最後で呼び出している。 */
BackgroundLoad.init = function(){

  /* 内部変数の初期化 */
  BackgroundLoad.layoutHash = new Object();  // レイアウト名 => 親DIVDOM, 一時DIVDOM
  BackgroundLoad.containerHash = new Object();  // DIVDOMのID => 現在そのDIVDOMに表示されているレイアウト名
  BackgroundLoad.divUniqueID = 0;
  BackgroundLoad.HIDE_ZONE = {top:3000, left:3000};

  /* プログレスバーの作成 */
  BackgroundLoad.progressBarWindow = document.createElement("div");
  BackgroundLoad.progressBarWindow.style.position = "absolute";
  BackgroundLoad.progressBarWindow.style.zIndex = 32767;
  BackgroundLoad.progressBarWindow.style.top = "100px";
  BackgroundLoad.progressBarWindow.style.left = "100px";
  BackgroundLoad.progressBarWindow.style.border = "3px solid black";
  BackgroundLoad.progressBarWindow.style.width = "300px";
  BackgroundLoad.progressBarWindow.style.height = "50px";
  BackgroundLoad.progressBarWindow.style.padding = "1em";
  BackgroundLoad.progressBarWindow.style.backgroundColor = "pink";
}

/* プログレスバーを表示 */
BackgroundLoad.showProgressBar = function(){

  if(!BackgroundLoad.isProgressBarLoaded){
    document.body.appendChild(BackgroundLoad.progressBarWindow);
    BackgroundLoad.isProgressBarLoaded = true;
  }

  /* 画面中央に表示 */
  BackgroundLoad.progressBarWindow.style.top = 
    (document.body.clientHeight - BackgroundLoad.progressBarWindow.offsetHeight) / 2;
  BackgroundLoad.progressBarWindow.style.left =
    (document.body.clientWidth - BackgroundLoad.progressBarWindow.offsetWidth) / 2;

}

/* プログレスバーを非表示 */
BackgroundLoad.hideProgressBar = function(){

  BackgroundLoad.progressBarWindow.style.top = BackgroundLoad.HIDE_ZONE.top;
  BackgroundLoad.progressBarWindow.style.left = BackgroundLoad.HIDE_ZONE.left;

}

/* レイアウトをバックグラウンドでロード */
/* 引数: {'fileName':<レイアウトXMLファイル名>, 'refParentObjText':<親DIVタグのDOMのテキスト表現>} の配列 */
BackgroundLoad.loadLayout = function(args){

  BackgroundLoad.args = args;  // TODO: setTimeoutで引数に渡せなかった。後で直す
  BackgroundLoad.showProgressBar();
  
  BackgroundLoad.progressBarWindow.innerHTML = args.length + "つのファイルの取得・コンパイル中";

  setTimeout(BackgroundLoad.loadLayout2, 500);  // プログレスバーが表示されるよう、0.5秒待つ
}

BackgroundLoad.loadLayout2 = function(){
  var args = BackgroundLoad.args;  // TODO: setTimeoutで引数に渡せなかった。後で直す
  BackgroundLoad.args = null;  // TODO: setTimeoutで引数に渡せなかった。後で直す
  
  BackgroundLoad.layoutNameArray = new Array();
  
  for (var i = 0; i < args.length; i++){
    BackgroundLoad.loadLayout3(args[i]);
  }

  BackgroundLoad.progressBarWindow.innerHTML = "";
  for (var i = 0; i < args.length; i++){
    BackgroundLoad.progressBarWindow.innerHTML += "<div>[" + BackgroundLoad.layoutNameArray[i] + "] <span id='_maskat_layout_loadStatusMessage_" + BackgroundLoad.layoutNameArray[i] + "'>ロード待ち</span></div>";
  }
  
  BackgroundLoad.nextLayoutIndex = 0; 
  BackgroundLoad.loadLayout3_1();
}

BackgroundLoad.loadLayout3_1 = function(){

  if (BackgroundLoad.nextLayoutIndex > BackgroundLoad.layoutNameArray.length - 1){
    BackgroundLoad.hideProgressBar();
  }
  else{
    var statusMessageDOM = document.getElementById("_maskat_layout_loadStatusMessage_" + BackgroundLoad.layoutNameArray[BackgroundLoad.nextLayoutIndex]);
    statusMessageDOM.innerHTML = "ロード中";
    setTimeout(BackgroundLoad.loadLayout3_2, 500);  // 画面描画が反映されるように、0.5秒待つ
  }
}

BackgroundLoad.loadLayout3_2 = function(){
  loadLayout(BackgroundLoad.layoutNameArray[BackgroundLoad.nextLayoutIndex]);
  
  var statusMessageDOM = document.getElementById("_maskat_layout_loadStatusMessage_" + BackgroundLoad.layoutNameArray[BackgroundLoad.nextLayoutIndex]);
  statusMessageDOM.innerHTML = "ロード完了";


  BackgroundLoad.nextLayoutIndex++;
  setTimeout(BackgroundLoad.loadLayout3_1, 500);  // 画面描画が反映されるように、0.5秒待つ
}


/* BackgroundLoad.loadLayout関数の補助関数 */
BackgroundLoad.loadLayout3 = function(arg){
  var xmlhttp;
  try {
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {
      xmlhttp = false;
    }
  }
  if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
    xmlhttp = new XMLHttpRequest();
  }
  if (xmlhttp) {
    xmlhttp.open("GET", "http://localhost:8080/maskat/"+arg.fileName, false);
    xmlhttp.send(null);
    if (xmlhttp.status == 200) {
      BackgroundLoad.loadLayout4(xmlhttp.responseText, arg.refParentObjText);
    } else {
      alert("リソースの取得に失敗しました");
    }
  }
  else {
    alert('非同期通信モジュールの取得に失敗しました。\n処理を停止します。');
    return;
  }
}

/* BackgroundLoad.loadLayout関数の補助関数 */
BackgroundLoad.loadLayout4 = function(layoutXML, refParentObjText){
  // TODO: すでにそのレイアウトがロードされていた場合の処理

  var sourceDoc = CrossBrowser.XML2DOM(layoutXML);
//  var layoutName = CrossBrowser.getElementsByTagName(sourceDoc, "layout")[0].getAttribute("name");
  var layoutName = sourceDoc.getElementsByTagName("layout").item(0).getAttribute("name");
  var refParentObj = eval(refParentObjText);

  // refParentObjがDIVタグのDOMの場合
  if (refParentObj.tagName != null && refParentObj.tagName.toUpperCase() == "DIV"){

    /* 画面外にDIVのDOMを作成し、そのDOMに対して表示処理を行う(実際は画面外のため表示されない) */

    var layoutDIV = document.createElement("div");
    layoutDIV.id = "_maskat_" + refParentObj.id + "_" + BackgroundLoad.divUniqueID++;
    layoutDIV.style.position = "absolute";
    layoutDIV.style.top = BackgroundLoad.HIDE_ZONE.top;
    layoutDIV.style.left = BackgroundLoad.HIDE_ZONE.left;
    layoutDIV.style.width = refParentObj.style.width;
    layoutDIV.style.height = refParentObj.style.height;
    document.body.appendChild(layoutDIV);

    var rialtoJSSrc;
    try{
      rialtoJSSrc = maskat.interpretLayoutXML(sourceDoc, 'document.getElementById("' + layoutDIV.id + '")');
    } catch(e){
      alert("name: " + e.name + "\nmessage: " + e.message + "\nfileName: " + e.fileName);
    }
    maskat.loadJSSrc(rialtoJSSrc);
    
    BackgroundLoad.layoutNameArray.push(layoutName);

    BackgroundLoad.layoutHash[layoutName] = {"refParentObj":refParentObj, "layoutDIV":layoutDIV};
    BackgroundLoad.containerHash[refParentObj.id] = null;

  }
  // TODO: refParentObjがRialtoコンテナオブジェクトの場合
  

}

BackgroundLoad.unloadLayout = function(layoutName){
  if (BackgroundLoad.layoutHash[layoutName] != undefined){
    // TODO: layout配下の全コンポーネントをremove

    BackgroundLoad.hideLayout(layoutName);

    var layoutDIV = BackgroundLoad.layoutHash[layoutName].layoutDIV;
    layoutDIV.parentNode.removeChild(layoutDIV);

    delete BackgroundLoad.layoutHash[layoutName];
  }
  else {
    alert(layoutName + "レイアウトはロードされていないので、アンロードできません。");
  }
}

BackgroundLoad.showLayout = function(layoutName){
  if (BackgroundLoad.layoutHash[layoutName] != undefined){
    var currentLayoutName = BackgroundLoad.containerHash[BackgroundLoad.layoutHash[layoutName].refParentObj.id];
    if (currentLayoutName != null){
      // 既存のレイアウトをhideする
      BackgroundLoad.hideLayout(currentLayoutName);
    }
    
    var layoutDIV = BackgroundLoad.layoutHash[layoutName].layoutDIV;
    var refParentObj = BackgroundLoad.layoutHash[layoutName].refParentObj;
    layoutDIV.style.top = refParentObj.style.top;
    layoutDIV.style.left = refParentObj.style.left;
    
    BackgroundLoad.containerHash[BackgroundLoad.layoutHash[layoutName].refParentObj.id] = layoutName;
  }
  else {
    alert(layoutName + "レイアウトはロードされていないので、表示できません。");
  }
}

BackgroundLoad.hideLayout = function(layoutName){
  if (BackgroundLoad.layoutHash[layoutName] != undefined){
    var currentLayoutName = BackgroundLoad.containerHash[BackgroundLoad.layoutHash[layoutName].refParentObj.id];
    /* hide指定されたレイアウト名と、現在表示されているレイアウト名が等しい場合のみ処理を行う */
    if (currentLayoutName == layoutName){
      var layoutDIV = BackgroundLoad.layoutHash[layoutName].layoutDIV;
      layoutDIV.style.top = BackgroundLoad.HIDE_ZONE.top;
      layoutDIV.style.left = BackgroundLoad.HIDE_ZONE.left;
    
      BackgroundLoad.containerHash[BackgroundLoad.layoutHash[layoutName].refParentObj.id] = null;
    }
  }
  else {
    alert(layoutName + "レイアウトはロードされていないので、非表示にできません。");
  }
}

BackgroundLoad.init();

/*
  ・クロスブラウザ化を実現する機能を集めたオブジェクト
  ・静的クラス
*/

function CrossBrowser(){
}

// ブラウザを判定し、その結果を内部変数に保存する。
CrossBrowser.init = function(){
  CrossBrowser.isIE = false;
  CrossBrowser.isFF = false;

  if (navigator.appName == "Microsoft Internet Explorer"){
    CrossBrowser.isIE = true;
  }
  else if (navigator.appName == "Netscape"){
    CrossBrowser.isFF = true;
  }
  else {
    alert("お使いのブラウザは動作保障対象外です。本システムは正しく機能しません。");
  }
}

// 入力であるXMLの文字列(srcXML)をDOM化したものを返す
CrossBrowser.XML2DOM = function(srcXML){
  var desDOM;

  if (CrossBrowser.isIE){
    desDOM = new ActiveXObject("MSXML2.DOMDocument");
    desDOM.async = false;
    desDOM.loadXML(srcXML);
  }
  else if (CrossBrowser.isFF){
    desDOM = (new DOMParser()).parseFromString(srcXML, "text/xml");
  }

  return desDOM;
}

// getElementsByTagNameのクロスブラウザ化(IE: 名前空間必要、Firefox: 名前空間不必要)
CrossBrowser.getElementsByTagName = function(srcDOM, tagName){
  if (CrossBrowser.isIE){
    return(srcDOM.getElementsByTagName(srcDOM.documentElement.prefix + ":" + tagName));
  }
  else if (CrossBrowser.isFF){
    return(srcDOM.getElementsByTagName(tagName));
  }
}

// ノード内のコンテンツ文字列を取得
CrossBrowser.getInnerContents = function(srcElm){
  if (CrossBrowser.isIE){
    return(srcElm.xml);
  }
  else if (CrossBrowser.isFF){
    return((new XMLSerializer).serializeToString(srcElm));
  }
}

// このライブラリのロード時にブラウザ判定を行う。
// 下記関数呼び出しは対象とする関数定義よりも後に記述する必要がある。
CrossBrowser.init();

 
//// JavaScriptファイルを動的にロードする。 ////

maskat.loadJSFile_i = 0;  // scriptタグのユニークなIDを生成するのに利用する

maskat.loadJSFile = function(fileName){
  var elementScript = document.createElement("script");
  document.acsync = false;
  elementScript.id = "forDynamicJSFileLoad" + maskat.loadJSFile_i++;  // ID名は一意であれば何でもよい
  elementScript.src = fileName;
  document.getElementsByTagName("head").item(0).appendChild(elementScript);
//  elementScript.parentNode.replaceChild(elementScript, elementScript);
}

//// CSSファイルを動的にロードする。 ////

maskat.loadCSSFile_i = 0;  // linkタグのユニークなIDを生成するのに利用する

maskat.loadCSSFile = function(fileName){
  var elementLink = document.createElement("link");
  elementLink.id = "forDynamicCSSFileLoad" + maskat.loadCSSFile_i++;  // ID名は一意であれば何でもよい
  elementLink.href = fileName;
  document.getElementsByTagName("head").item(0).appendChild(elementLink);
//  elementLink.parentNode.replaceChild(elementLink, elementLink);
}

//// JavaScriptソースを動的にロードする。 ////

maskat.loadJSSrc_i = 0; // scriptタグのユニークなIDを生成するのに利用する

maskat.loadJSSrc = function(jsSrc){
  var elementScript = document.createElement("script");
  document.async = false;
  elementScript.id = "forDynamicJSSrcLoad" + maskat.loadJSSrc_i++;  // ID名は一意であれば何でもよい
  elementScript.text = jsSrc;
  document.getElementsByTagName("head").item(0).appendChild(elementScript);
  document.getElementsByTagName("head").item(0).removeChild(elementScript);
//  elementScript.parentNode.replaceChild(elementScript, elementScript);
}

maskat.layouts = new Object;

/**
 * layout単位画面制御
 */
maskat.Layout = function(name){
    this.name = name;
    this.components=new Object;
    this.componentsLevel1=new Object;
    this.isLoaded = false;
    maskat.layouts[this.name] = this;
}

maskat.Layout.prototype.hide=function(){
    for (key in this.componentsLevel1){
        if (this.componentsLevel1[key]!=null && (typeof this.componentsLevel1[key].setVisible == "function")){
            this.componentsLevel1[key].setVisible(false);
        }
    }
}
maskat.Layout.prototype.show=function(){
    if (this.isLoaded == false){
        //レイアウトロード
        loadLayout(this.name);
        this.isLoaded = true;
        return;
    }
    for (key in this.componentsLevel1){
        if (this.componentsLevel1[key]!=null && (typeof this.componentsLevel1[key].setVisible == "function")){
            this.componentsLevel1[key].setVisible(true);
        }
    }
}
maskat.Layout.prototype.remove=function(){
    for (key in this.componentsLevel1){
        if (this.componentsLevel1[key]!=null && (typeof this.components[key].remove == "function")){
            this.componentsLevel1[key].remove();
        }
    }
    delete maskat.layouts[this.name];
}

maskat.showLayout = function(layoutName){
    var layoutObj = maskat.layouts[layoutName];
    if (layoutObj != null){
        layoutObj.show();
    }
}

maskat.hideLayout = function(layoutName){
    var layoutObj = maskat.layouts[layoutName];
    if (layoutObj != null){
        layoutObj.hide();
    }
}

maskat.removeLayout = function(layoutName){
    var layoutObj = maskat.layouts[layoutName];
    if (layoutObj != null){
        layoutObj.remove();
    }
}
// XMLの読み込み
/**
 * 通信成功後に呼び出される処理
 * 注意：targetDivはDOMオブジェクトではなく、divを取得できるjavascriptの文字列
 */
maskat.loadLayoutFile = function(layoutDefFileName, targetDiv, bToShow) {
  var xhr;
  try {
    xhr = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xhr = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {
      xhr = false;
    }
  }
  if (!xhr && typeof XMLHttpRequest!='undefined') {
    xhr = new XMLHttpRequest();
  }
  if (xhr) {
    xhr.open("GET", layoutDefFileName, false);
    xhr.send(null);
    if (xhr.readyState == 4 && xhr.status == 200) {
      try{
          var layoutDOM = xhr.responseXML;
          var rialtoJSSrc; // 変換後のJavaScriptソース
          rialtoJSSrc = maskat.interpretLayoutXML(layoutDOM, targetDiv);
          maskat.loadJSSrc(rialtoJSSrc);

          if (bToShow==true || arguments.length <= 2){
              var layoutElements = layoutDOM.getElementsByTagName("layout");
              for (var i = 0; i < layoutElements.length; i++){
                var layoutName = layoutElements[i].getAttribute("name");
                maskat.layouts[layoutName].show();
                // add KeyNavi
                document.onkeydown=maskat.setForcus;
              }
          }
          document.onselectstart = function(){return true};
      }catch(e){
          if (e instanceof MaskatError){
              alert("name: " + e.name + "\nmessage: " + e.message + "\nfileName: " + e.fileName);
          }else{
              throw e;
          }
      }

    } else if (xhr.readyState == 4) {
      alert(xhr.status);
    }
  }
}

maskat.loadEventFile = function(fileName){
  try {
    var eventDefDOM = maskat.loadXMLFile(fileName);

    maskat.loadLayoutEvents(eventDefDOM);
    maskat.loadComponentEvents(eventDefDOM);
  }
  catch (e){
      if (e instanceof MaskatError){
          alert("name: " + e.name + "\nmessage: " + e.message + "\nfileName: " + e.fileName);
      }else{
          throw e;
      }
  }
}

maskat.loadLayoutEvents = function(eventDefDOM){
  try {
    var eventNode = maskat.xpath(eventDefDOM, 'event[@id="onload"]');
    if (eventNode){
      var IDs = {component:null, event:"onload"};
      var onloadFunc = maskat.autoGenEventFunc(eventNode, eventDefDOM, IDs, null);
      onloadFunc();
    }
  }
  catch (e){
    throw e;
  }
}

maskat.loadComponentEvents = function(eventDefDOM){
  try{
    var componentNodes = maskat.xpath(eventDefDOM, 'component');
    for (var i = 0; i < componentNodes.length; i++){
      var componentNode = componentNodes[i];
      var componentID = maskat.xpath(componentNode, '@id');
      var eventNodes = maskat.xpath(componentNode, 'event');
      for (var j = 0; j < eventNodes.length; j++){
        var eventNode = eventNodes[j];
        var eventID = maskat.xpath(eventNode, '@id');
      
        var IDs = {component:componentID, event:eventID};
      
        var componentObj = null;
        try {
          componentObj = eval(IDs.component);
//          var layoutName = maskat.xpath(eventDefDOM, '@layoutName');
//          componentObj = maskat.layouts[layoutName].components[componentID];
        }
        catch (e){
          throw new MaskatError({name: "EventXML Syntax Error",
                                 message: "コンポーネント'" + IDs.component + "'が画面定義XMLに定義されていません。",
                                 fileName: "intpr.js",
                                 functionName: "maskat.loadComponentEvents"});
        }
        componentObj[IDs.event] = maskat.autoGenEventFunc(eventNode, eventDefDOM, IDs, componentObj);
      }
    }
  }
  catch (e){
    throw e;
  }
}


//イベント関数を自動生成する
maskat.autoGenEventFunc = function(eventNode, eventDefDOM, IDs, hostComponent){
  try {
  
    // <event ref="..." ...>の処理
    var eventRefID = maskat.xpath(eventNode, '@ref');
    if (eventRefID){
      var eventRefNode = maskat.xpath(eventDefDOM, 'eventRef[@id="' + eventRefID + '"]');
      if (eventRefNode){
        for (var i = 0; i < eventRefNode.childNodes.length; i++){
          eventNode.appendChild(eventRefNode.childNodes[i].cloneNode(true));
        }
        // eventNode.removeAttribute("ref");  // ref属性を二度と利用できなくする
      }
      else {
        throw new MaskatError({name: "EventXML Syntax Error",
                               message: "id値'" + eventRefID + "'を持つeventRef要素が見つかりません。",
                               fileName: "intpr.js",
                               functionName: "maskat.loadComponentEvents"});
      }
    }
  
    // <event type="local" ...>の処理
    if (maskat.xpath(eventNode, '@type') == "local"){
      return function(x){
        try {
          maskat.startFunc(eventNode, IDs);
          
          var validator = maskat.getValidator(false);
  
          // <result>の処理
          var resultNodes = maskat.xpath(eventNode, 'result');
          if (resultNodes.length == 1){
            var resultNode = resultNodes[0];
            var targetNodes = maskat.xpath(resultNode, 'target');
            for (var i = 0; i < targetNodes.length; i++){
              var targetNode = targetNodes[i];
              try {
                maskat.parseLocalTarget(targetNode, validator);
              }
              catch (e){
                if (e instanceof maskat.ValidationError){
                  validator.acceptError(e);
                }
                else {
                  throw e;
                }
              }
              if (validator.errors.length > 0){
                if (maskat.validationErrorHandler){
                  maskat.validationErrorHandler(validator.errors);
                }
                return;
              }
            }
          }
  
          maskat.finishFunc(eventNode);
        }
        catch (e){
          // これより上にエラーをthrowできないので(呼び出し元はWebブラウザとなる)、ここでalert文を出力する
          if (e instanceof MaskatError){
            alert("イベント実行時にエラーが発生しました。"
                 + "\nname: " + e.name + "\nmessage: " + e.message
                 + "\nfileName: " + e.fileName + "\nfunctionName: " + e.functionName);
          }
          else if (e instanceof MaskatProcessInterruption){
            // Do Nothing
          }
          else{
            throw e;
          }
        }
      }
    }
  
    // <event type="remote" ...>の処理
    else {
      return function(x){
        try {
          maskat.startFunc(eventNode, IDs);
          
          var validator = maskat.getValidator(false);

          // 送信電文の作成
          var sendXML;
          var paramNodes = maskat.xpath(eventNode, 'param');
          if (paramNodes.length == 1){
            var paramNode = paramNodes[0];
            var rootNode = maskat.xpath(paramNode, '@rootNode');
            var sourceNodes = maskat.xpath(paramNode, 'source');
          
            sendXML = '<' + rootNode;
            var ns = maskat.xpath(eventNode, 'param[1]/@ns');
            if (ns){
              sendXML += ' xmlns="' + ns + '"';
            }
            sendXML += '>';
            
            for (var i = 0; i < paramNode.childNodes.length; i++){
              var paramChildNode = paramNode.childNodes[i];
              if (paramChildNode.nodeType != 1){
                continue;
              }
              

              var parserFunc = maskat.intprSendTele;
              if (paramChildNode.prefix && paramChildNode.prefix != ""){
                var parserFuncName = "maskat." + paramChildNode.prefix + "SendTeleParser";
                parserFunc = eval(parserFuncName);
                if (!parserFunc){
                  throw new MaskatError({name: "Extended Syntax Error",
                                         message: "独自拡張タグ'" + paramChildNode.nodeName + "'を利用するには専用パーサとして'" + parserFuncName + "'関数を定義する必要があります。",
                                         fileName: "intpr.js",
                                         functionName: "maskat.autoGenEventFunc"});
                }
              }

              try{
                sendXML += parserFunc(paramChildNode, validator);
              }
              catch (e){
                if (e instanceof maskat.ValidationError){
                  validator.acceptError(e);
                }
                else {
                  throw e;
                }
              }
              if (validator.errors.length > 0){
                if (maskat.validationErrorHandler){
                  maskat.validationErrorHandler(validator.errors);
                }
                return;
              }
            }
            
            sendXML += '</' + rootNode + '>';

            var soap = maskat.xpath(paramNode, '@soap');
            if (soap=="true"){
                sendXML = maskat.soap.wrapMessage(sendXML,paramNode);
            }

            sendXML = '<?xml version="1.0" encoding="UTF-8"?>' + sendXML;
          }

          maskat.asyncTele(sendXML, eventNode, eventDefDOM, IDs, soap, hostComponent);
        }
        catch (e){
          // これより上にエラーをthrowできないので(呼び出し元はWebブラウザとなる)、ここでalert文を出力する
          if (e instanceof MaskatError){
            alert("イベント実行時にエラーが発生しました。"
                 + "\nname: " + e.name + "\nmessage: " + e.message
                 + "\nfileName: " + e.fileName + "\nfunctionName: " + e.functionName);
          }
          else if (e instanceof MaskatProcessInterruption){
            // Do Nothing
          }
          else{
            throw e;
          }
        }
      }
    }
  }
  catch (e){
    throw e;
  }
}

maskat.parseLocalTarget = function(targetNode, validator){
  try {
    var inName = maskat.xpath(targetNode, '@in');
    var inObj = maskat.getObjByName(inName);
    var inObjWrap;
    if (inObj){
      inObjWrap = new ObjWrapper(inObj);
    }

    var outName = maskat.xpath(targetNode, '@out');
    var outObj = maskat.getObjByName(outName);
    var outObjWrap;
    if (outObj){
      outObjWrap = new ObjWrapper(outObj);
    }

    //targetNodeのteleType属性によって、カスタマイズworkerに処理を任せる
    var workType = maskat.xpath(targetNode, '@workType');
    if (workType!=null){
        var worker = ObjWrapper.findLocalWorker(workType);
        if (worker==null){
            throw new MaskatError({name: "teleTypeエラー",
                             message: "workType:["+workType+"]は定義されていませんでした。",
                             fileName: "intpr.js",
                             functionName: "maskat.parseLocalTarget"});
        }
        worker.work(outObj,inObj,targetNode);
        return;
    }

    var typeName = maskat.xpath(targetNode, '@type');

    if (!inName && outObjWrap){
      // out属性値のオブジェクトをクリア
      outObjWrap.clear();
    }
    else if (inObjWrap && outObjWrap && (maskat.isRialtoObj(outObj) || !outObjWrap.isSingleDataObj())){
      //FIXED outObjはjavascriptの場合は、outObjWrapのsetValueはエラーになるから、避ける
      var value = inObjWrap.getSingleValue();
      if (value && value != ""){
        if (typeName && typeName != ""){
          var descName = maskat.xpath(targetNode, '@desc');
          var minName = maskat.xpath(targetNode, '@min');
          var maxName = maskat.xpath(targetNode, '@max');
          var regexp = maskat.xpath(targetNode, '@regexp');

          validator.validate(inName, value, typeName, descName, minName, maxName, regexp);
        }
     
        // TODO: in,out両者が単一値オブジェクトであるかのチェック
        outObjWrap.setSingleValue(value);
      }
      else {
        if (typeName == "required"){
          var vTarget = new Object;
          vTarget.desc = descName;
          validator.acceptError(new maskat.ValidationError(vTarget, "入力してください。"));
        }
        else {
          return;
        }
      }
    }
    else if (inObjWrap && outName && 
       ((outObjWrap==null) || (!maskat.isRialtoObj(outObj) && outObjWrap.isSingleDataObj() ))){
      //FIXED outObjはjavascriptオブジェクトの場合この分岐に
      var value = inObjWrap.getSingleValue();
      if (value && value != ""){
        if (typeName && typeName != ""){
          var descName = maskat.xpath(targetNode, '@desc');
          var minName = maskat.xpath(targetNode, '@min');
          var maxName = maskat.xpath(targetNode, '@max');
          var regexp = maskat.xpath(targetNode, '@regexp');

          validator.validate(inName, value, typeName, descName, minName, maxName, regexp);
        }

        eval(outName + " = \"" + value + "\";");
        //FIXED valueを「"」で囲まれる、valueは文字列として扱われないと、混乱を招くかもしれない。例えば： true window ....
      }
      else {
        if (typeName == "required"){
          var vTarget = new Object;
          vTarget.desc = descName;
          validator.acceptError(new maskat.ValidationError(vTarget, "入力してください。"));
        }
        else {
          return;
        }
      }
    }    
    else {
      throw new MaskatError({name: "Mapping Error",
                             message: "in'" + inName + "'からout'" + outName + "'へのマッピングに対応していません。",
                             fileName: "intpr.js",
                             functionName: "maskat.parseLocalTarget"});
    }
  }
  catch (e){
    throw e;
  }
}

maskat.LEFTBRACKETREG = new RegExp("<","g");
maskat.RIGHTBRACKETREG = new RegExp(">","g");
maskat.AMPREG = new RegExp("\&","g");

maskat.toXMLData = function(value){
   value = ""+value;
   value = value.replace(maskat.AMPREG,"&amp;");
   value = value.replace(maskat.LEFTBRACKETREG,"&lt;");
   value = value.replace(maskat.RIGHTBRACKETREG,"&gt;");
   return value;;
}

maskat.intprSendTele = function(sourceNode, validator){
  try {
    var objName = maskat.xpath(sourceNode, '@obj');
    var objObj = maskat.getObjByName(objName);

    if (objObj == null){
      throw new MaskatError({name: "Mapping Error",
                             message: "送信元オブジェクト'" + objName + "'が未定義です。",
                             fileName: "intpr.js",
                             functionName: "maskat.intprSendTele"});
    }
    
    var teleType = maskat.xpath(sourceNode,"@teleType");
    if (teleType!=null){
        var teleMaker = ObjWrapper.findTeleMaker(teleType);
        if (teleMaker==null){
            throw new MaskatError({name: "teleTypeエラー",
                             message: "sourceの属性teleType:["+teleType+"]は定義されていませんでした。",
                             fileName: "intpr.js",
                             functionName: "maskat.intprSendTele"});
            
        }
        return teleMaker.make(objObj,validator,sourceNode);
    }
    
    var objObjWrap = new ObjWrapper(objObj);

    if (objObjWrap.isSingleDataObj()){
      //// 単一値を送信
      
      var value = objObjWrap.getSingleValue();

      var typeName = maskat.xpath(sourceNode, '@type');
      var descName = maskat.xpath(sourceNode, '@desc');

      var sendBlankElementName = maskat.xpath(sourceNode, '@sendBlankElement');

      // 非空白の入力フィールドしかXML要素を生成しない
      if ((value!=null && value != "") || sendBlankElementName == "true"){
        var nodeName = maskat.xpath(sourceNode, '@node');
        
        var minName = maskat.xpath(sourceNode, '@min');
        var maxName = maskat.xpath(sourceNode, '@max');
        
        var regexp = maskat.xpath(sourceNode, '@regexp');
        
        validator.validate(objName, value, typeName, descName, minName, maxName, regexp);
        return "<" + nodeName + ">" + maskat.toXMLData(value) + "</" + nodeName + ">";
      }
      else {
        if (typeName == "required"){
          var vTarget = new Object;
          vTarget.desc = descName;
          validator.acceptError(new maskat.ValidationError(vTarget, "入力してください。"));
        }
        else {
          return "";
        }
      }
    }
    else if (objObjWrap.isMultiDataObj()){
      var fromkeyName = maskat.xpath(sourceNode, '@fromkey');
      var idxRefName = maskat.xpath(sourceNode, '@idxRef');

      if (fromkeyName){
        //// 選択行(最近選択した1行)の特定列の値(単一値)を送信

        var selectedIndex = objObjWrap.getSelectedIndex();
        if (selectedIndex != -1){
        
          var targetObjWrap = objObjWrap;
        
          var idxRefName = maskat.xpath(sourceNode, '@idxRef');  // TODO: 二重宣言
          var idxRefObj = maskat.getObjByName(idxRefName);
          if (idxRefObj){
            var idxRefObjWrap = new ObjWrapper(idxRefObj);
            if (!idxRefObjWrap.isMultiDataObj()){
              throw new MaskatError({name: "Mapping Error",
                                     message: "idxRefは複数データ型オブジェクトを指定して下さい",  // TODO:詳細に
                                     fileName: "intpr.js",
                                     functionName: "maskat.intprSendTele"});
            }
            targetObjWrap = idxRefObjWrap;
          }

          var value = targetObjWrap.getValueFromMultiData(selectedIndex, fromkeyName);
         
          var sendBlankElementName = maskat.xpath(sourceNode, '@sendBlankElement');
      
          if ((value && value != "") || sendBlankElementName == "true"){
            var nodeName = maskat.xpath(sourceNode, '@node');
            return "<" + nodeName + ">" + maskat.toXMLData(value) + "</" + nodeName + ">";
          }
        }
      }
      else if (idxRefName){
        //// 選択行データの送信

        if (objObjWrap.isMultiSelect()){
          // 複数行選択
          var childNodeName = maskat.xpath(sourceNode, '@childNode');
          if (!childNodeName){
            throw new MaskatError({name: "EventXML Syntax Error",
                                   message: "複数行選択データの送信マッピングの際には、childNode属性の指定が必須です。",  // TODO:詳細に
                                   fileName: "intpr.js",
                                   functionName: "maskat.intprSendTele"});
          }
          var nodeName = maskat.xpath(sourceNode, '@node');
          
          var indexArray = objObjWrap.getSelectedIndexes();
          
          var bindNodes = maskat.xpath(sourceNode, 'bind');
          if (bindNodes.length == 0){
            return "";
          }
          var bindMapping = new Object();
          for (i = 0; i < bindNodes.length; i++){
            var bindNode = bindNodes[i];
            var fromkeyValue = maskat.xpath(bindNode, '@fromkey');
            var nodeValue = maskat.xpath(bindNode, '@node');
            bindMapping[fromkeyValue] = new Array;
            bindMapping[fromkeyValue][0] = nodeValue;
            if (maskat.xpath(bindNode, '@sendBlankElement')=="true"){
                bindMapping[fromkeyValue][1] = true;
            }else{
                bindMapping[fromkeyValue][1] = false;
            }
          }

          var targetObjWrap = objObjWrap;

          var idxRefName = maskat.xpath(sourceNode, '@idxRef');
          var idxRefObj = maskat.getObjByName(idxRefName);
          if (idxRefObj){
            var idxRefObjWrap = new ObjWrapper(idxRefObj);
            if (!idxRefObjWrap.isMultiDataObj()){
              throw new MaskatError({name: "Mapping Error",
                                     message: "idxRefは複数データ型オブジェクトを指定して下さい",  // TODO:詳細に
                                     fileName: "intpr.js",
                                     functionName: "maskat.intprSendTele"});
            }
            targetObjWrap = idxRefObjWrap;
          }
          
          var resultXML = "";

          //var sendBlankElementName = maskat.xpath(sourceNode, '@sendBlankElement');

          for (var i = 0; i < indexArray.length; i++){
            var resultXMLRow = "";
            for (var fromkeyValue in bindMapping){
              var value = targetObjWrap.getValueFromMultiData(indexArray[i], fromkeyValue);
              var sendBlankElement = bindMapping[fromkeyValue][1];
              if ((value && value != "") || sendBlankElement == true){
                resultXMLRow += "<" + bindMapping[fromkeyValue][0] + ">" + maskat.toXMLData(value) + "</" + bindMapping[fromkeyValue][0] + ">";
              }
            }
            if (resultXMLRow != ""){
              resultXMLRow = "<" + childNodeName + ">" + resultXMLRow + "</" + childNodeName + ">";
            }
            resultXML += resultXMLRow;
          }
          if (resultXML != "" && nodeName!=null && nodeName!=""){
            resultXML = "<" + nodeName + ">" + resultXML + "</" + nodeName + ">";
          }
          
          return resultXML;
        }
        else {
          // 単一行選択

          var index = objObjWrap.getSelectedIndex();
          if (index == -1){
            return "";
          }
          
          var nodeName = maskat.xpath(sourceNode, '@node');
          
          var bindNodes = maskat.xpath(sourceNode, 'bind');
          if (bindNodes.length == 0){
            return "";
          }
          var bindMapping = new Object();
          for (i = 0; i < bindNodes.length; i++){
            var bindNode = bindNodes[i];
            var fromkeyValue = maskat.xpath(bindNode, '@fromkey');
            var nodeValue = maskat.xpath(bindNode, '@node');
            bindMapping[fromkeyValue] = new Array;
            bindMapping[fromkeyValue][0] = nodeValue;
            if (maskat.xpath(bindNode, '@sendBlankElement')=="true"){
                bindMapping[fromkeyValue][1] = true;
            }else{
                bindMapping[fromkeyValue][1] = false;
            }
          }
          
          var targetObjWrap = objObjWrap;

          var idxRefName = maskat.xpath(sourceNode, '@idxRef');
          var idxRefObj = maskat.getObjByName(idxRefName);
          if (idxRefObj){
            var idxRefObjWrap = new ObjWrapper(idxRefObj);
            if (!idxRefObjWrap.isMultiDataObj()){
              throw new MaskatError({name: "Mapping Error",
                                     message: "idxRefは複数データ型オブジェクトを指定して下さい",  // TODO:詳細に
                                     fileName: "intpr.js",
                                     functionName: "maskat.intprSendTele"});
            }
            targetObjWrap = idxRefObjWrap;
          }
          
          var resultXML = "";
          
          //var sendBlankElementName = maskat.xpath(sourceNode, '@sendBlankElement');

          for (var fromkeyValue in bindMapping){
            var value = targetObjWrap.getValueFromMultiData(index, fromkeyValue);
            var sendBlankElement = bindMapping[fromkeyValue][1];
            if ((value && value != "") || sendBlankElement == true){
              resultXML += "<" + bindMapping[fromkeyValue][0] + ">" + maskat.toXMLData(value) + "</" + bindMapping[fromkeyValue][0] + ">";
            }
          }

          if (nodeName!=null && nodeName!="") 
             resultXML = "<" + nodeName + ">" + resultXML + "</" + nodeName + ">";
  
          return resultXML;
        }
      }
      else {
        // 複数データ型のデータ全てを送信

        var childNodeName = maskat.xpath(sourceNode, '@childNode');
        if (childNodeName){
          // TODO: MaskatError
        }
        var nodeName = maskat.xpath(sourceNode, '@node');
      
        var bindNodes = maskat.xpath(sourceNode, 'bind');
        if (bindNodes.length == 0){
          return "";
        }
        var bindMapping = new Object();
        for (var i = 0; i < bindNodes.length; i++){
          var bindNode = bindNodes[i];
          var fromkeyValue = maskat.xpath(bindNode, '@fromkey');
          var nodeValue = maskat.xpath(bindNode, '@node');
          bindMapping[fromkeyValue] = new Array;
          bindMapping[fromkeyValue][0] = nodeValue;
            if (maskat.xpath(bindNode, '@sendBlankElement')=="true"){
                bindMapping[fromkeyValue][1] = true;
            }else{
                bindMapping[fromkeyValue][1] = false;
            }
        }

        var resultXML = "";
        
        //var sendBlankElementName = maskat.xpath(sourceNode, '@sendBlankElement');

        for (i = 0; i < objObjWrap.getRowNum(); i++){
          var resultXMLRow = "";
          for (var fromkeyValue in bindMapping){
            var value = objObjWrap.getValueFromMultiData(i, fromkeyValue);
            var sendBlankElement = bindMapping[fromkeyValue][1];
            if ((value && value != "") || sendBlankElement == true){
              resultXMLRow += "<" + bindMapping[fromkeyValue][0] + ">" + maskat.toXMLData(value) + "</" + bindMapping[fromkeyValue][0] + ">";
            }
          }
          if (resultXMLRow != ""){
            resultXMLRow = "<" + childNodeName + ">" + resultXMLRow + "</" + childNodeName + ">";
          }
          resultXML += resultXMLRow;
        }
        if (resultXML != "" && nodeName!=null && nodeName!=""){
          resultXML = "<" + nodeName + ">" + resultXML + "</" + nodeName + ">";
        }
        return resultXML;
      }
    }
    return "";
  }
  catch (e){
    throw e;
  }
}

maskat.toParamStr = function(obj){
    if (obj==null || obj==undefined){
        return "";
    }
    return obj.toString();
}


maskat.intprRecvTele = function(eventNode, teleDOM){
  try {
    var eventType = maskat.xpath(eventNode, '@type');
    var resultNodes = maskat.xpath(eventNode, 'result');
    var resultNode;
    if (resultNodes.length == 1){
      resultNode = resultNodes[0];
    }
    
    if (teleDOM.nodeName == "errors"){
      var onErrorTele;
      if (resultNode){
        onErrorTele = maskat.xpath(resultNode, '@onErrorTele');
      }
      
      if (onErrorTele){
        try {
          eval(onErrorTele + "(teleDOM);");
        }
        catch (e){
          throw new MaskatError({name: "onErrorTele Error",
                                 message: "onErrorTele関数が定義されていません。",
                                 fileName: "intpr.js",
                                 functionName: "maskat.intprRecvTele"});
        }
      }
      else {
        // デフォルトのエラー電文処理関数で処理
        maskat.processErrorTele(teleDOM);
      }
      throw new MaskatProcessInterruption(
          {name: "intprRecvTele Function Interruption",
           message: "エラー電文処理関数実行後の処理停止",
           fileName: "intpr.js",
           functionName: "maskat.intprRecvTele"});
    }
    else if (resultNode) {
      var rootNode = maskat.xpath(resultNode, '@rootNode');
      var soap = maskat.xpath(resultNode, '@soap');
      if (soap=="true"){
          teleDOM = maskat.soap.unwrapDOM(teleDOM,resultNode);
      }
      
      if (teleDOM.nodeName != rootNode){
        throw new MaskatError({name: "Received Tele Error",
                               message: "受信電文XMLのルートノード名'" + teleDOM.nodeName + "'とイベント定義XMLで指定した受信電文XMLのルートノード名'" + rootNode + "'が一致していません。",
                               fileName: "intpr.js",
                               functionName: "maskat.intprRecvTele"});
      }
      else{
        var eventNodeType = maskat.xpath(eventNode, '@type');
        var targetNodes = maskat.xpath(resultNode, 'target');
        for (var i = 0; i < targetNodes.length; i++){
          var targetNode = targetNodes[i];
          var targetNodeType = maskat.xpath(targetNode, '@type');
          if (targetNodeType != "local" && eventNodeType != "local"){
            maskat.parseRemoteTarget(targetNode, teleDOM);
          }
          else {
            maskat.parseLocalTarget(targetNode);
          }
        }
      }
    }

    //maskat.finishFunc(eventNode);
  }
  catch (e){
    throw e;
  }
}

maskat.parseRemoteTarget = function(targetNode, teleDOM){
  try {
    var outName = maskat.xpath(targetNode, '@out');
    var outObj = maskat.getObjByName(outName);
    var outObjWrap;
    if (outObj){
      outObjWrap = new ObjWrapper(outObj);
    }

    //targetNodeのteleType属性によって、カスタマイズwrapperバインディング
    var teleType = maskat.xpath(targetNode, '@teleType');
    if (teleType!=null){
        var pluggableTeleConsumer = ObjWrapper.findTeleConsumer(teleType);
        if (pluggableTeleConsumer==null){
            throw new MaskatError({name: "teleTypeエラー",
                             message: "teleType:["+teleType+"]は定義されていませんでした。",
                             fileName: "intpr.js",
                             functionName: "maskat.parseRemoteTarget"});
        }
        pluggableTeleConsumer.consume(outObj,maskat.xpath(teleDOM, maskat.xpath(targetNode, '@in')));
        return;
    }

    // 受信電文のデータ形式と、出力先オブジェクトの受け入れ可能データ形式との整合性チェック
    var isInSingleData = false;
    var isInMultiData = false;
    var isOutJSObj = false;
    var isOutSingleData = false;
    var isOutMultiData = false;
    if (maskat.xpath(targetNode, '@inkey')){
      isInMultiData = true;
    }
    else {
      isInSingleData = true;
    }
    if (!outObjWrap || outObjWrap.isJSObj()){
      isOutJSObj = true;
    }
    if (outObjWrap && outObjWrap.isSingleDataObj()){
      isOutSingleData = true;
    }
    else if (outObjWrap && outObjWrap.isMultiDataObj()){
      isOutMultiData = true;
    }
    if (!(isOutJSObj || (isInSingleData && isOutSingleData) || (isInMultiData && isOutMultiData))){
      var inDataType = "未対応型";
      var outDataType = "未対応型";
      if (isInSingleData){
        inDataType = "単一データ型";
      }
      else if (isInMultiData){
        inDataType = "複数データ型";
      }
      if (isOutSingleData && isOutMultiData){
        outDataType = "単一/複数両用データ型";
      }
      else if (isOutSingleData){
        outDataType = "単一データ型";
      }
      else if (isOutMultiData){
        outDataType = "複数データ型";
      }
      throw new MaskatError({name: "Mapping Error",
                             message: "受信電文のデータ形式(" + inDataType + ")と、出力先オブジェクトの受け入れ可能データ形式(" + outDataType + ")が一致していません。",
                             fileName: "intpr.js",
                             functionName: "maskat.parseRemoteTarget"});
    }

    // 受信電文データを取得
    var inData;
    if (isInSingleData){
      inData = maskat.xpath(teleDOM, maskat.xpath(targetNode, '@in') + '/text()');
    }
    else if (isInMultiData){
      var i;
      var bindNodes = maskat.xpath(targetNode, 'bind');
      var bindMapping;
      if (bindNodes.length != 0){
        bindMapping = new Object();
        for (i = 0; i < bindNodes.length; i++){
          var bindNode = bindNodes[i];
          var tokeyValue = maskat.xpath(bindNode, '@tokey');
          var nodeValue = maskat.xpath(bindNode, '@node');
          bindMapping[nodeValue] = tokeyValue;
        }
      }
 
      var inValue = maskat.xpath(targetNode, '@in');
      var inkeyValue = maskat.xpath(targetNode, '@inkey');
      var xpath;
      if (inValue==null || inValue==""){
          xpath = inkeyValue;
      }else{
          xpath = inValue + "[1]/" + inkeyValue;
      }
      var teleRowNodes = maskat.xpath(teleDOM, xpath);
      if (teleRowNodes.length == 0){
        // 受信電文にgridデータが無い
        return;
      }

      var inData = new Array(teleRowNodes.length);
      for (i = 0; i < inData.length; i++){
        inData[i] = new Object();
      }

      if (bindMapping){
        for (i = 0; i < teleRowNodes.length; i++){
          var teleRowNode = teleRowNodes[i];
          for (var nodeValue in bindMapping){
            var colNodes = maskat.xpath(teleRowNode, nodeValue);
            if (colNodes.length == 1){
              inData[i][bindMapping[nodeValue]] = maskat.xpath(colNodes[0], "text()");
            }
          }
        }
      }
      else {
        for (i = 0; i < teleRowNodes.length; i++){
          var teleRowNode = teleRowNodes[i];
          for (var j = 0; j < teleRowNode.childNodes.length; j++){
            if (teleRowNode.childNodes[j].nodeType != 1){
              continue;
            }
            if (teleRowNode.childNodes[j].hasChildNodes())
                inData[i][teleRowNode.childNodes[j].nodeName] = teleRowNode.childNodes[j].childNodes[0].nodeValue;
            else
                inData[i][teleRowNode.childNodes[j].nodeName] = "";
          }
        }
      }
    }

    /*
    // 受信電文データのデバッグ出力
    if (maskat.isArray(inData)){
      for (var i = 0; i < inData.length; i++){
        for (var j in inData[i]){
          alert(inData[i][j]);
        }
      }
    }
    else{
      alert(inData);
    }
    */

    // 出力先オブジェクトに受信電文データを設定
    if (isOutJSObj){
      eval(outName + " = inData");
    }
    else if (outObjWrap && outObjWrap.isSingleDataObj()){
      outObjWrap.setSingleValue(inData);
    }
    else if (outObjWrap && outObjWrap.isMultiDataObj()){
      outObjWrap.setMultiValue(inData);
    }
  }
  catch (e){
    throw e;
  }
}

//グローバル範囲でname変数を取得する、定義されなければ、undefinedを戻り値とする
maskat.getObjByName = function(name){
  var obj = null;
  try{
    obj = eval(name);
  }
  catch (e){
  }
  return obj;
}


// デフォルトのエラー電文処理関数
maskat.processErrorTele = function(teleDOM){
  try {
    var errorCodeText = maskat.xpath(teleDOM, 'error/errorCode/text()');
    var messageCodeText = maskat.xpath(teleDOM, 'error/messageCode/text()');
    var messageText = maskat.xpath(teleDOM, 'error/message/text()');
    var infoText = maskat.xpath(teleDOM, 'error/info/text()');
    var systemErrorMessageText = maskat.xpath(teleDOM, 'error/systemErrorMessage/text()');

    var errorMsg = "エラーが発生しました。\nerrorCode:" + errorCodeText + "\nmessageCode:"
                   + messageCodeText + "\nmessage:" + messageText;
    if (infoText){
      errorMsg += "\ninfo:" + infoText;
    }
    if (systemErrorMessageText){
      errorMsg += "\nsystemErrorMessage:" + systemErrorMessageText;
    }

    throw new MaskatError({name: "Received Tele Error",
                           message: errorMsg,
                           fileName: "intpr.js",
                           functionName: "maskat.processErrorTele"});
  }
  catch (e){
    throw e;
  }
}





// 同期通信でサーバからXMLファイルを取得し、そのDOMのdocumentElementを返す
maskat.loadXMLFile = function(xmlFile){
  var xhr;
  try {
    xhr = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xhr = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {
      xhr = false;
    }
  }
  if (!xhr && typeof XMLHttpRequest != 'undefined') {
    xhr = new XMLHttpRequest();
  }
  if (xhr) {
    xhr.open("GET", xmlFile, false);
    xhr.send(null);
    if (xhr.readyState == 4){
      if (xhr.status == 200) {
        if (xhr.responseXML && xhr.responseXML.nodeType == 9){
          return(xhr.responseXML.documentElement);
        }
        else {
          throw new MaskatError({name: "File Error",
                               message: "サーバから取得したファイル'" + xmlFile + "'が正規のXML文書ではありません。\nファイル内のテキスト文字列: " + xhr.responseText,
                               fileName: "intpr.js",
                               functionName: "maskat.loadXMLFile"});
        }
      }
      else {
        throw new MaskatError({name: "XMLHttpRequest Error",
                               message: "サーバからファイル'" + xmlFile + "'を正常に取得できませんでした。\nXMLHttpRequest#readyState: " + xhr.readyState + "\nXMLHttpRequest#status: " + xhr.status,
                               fileName: "intpr.js",
                               functionName: "maskat.loadXMLFile"});
      }
    }
  }
  else{
    throw new MaskatError({name: "XMLHttpRequest Error",
                           message: "XMLHttpRequestオブジェクトが取得できませんでした。",
                           fileName: "intpr.js",
                           functionName: "maskat.loadXMLFile"});
  }
}

maskat.asyncTele = function(data, eventNode, eventDefDOM, IDs, soap, hostComponent){
  try {
    // XMLHttpRequestオブジェクトの取得
    var xhr;
    try {
      xhr = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {
        xhr = false;
      }
    }
    if (!xhr && typeof XMLHttpRequest != 'undefined') {
      xhr = new XMLHttpRequest();
    }
    if (!xhr) {
      throw new MaskatError({name: "XMLHttpRequest Error",
                             message: "XMLHttpRequestオブジェクトが取得できませんでした。",
                             fileName: "intpr.js",
                             functionName: "maskat.asyncTele"});
    }

    // remoteUrl属性値の取得
    var remoteUrl = maskat.xpath(eventNode, '@remoteUrl');
    if (!remoteUrl){
      remoteUrl = maskat.xpath(eventDefDOM, 'remoteUrl/@url');
      if (!remoteUrl){
        throw new MaskatError({name: "EventXML Syntax Error",
                               message: "リモート通信するイベント要素に対してはremoteUrlの指定が必須です。",
                               fileName: "intpr.js",
                               functionName: "maskat.asyncTele"});
      }
    }

    // async属性値の取得
    var async = maskat.xpath(eventNode, '@async');
    if (async==null || async == "true"){//デフォルトは非同期
      async = true;
    }
    else {
      async = false;
    }
    xhr.open("POST", remoteUrl, true);  // async=true(同期通信)でも内部的には非同期通信を行う

    // ヘッダ処理
    var headerNodes = maskat.xpath(eventNode, 'header');
    for (var i = 0; i < headerNodes.length; i++){
      var headerValue = encodeURI(maskat.xpath(headerNodes[i], '@value'));
      xhr.setRequestHeader(maskat.xpath(headerNodes[i], '@name'), headerValue);
    }
    headerNodes = maskat.xpath(eventDefDOM, 'header');
    for (var i = 0; i < headerNodes.length; i++){
      var headerValue = encodeURI(maskat.xpath(headerNodes[i], '@value'));
      xhr.setRequestHeader(maskat.xpath(headerNodes[i], '@name'), headerValue);
    }
    if (soap=="true"){
       xhr.setRequestHeader("Content-Type", "application/soap+xml");
    }
    else {
       xhr.setRequestHeader("Content-Type", "application/xml");
    }
    if (IDs.component){
      xhr.setRequestHeader("maskat_componentID", IDs.component);
    }
    xhr.setRequestHeader("maskat_eventID", IDs.event);

    // タイムアウト
    var timeout = maskat.xpath(eventNode, '@timeout');
    if (timeout){
      var onTimeoutError = maskat.xpath(eventNode, '@onTimeoutError');
      if (onTimeoutError){
        try {
          onTimeoutError = eval(onTimeoutError);
        }
        catch (e){
          throw new MaskatError({name: "onTimeoutError Error",
                                 message: "onTimeoutError関数' + onTimeoutError + 'が定義されていません。",
                                 fileName: "intpr.js",
                                 functionName: "maskat.asyncTele"});
        }
      }
      else {
        // デフォルトのonTimeoutError関数で処理
        onTimeoutError = maskat.defaultOnTimeoutError;
      }
    }
    
    
    var sendObj = new maskat.sendObj({xhr: xhr, data: data, async: async,
                        eventNode: eventNode, IDs: IDs, timeout: timeout,
                        onTimeoutError: onTimeoutError, hostComponent: hostComponent});
    
    // コールバック関数の設定
    var callbackFunc = maskat.autoCallBackFunc(sendObj);
    xhr.onreadystatechange = callbackFunc;
    
    maskat.globalVar.sendQueueThread.add(sendObj);

    if (CrossBrowser.isFF && async == "false"){
      // FireFoxのXMLHttpRequest同期通信ではコールバックとしてonreadystatechangeは呼ばれないので、ここで明示的に呼ぶ
      callbackFunc();
    }

  }
  catch (e){
    if (sendObj!=null && sendObj.async!=true){
      sendObj.commuEnd();
    }
    throw e;
  }
}


maskat.globalVar.sendObjUniqueID = 0;
maskat.globalVar.syncConn = false;  // 起動時はfalse


maskat.sendObj = function(param){
  this.id = maskat.globalVar.sendObjUniqueID++;
  this.xhr = param.xhr;
  this.data = param.data;
  this.async = param.async;
  this.eventNode = param.eventNode;
  this.IDs = param.IDs;
  this.timeout = param.timeout;
  this.onTimeoutError = param.onTimeoutError;
  this.hostComponent = param.hostComponent;
}
maskat.sendObj.prototype.send = function(){
  maskat.beforeFunc(this.eventNode, this.xhr, this.data, this.IDs);
  
  maskat.globalVar.processingHash.add(this);
  if (this.hostComponent instanceof rialto.widget.Button && this.hostComponent.setEnable != null
          && this.async == false){
      this.hostComponent.setEnable(false);
  }
  
  if (this.timeout){
    this.onTimeoutErrorID = setTimeout("maskat.globalVar.processingHash.timeout(" + this.id + ")" , this.timeout);
  }
  
  this.xhr.send(this.data);
}
maskat.sendObj.prototype.receive = function(){
  maskat.autoCallBackFunc2(this);
}
maskat.sendObj.prototype.commuEnd = function(){
  if (this.hostComponent instanceof rialto.widget.Button && this.hostComponent.setEnable != null
          && this.async == false){
      this.hostComponent.setEnable(true);
      this.hostComponent = null;
  }
  if (this.async!=true && maskat.globalVar.syncConnDialog!=null && 
      maskat.globalVar.syncConnDialog.remove!=null){
       // ダイアログボックス閉じる
       maskat.globalVar.syncConnDialog.remove();
       maskat.globalVar.syncConnDialog = null;
       // 同期通信
       maskat.globalVar.syncConn = false;
  }
}


maskat.sendQueueThread = function(){
  this.queue = new Array();
}
maskat.sendQueueThread.prototype.add = function(obj){
  this.queue.push(obj);
  this.sendCheck();
}
maskat.sendQueueThread.prototype.sendCheck = function(){
 try{
  var thisObj = maskat.globalVar.sendQueueThread;
  if (thisObj.queue.length > 0){
    if (!maskat.globalVar.syncConn){
      maskat.globalVar.syncConn = true;  // 同期/非同期に関わらずすぐにロックをかける
      var sendObj = thisObj.queue.shift();
      if (!sendObj.async){
        // ダイアログボックス表示
        var _maskat_connecting_popup = new rialto.widget.PopUp('_maskat_connecting_popup', 50, 50, 250, 50,
            null, '通信中', 'Transparent', {withCloseButon:false});
        var _maskat_connecting_label = new rialto.widget.Label('_maskat_connecting_label', 10, 10,
            _maskat_connecting_popup, '通信中です。しばらくお待ち下さい。', null,
            {name:'_maskat_connecting_label', top:10, left:10, text:'通信中です。しばらくお待ち下さい。',
            parent:_maskat_connecting_popup});
        maskat.globalVar.syncConnDialog = _maskat_connecting_popup;
      }
      else {
        maskat.globalVar.syncConn = false;  // 非同期であればこの時点でロック解除
      }
      sendObj.send();
      thisObj.sendCheck();
    }
    else {
      setTimeout(thisObj.sendCheck, 500);
    }
   }
 }catch(e){
      if (sendObj!=null)
         sendObj.commuEnd();

      // これより上にエラーをthrowできないので(非同期通信時のmaskat.autoCallBackFuncの
      // 呼び出し元はWebブラウザとなる)、ここでalert文を出力
      if (e instanceof MaskatError){
        alert("maskat.autoCallBackFunc呼び出し時にエラーが発生しました。"
             + "\nname: " + e.name + "\nmessage: " + e.message
             + "\nfileName: " + e.fileName + "\nfunctionName: " + e.functionName);
      }
  }
}
maskat.globalVar.sendQueueThread = new maskat.sendQueueThread();


maskat.processingHash = function(){
  this.hash = new Object();
}
maskat.processingHash.prototype.add = function(obj){
  this.hash[obj.id] = obj;
}
maskat.processingHash.prototype.remove = function(obj){
  this.hash[obj.id] = undefined;
}
maskat.processingHash.prototype.timeout = function(id){
  var timeoutObj = this.hash[id];
  
  timeoutObj.xhr.abort();
  timeoutObj.commuEnd();
  timeoutObj.onTimeoutError();
  this.hash[id] = undefined;
}
maskat.globalVar.processingHash = new maskat.processingHash();


maskat.receiveQueueThread = function(){
  this.queue = new Array();
}
maskat.receiveQueueThread.prototype.add = function(obj){
  this.queue.push(obj);
  this.receiveCheck();
}
maskat.receiveQueueThread.prototype.receiveCheck = function(){
  var thisObj = maskat.globalVar.receiveQueueThread;
  if (thisObj.queue.length > 0){
    if (!maskat.globalVar.syncConn){
      var receiveObj = thisObj.queue.shift();
      receiveObj.receive();
      thisObj.receiveCheck();
    }
    else {
      setTimeout(thisObj.receiveCheck, 500);
    }
  }
}
maskat.globalVar.receiveQueueThread = new maskat.receiveQueueThread();


maskat.defaultOnTimeoutError = function(){
  alert("defaultOnTimeoutError");
}


maskat.autoCallBackFunc = function(sendObj){
  return function(){
    try{
      if (sendObj.xhr.readyState == 4){
        if (sendObj.xhr.status == 200){
        
          // タイムアウト解除
          if (sendObj.timeout){
            clearTimeout(sendObj.onTimeoutErrorID);
          }
          
          maskat.globalVar.processingHash.remove(sendObj.id);

          if (sendObj.async){
            // 非同期通信
            maskat.globalVar.receiveQueueThread.add(sendObj);
          }
          else {
            // 同期通信
            maskat.autoCallBackFunc2(sendObj);
          }
        }
        else if (sendObj.xhr.status == 0){
          // timeoutエラーのXHR#abort時
        }
        else{
          throw new MaskatError({name: "XMLHttpRequest Error",
                                 message: "サーバから受信電文を正常に取得できませんでした。\nXHR#readyState: " + sendObj.xhr.readyState + "\nXHR#status: " + sendObj.xhr.status,
                                 fileName: "intpr.js",
                                 functionName: "maskat.autoCallBackFunc"});
        }
      }
    }
    catch (e){
      if (sendObj!=null)
         sendObj.commuEnd();

      // これより上にエラーをthrowできないので(非同期通信時のmaskat.autoCallBackFuncの
      // 呼び出し元はWebブラウザとなる)、ここでalert文を出力
      if (e instanceof MaskatError){
        alert("maskat.autoCallBackFunc呼び出し時にエラーが発生しました。"
             + "\nname: " + e.name + "\nmessage: " + e.message
             + "\nfileName: " + e.fileName + "\nfunctionName: " + e.functionName);
      }
      else if (e instanceof MaskatProcessInterruption){
        // Do Nothing
      }
      else{
        throw e;
      }
    }
  };
}

maskat.autoCallBackFunc2 = function(sendObj){
  sendObj.recvDOM = sendObj.xhr.responseXML.documentElement;
  maskat.afterFunc(sendObj);
  maskat.intprRecvTele(sendObj.eventNode, sendObj.recvDOM);

  sendObj.commuEnd();
  maskat.finishFunc(sendObj.eventNode);
}


maskat.startFunc = function(eventNode, IDs){
  try {
    var startFunc = maskat.xpath(eventNode, '@start');
    if (startFunc){
      var param = new Object();
      param.stopProcess = false;
      try{
        eval(startFunc + "(param);");
      }
      catch (e){
        throw e;  // TODO: MaskatErrorに変更？IDs利用
      }
      if (param.stopProcess){
        throw new MaskatProcessInterruption(
          {name: "Start Function Interruption",
           message: "componentID'" + IDs.component + "',eventID'" + IDs.event + "'のstart関数内で処理停止",
           fileName: "intpr.js",
           functionName: "maskat.startFunc"});
      }
    }
  }
  catch (e){
    throw e;
  }
}

maskat.beforeFunc = function(eventNode, xhr, sendXML, IDs){
    var beforeFunc = maskat.xpath(eventNode, '@before');
    if (beforeFunc){
      var param = new Object();
      param.stopProcess = false;
      param.xhr = xhr;
      param.sendXML = sendXML;
      try{
        eval(beforeFunc + "(param);");
      }
      catch(e){
        throw e;  // TODO: MaskatErrorに変更？
      }
      if (param.stopProcess){
        throw new MaskatProcessInterruption(
          {name: "Before Function Interruption",
           message: "componentID'" + IDs.component + "',eventID'" + IDs.event + "'のbefore関数内で処理停止",
           fileName: "intpr.js",
           functionName: "maskat.beforeFunc"});
      }
    }
}

maskat.afterFunc = function(sendObj){
  try {
    var afterFunc = maskat.xpath(sendObj.eventNode, '@after');
    if (afterFunc){
      var param = new Object();
      param.stopProcess = false;
      param.xhr = sendObj.xhr;
      param.recvDOM = sendObj.recvDOM;
      try{
        eval(afterFunc + "(param);");
        sendObj.recvDOM = param.recvDOM;
      }
      catch(e){
        alert("after関数実行中、エラーが発生："+e.message);  // TODO: エラーオブジェクト
      }
      if (param.stopProcess){
        throw new MaskatProcessInterruption(
          {name: "After Function Interruption",
           message: "componentID'" + sendObj.IDs.component + "',eventID'" + sendObj.IDs.event + "'のafter関数内で処理停止",
           fileName: "intpr.js",
           functionName: "maskat.afterFunc"});
      }
    }
  }
  catch (e){
    throw e;
  }
}

maskat.finishFunc = function(eventNode){
  try {
    var finishFunc = maskat.xpath(eventNode, '@finish');
    if (finishFunc){
      try{
        eval(finishFunc + "();");
      }
      catch(e){
        alert("finish関数実行中、エラーが発生："+e.message);  // TODO: エラーオブジェクトを返す
      }
    }
  }
  catch (e){
    throw e;
  }
}

/* Mask@版XPath制限事項
   ・ロケーションパスは相対ロケーションパスのみ指定可能。
   ・軸(axis)はchildとattributeのみ。childとattributeはそれぞれ省略記法のみ(child:(省略して何も書かない), attribute: @)
   ・ノードテスト(nodetest)は要素名(child軸の場合)、属性名(attribute軸の場合)、'text()'のみ
   ・述語(predicate)はchild軸に対してのみ利用可能
   ・述語は[n]か[@name="value"]のみ。左記述語を複数回並べて指定することを禁止。
   ・[注意] 述語の[n]のnは1-index。ゼロ始まりではない。
   Mask@版XPath拡張事項
   ・attribute軸はロケーションステップの最後、かつ単一Nodeに対してのみ利用可能。
     その場合、戻り値は属性名の文字列。属性が定義されていない場合はnull。
   ・text()ノードテストはロケーションステップの最後、かつ単一親Nodeに対してのみ利用可能。
     その場合、戻り値はテキスト文字列。
   ・ロケーションステップの最後に述語が使われていた場合、戻り値は単一Nodeとする(述語がマッチしなければnullを返す)。
   ・その他の場合の戻り値: Node集合
*/

maskat.xpath = function(dom, locationPath){
  var locationStep = locationPath.split("/");
  var i;
  var j;
  var k;
  
  if (!dom || dom.nodeType != 1){  // ELEMENT_NODE
    throw new MaskatError({name: "Mask@XPath Syntax Error",
                           message: "引数domが不正です。引数domにはDOMの要素ノードを指定して下さい。",
                           fileName: "intpr.js",
                           functionName: "maskat.xpath"});
  }
  
  var domArray = new Array();

  domArray.push(dom);
  
  var isLastPredicate = false;
  
  for (i = 0; i < locationStep.length; i++){
    var domNextArray = new Array();
    for (j = 0; j < domArray.length; j++){

      // 軸がattributeの場合
      if (locationStep[i].charAt(0) == "@"){
        if (i != locationStep.length - 1 || domArray.length != 1){
          throw new MaskatError({name: "Mask@XPath Syntax Error",
                                 message: "attribute軸はロケーションステップの最後、かつ単一Nodeに対してのみ利用可能です。\nエラーが発生したロケーションパス: " + locationPath,
                                 fileName: "intpr.js",
                                 functionName: "maskat.xpath"});
        }
        else {
          var attributeName = locationStep[i].substring(1, locationStep[i].length);
          var attributeNode = domArray[j].getAttributeNode(attributeName);
          if (attributeNode){
            // すぐに属性値(文字列)を返す
            return attributeNode.nodeValue;
          }
          else {
            // 属性が設定されていない場合はすぐにnullを返す
            return null;
          }
        }
      }
      
      // ノードテストがtext()のchild軸の場合
      else if (locationStep[i] == "text()"){
        if (i != locationStep.length - 1 || domArray.length != 1){
          throw new MaskatError({name: "Mask@XPath Syntax Error",
                                 message: "text()ノードテストはロケーションステップの最後、かつ単一親Nodeに対してのみ利用可能です。\nエラーが発生したロケーションパス: " + locationPath,
                                 fileName: "intpr.js",
                                 functionName: "maskat.xpath"});
        }
        else {
          if (domArray[j].childNodes && domArray[j].childNodes.length == 1
                 && (domArray[j].childNodes[0].nodeType == 3 || domArray[j].childNodes[0].nodeType == 4)){
            return domArray[j].childNodes[0].nodeValue;
          }
          else if (domArray[j].childNodes && domArray[j].childNodes.length == 0){
            return "";
          }
          else {
            throw new MaskatError({name: "Mask@XPath Syntax Error",
                                   message: "text()ノードテストを指定したノードのXML形式が不正です。\nエラーが発生したロケーションパス: " + locationPath,
                                   fileName: "intpr.js",
                                   functionName: "maskat.xpath"});
          }
        }
      }
      
      // ノードテストが要素名のchild軸の場合
      else{

        var nodeTest = null;
        var predicate = null;
        var predicateAttributeName = null;
        var predicateAttributeValue = null;
        var nodePos = 0;
    
        if (locationStep[i].indexOf("[") != -1){
          nodeTest = locationStep[i].substring(0, locationStep[i].indexOf("["));
          predicate = locationStep[i].substring(locationStep[i].indexOf("[") + 1, locationStep[i].indexOf("]"));

          if (predicate.charAt(0) == "@"){
            predicateAttributeName = predicate.substring(1, predicate.indexOf("="));
            predicateAttributeValue = predicate.substring(predicate.indexOf("=") + 2, predicate.length - 1); // ダブルクォートのことを考慮に入れる
          }
          else {
            nodePos = parseInt(predicate);
            if (isNaN(nodePos)){
              throw new MaskatError({name: "Mask@XPath Syntax Error",
                                     message: "述語が不正です。\nエラーが発生したロケーションパス: " + locationPath,
                                     fileName: "intpr.js",
                                     functionName: "maskat.xpath"});
            }
          }
          
          if (i == locationStep.length - 1){
            isLastPredicate = true;
          }
          
        }
        else{
          nodeTest = locationStep[i];
        }
        
        var currentNodePos = 0;  // 述語[n]を処理するために利用

        for (k = 0; k < domArray[j].childNodes.length; k++){
          var childNode = domArray[j].childNodes[k];
          if (childNode.nodeType != 1){  // ELEMENT_NODE
            continue;
          }
          if (childNode.nodeName == nodeTest){
            currentNodePos++;
            if (predicate){
              if (predicateAttributeName){
                if (childNode.getAttribute(predicateAttributeName) != predicateAttributeValue){
                  continue;
                }
                else if (isLastPredicate){
                  return childNode;
                }
              }
              else {
                if (nodePos != currentNodePos){
                  continue;
                }
                else if (isLastPredicate){
                  return childNode;
                }
              }
            }
            domNextArray.push(childNode);
          }
        }
      }
    }
    domArray = domNextArray;
  }

  if (isLastPredicate){
    return null;
  }
  else {
    return domArray;
  }
}

 maskat.RadioGroup = function(group){
  this.group = group;
  this.type = "radioGroup";
  this.base = rialto.widget.AbstractComponent;
  this.radioMemberArray = new Array();
  this.radioMemberNameArray = new Array();
  this.tabIndex=0;
}

maskat.RadioGroup.prototype = new rialto.widget.AbstractComponent;

maskat.RadioGroup.prototype.addRadioMemberName = function(radioMemberName){
  this.radioMemberNameArray.push(radioMemberName);
}

maskat.RadioGroup.prototype.addRadioMember = function(radioMember){
  this.radioMemberArray.push(radioMember);
}

maskat.RadioGroup.prototype.getSelValue = function(){
  for (var i = 0; i < this.radioMemberArray.length; i++){
    if (this.radioMemberArray[i].isCheck()){
      return this.radioMemberArray[i].name;
    }
  }
  return "";
}

maskat.RadioGroup.prototype.setSelValue = function(radioName){
  for (var i = 0; i < this.radioMemberArray.length; i++){
    if (this.radioMemberArray[i].name == radioName){
      this.radioMemberArray[i].setCheck(true);
      return;
    }
  }
}

maskat.RadioGroup.prototype.initRadio = function(){
  for (var i = 0; i < this.radioMemberArray.length; i++){
    this.radioMemberArray[i].setCheck(false);
  }
}

// タブインデックス用
var focusObj = null;
var focusNode = null;
var tagIndexMap = new Object();

maskat.syntax = {
  AbstractComponent: {
    bWithoutPlaceIn: {type: "boolean"},
    name: {type: "string"},
    type: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    width: {type: "string"},
    height: {type: "string"},
    position: {type: "enum", elem: ["static", "absolute", "relative"], def: "absolute"},
    enable: {type: "boolean"},
    draggable: {type: "boolean"},
    resizable: {type: "boolean"},
    autoResizableH: {type: "boolean"},
    autoResizableW: {type: "boolean"}
  },
  layoutDef: {
  },
  layout: {
    name: {type: "string", req: true},
    refParentHTML: {type: "string", req: false}
  },
  window: {
    parent: {type: "object"},
    title: {type: "string"},
    icone: {type: "string"},
    style: {type: "enum", elem: ["default", "fenetre"], def: "fenetre"}
  },
  frame: {
    dynamic: {type: "boolean"},
    open: {type: "boolean"},
    title: {type: "string"},
    printTitle: {type: "string"},
    autoResizeContenu: {type: "boolean"},
    autoResizeParent: {type: "boolean"},
    boolPrint: {type: "boolean"},
    boolMaxi: {type: "boolean"},
    parent: {type: "object"}
  },
  popup: {
    name: {type: "string"},  // 名前変更
    top: {type: "number"},
    left: {type: "number"},
    width: {type: "number"},
    height: {type: "number"},
    contenu: {type: "string"},
    title: {type: "string"},  // 名前変更
    suffFond: {type: "enum", elem: ["Gris", "Transparent"], def: "Transparent"},
    modeContainer: {type: "enum", elem: ["AutoScroll", "nonFen"]},  // AutoScrollを指定するとRialtoエラー
    bSansBtonClose: {type: "boolean"},
    oCiuLie: {type: "unknown"}  // TODO: 要チェック
  },
  form: {
    name: {type: "string"},  // 名前変更
    left: {type: "number"},
    top: {type: "number"},
    url: {type: "string"},
    parent: {type: "object"},
    imgBtonSubmit: {type: "object"},
    autoSubmit: {type: "boolean"},
    method: {type: "enum", elem: ["post", "get"], def: "post"},
    boolWithFenWait: {type: "boolean"},
    boolAsynch: {type: "boolean"},
    idCont: {type: "string"},
    canBeCancel: {type: "boolean"},
    boolIframe: {type: "boolean"},
    onSuccess: {type: "object"},
    callBackObjectOnSuccess: {type: "object"}
  },
  tabFolder: {
    autoResizeContenu: {type: "boolean"},
    autoResizeParent: {type: "boolean"},
    autoRedimTab: {type: "boolean"},
    isClosable: {type: "boolean"},
    draggableItem: {type: "boolean"},
    widthTabName: {type: "number"},
    parent: {type: "object"},
    noActiveTab: {type: "number", def: 1},  // taglibでの追加属性
    tabIndex: {type: "number", def: -1}
  },
  tabItem: {
    name: {type: "string"},
    title: {type: "string"}
  },
  splitter: {
    prop: {type: "integer"},
    orientation: {type: "enum", elem: ["v", "h"]},
    autoResizeContenu: {type: "boolean"},
    autoResizeParent: {type: "boolean"},
    autoResizableH: {type: "boolean"},
    autoResizableW: {type: "boolean"},
    style: {type: "enum", elem: ["normal", "3D"]},
    overflow: {type: "enum", elem: ["auto", "hidden"]},
    modeLim: {type: "enum", elem: ["%", "abs"]},
    limInf: {type: "number"},
    limSup: {type: "number"},
    reverseClose: {type: "boolean"},
    withImg: {type: "boolean"},
    tailleCurs: {type: "number"},
    parent: {type: "object"}
  },
  divSplit: {
    name: {type: "string"},
    backgroundColor: {type: "string", def: "white"}
  },
  image: {
    imageOut: {type: "string"},
    left: {type: "number"},
    top: {type: "number"},
    parent: {type: "object"},
    alternateText: {type: "string"},
    imageOn: {type: "string"},
    imageDisabled: {type: "string"},
    boolFloatRight: {type: "boolean"},
    boolFloatLeft: {type: "boolean"}
  },
  label: {
    name: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    parent: {type: "object"},
    text: {type: "string"},
    className: {type: "string"},
    position: {type: "enum", elem: ["static", "relative", "absolute"]}
  },
  text: {
    name: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    width: {type: "number"},
    datatype: {type: "enum", elem: ["T", "P", "A", "N", "I", "D", "H", "Hi"]},
    parent: {type: "object"},
    position: {type: "enum", elem: ["static", "relative", "absolute"]},
    nbchar: {type: "number"},
    autoUp: {type: "boolean"},
    disable: {type: "boolean"},
    isRequired: {type: "boolean"},
    rows: {type: "number"},
    initValue: {type: "string"},
    accessKey: {type: "string"},
    tabIndex: {type: "number"}
  },
  button: {
    name: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    title: {type: "string"},
    alt: {type: "string"},
    parent: {type: "object"},
    enable: {type: "boolean"},
    tabIndex: {type: "number", def: -1}
  },
  combo: {
    tabData: {type: "object", def: '[]'},
    name: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    width: {type: "number"},
    parent: {type: "object"},
    position: {type: "enum", elem: ["static", "relative", "absolute"]},
    suggest: {type: "boolean"},
    enable: {type: "boolean"},
    heightItem: {type: "number"},
    tabIndex: {type: "number", def: -1}
  },
  comboItem: {
    text: {type: "string"},
    value: {type: "string"}
  },
  codeLib: {
    name: {type: "string"},  // 名前変更
    top: {type: "number"},
    left: {type: "number"},
    width: {type: "number"},
    parent: {type: "object"},
    arrValue: {type: "object"},
    boolWithLabel: {type: "boolean", alias: "withLabel"},
    url: {type: "string"},
    submitOnload: {type: "boolean"},
    alwaysRefresh: {type: "boolean"},
    codeWidth: {type: "number"},
    tabIndex: {type: "number", def: -1}
  },
  radioGroup: {
    name: {type: "string"},
    tabIndex: {type: "number", def: -1}
  },
  radioMember: {
    ref: {type: "string"}
  },
  radio: {
    name: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    parent: {type: "object"},
    group: {type: "string"}, // レイアウト定義XML的には使用してはいけないが、処理上許可
    text: {type: "string"},
    checked: {type: "boolean"},
    className: {type: "string"}
  },
  checkbox: {
    name: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    parent: {type: "object"},
    text: {type: "string"},
    checked: {type: "boolean"},
    className: {type: "string"},
    tabIndex: {type: "number", def: -1}
  },
  alert: {
    name: {type: "string"},
    mess: {type: "string"}
  },
  divHtml: {
  	name: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    parent: {type: "object"},
    className: {type: "string"},
    position: {type: "enum", elem: ["static", "relative", "absolute"]}
  },
  treeview: {
    boolSelActive: {type: "boolean"},
    withT: {type: "boolean"},
    rootOpen: {type: "boolean"},
    withRoot: {type: "boolean"},
    autoResizableH: {type: "boolean"},
    autoResizableW: {type: "boolean"},
    draggableNode: {type: "boolean"},
    rootNode: {type: "object"},
    parent: {type: "object"},
    tabIndex: {type: "number"}
  },
  treeNode: {
    typeInfo: {type: "string"},
    sText: {type: "string", alias:"text"},
    sIcon: {type: "string", alias:"icon"},
    sIcon2: {type: "string", alias:"icon2"},
    onclick: {type: "string"},
    open: {type: "boolean"},
    reload: {type: "boolean"},
    url: {type: "string"}
  },
  grid: {
    TabEntete: {type: "object"},
    bNavig: {type: "boolean"},
    cellActive: {type: "boolean"},
    sortable: {type: "boolean"},
    multiSelect: {type: "boolean"},
    lineHeight: {type: "number"},
    rang: {type: "number"},
    widthLastCell: {type: "number"},
    actifClic: {type: "boolean"},
    boolPrint: {type: "boolean"},
    switchable: {type: "boolean"},
    printTitle: {type: "string"},
    autoResizeContenu: {type: "boolean"},
    autoResizeParent: {type: "boolean"},
    writable: {type: "boolean"},
    tabTypeCol: {type: "object"},
    parent: {type: "object"},
    tabIndex: {type: "number", def: -1}
  },
  gridHeader: {
    width: {type: "number"},
    title: {type: "string"},
    type: {type: "enum", elem: ["number", "date", "string"]}
  },
/*  gridCellCombo: {
    value: {type: "string"},
    text: {type: "string"}
  },*/
  gridLine: {
  },
  gridCell: {
    value: {type: "string"}
  },
  javaScript: {
  },
  javaScriptGlobal: {
  },
  desc: {
  }
}

maskat.syntax.init = function(){
  // AbstractComponentの属性を継承するコンポーネントの属性初期化
  for(var attr in maskat.syntax.AbstractComponent){
    maskat.syntax.window[attr] = maskat.syntax.AbstractComponent[attr];
    maskat.syntax.frame[attr] = maskat.syntax.AbstractComponent[attr];
    maskat.syntax.tabFolder[attr] = maskat.syntax.AbstractComponent[attr];
    maskat.syntax.splitter[attr] = maskat.syntax.AbstractComponent[attr];
    maskat.syntax.image[attr] = maskat.syntax.AbstractComponent[attr];
    maskat.syntax.treeview[attr] = maskat.syntax.AbstractComponent[attr];
    maskat.syntax.treeNode[attr] = maskat.syntax.AbstractComponent[attr];
    maskat.syntax.grid[attr] = maskat.syntax.AbstractComponent[attr];
  }
  // 追加
  maskat.syntax.tabFolder.width.req = true;
  maskat.syntax.tabFolder.height.req = true;
}
maskat.syntax.init();

maskat.syntax.validate = function(layoutDOM){
  maskat.syntax.validateElement(layoutDOM.documentElement);
}

maskat.syntax.validateElement = function(domElem){
  var i;

  // 要素名validation
  var nodeName = domElem.nodeName;
  if (maskat.syntax[nodeName] == undefined){
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "要素名'" + nodeName + "'は不正な要素名です。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.syntax.validateElement"});
  }
  else{
    // 属性validation
    if (domElem.attributes){
      for (i = 0; i < domElem.attributes.length; i++){
        var attributeName = domElem.attributes[i].name;
        if (maskat.syntax[nodeName][attributeName] == undefined){
          throw new MaskatError({name: "layoutXML Syntax Error",
                                 message: "要素名'" + nodeName + "'の属性の内、属性名'" + attributeName + "'は不正な属性名です。",
                                 fileName: "layoutXMLInterpreter.js",
                                 functionName: "maskat.syntax.validateElement"});
        }
      }
    }
  }

  // 子要素を再帰的にvalidation
  if (domElem.hasChildNodes()){
    for (i = 0; i < domElem.childNodes.length; i++){
      if (domElem.childNodes[i].nodeType == 1){  // ELEMENT_NODE
        maskat.syntax.validateElement(domElem.childNodes[i]);
      }
    }
  }
}

maskat.interpretLayoutXML = function(layoutDOM, refParentHTML){

  // レイアウト定義XMLのvalidation [通常利用時はコメントアウト]
  maskat.syntax.validate(layoutDOM);

  // 変換後のJavaScriptソース
  var output = "";

  // ルート要素から現在の要素までのパス上にある要素オブジェクトの配列
  var pathObjArray = new Array();

  var i;
  var j;
  
  // layout要素の出現回数
  var layoutNum = 0;

  // ルート要素直下の子要素を処理
  for (i = 0; i < layoutDOM.documentElement.childNodes.length; i++){
    var domElem = layoutDOM.documentElement.childNodes[i];
    if (domElem.nodeType != 1){  // ELEMENT_NODE以外は無視
      continue;
    }
    else if (domElem.nodeName == "layout"){
      if (layoutNum > 0){
        throw new MaskatError({name: "layoutXML Syntax Error",
                               message: "layout要素は、1つのレイアウト定義XMLファイルに1つしか存在できません。",
                               fileName: "layoutXMLInterpreter.js",
                               functionName: "maskat.interpretLayoutXML"});
      }
      else{
        layoutNum++;
        if (refParentHTML){
          domElem.setAttribute("refParentHTML", refParentHTML);
        }
        output += maskat.transLayoutTag(pathObjArray, domElem);
      }
    }
    else if (domElem.nodeName == "javaScriptGlobal"){
      // "<javaScriptGlobal><![CDATA[...]]></javaScriptGlobal>"の"..."の部分を取得する
      if (domElem.hasChildNodes()){
        for (j = 0; j < domElem.childNodes.length; j++){
          if (domElem.childNodes[j].nodeType == 4){  // CDATA_SECTION
            output += domElem.childNodes[j].nodeValue + "\n";
          }
        }
      }
    }
    else{
      throw new MaskatError({name: "layoutXML Syntax Error",
                             message: "ルート要素の子要素として、不正な要素'" + domElem.nodeName + "'があります。",
                             fileName: "layoutXMLInterpreter.js",
                             functionName: "maskat.interpretLayoutXML"});
    }
  }

  return output;
}


////////////////////////////////////////////////////////////
//
// layout
//
////////////////////////////////////////////////////////////

maskat.transLayoutTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);
  if (attr.name==null || attr.name==""){
        throw new MaskatError({name: "layoutXML Syntax Error",
                               message: "layout要素のname属性は必須属性です。",
                               fileName: "layoutXMLInterpreter.js",
                               functionName: "maskat.transLayoutTag"});
  }

  new maskat.Layout(attr.name);
  //// 前変換
  output += "function " + attr.name + "(){\n";
  output += "var layoutObj = maskat.layouts[\"" + attr.name + "\"];\n";

  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var layoutObj = new maskat.LayoutClass(attr.name, attr.refParentHTML);
    pathObjArray.push(layoutObj);

    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換
  output += "return layoutObj;\n}\n";

  return output;
}

maskat.LayoutClass = function(name, refParentHTML){
  this.name = name;
  this.refParentHTML = refParentHTML;
}
maskat.LayoutClass.prototype.isContainer = true;
maskat.LayoutClass.prototype.getRefObj = function(){ return this.refParentHTML; }


////////////////////////////////////////////////////////////
//
// window
//
////////////////////////////////////////////////////////////

maskat.transWindowTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }
  
  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.SimpleWindow(" + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var windowObj = new maskat.WindowClass(attr.name);
    pathObjArray.push(windowObj);
    
    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換

  return output;
}

maskat.WindowClass = function(name){
  this.name = name;
}
maskat.WindowClass.prototype.isContainer = true;
maskat.WindowClass.prototype.getRefObj = function(){ return this.name; }


////////////////////////////////////////////////////////////
//
// popup
//
////////////////////////////////////////////////////////////

maskat.transPopupTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.PopUp("
                      + maskat.composeSingleParam(domElem, attr, "name") + ", "
                      + maskat.composeSingleParam(domElem, attr, "top") + ", "
                      + maskat.composeSingleParam(domElem, attr, "left") + ", "
                      + maskat.composeSingleParam(domElem, attr, "width") + ", "
                      + maskat.composeSingleParam(domElem, attr, "height") + ", "
                      + maskat.composeSingleParam(domElem, attr, "contenu") + ", "
                      + maskat.composeSingleParam(domElem, attr, "title") + ", "
                      + maskat.composeSingleParam(domElem, attr, "suffFond") + ", "
                      + strObjPar + ");\n";
                      //+ maskat.composeSingleParam(domElem, attr, "modeContainer") + ", "
                      //+ maskat.composeSingleParam(domElem, attr, "bSansBtonClose") + ", "
                      //+ maskat.composeSingleParam(domElem, attr, "oCiuLie") + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var popupObj = new maskat.PopupClass(attr.name);
    pathObjArray.push(popupObj);

    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換

  return output;
}

maskat.PopupClass = function(name){
  this.name = name;
}
maskat.PopupClass.prototype.isContainer = true;
maskat.PopupClass.prototype.getRefObj = function(){ return this.name; }

////////////////////////////////////////////////////////////
//
// frame
//
////////////////////////////////////////////////////////////

maskat.transFrameTag = function(pathObjArray, domElem){

  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.Frame(" + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
  
  // add keyNavi
  output += attr.name + ".cadre.tabIndex=-1;\n";
  
  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var frameObj = new maskat.FrameClass(attr.name);
    pathObjArray.push(frameObj);

    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }
  //// 後変換
  return output;
}

maskat.FrameClass = function(name){
  this.name = name;
}
maskat.FrameClass.prototype.isContainer = true;
maskat.FrameClass.prototype.getRefObj = function(){ return this.name; }


////////////////////////////////////////////////////////////
//
// form
//
////////////////////////////////////////////////////////////

maskat.transFormTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.Form("
                      + maskat.composeSingleParam(domElem, attr, "name") + ", "
                      + maskat.composeSingleParam(domElem, attr, "url") + ", "
                      + maskat.composeSingleParam(domElem, attr, "parent") + ", "
                      + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var formObj = new maskat.FormClass(attr.name);
    pathObjArray.push(formObj);

    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換

  return output;
}

maskat.FormClass = function(name){
  this.name = name;
}
maskat.FormClass.prototype.isContainer = true;
maskat.FormClass.prototype.getRefObj = function(){ return this.name; }

////////////////////////////////////////////////////////////
//
// tabFolder
//
////////////////////////////////////////////////////////////

maskat.transTabFolderTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  // 特別な内部変数
  var _tabFolderNbTabs = 0;

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.TabFolder(" + strObjPar +");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  // add keyNavi
  var num = maskat.composeSingleParam(domElem, attr, "tabIndex");
  if(num >= 0){
  	rialto.widget.Form.prototype.tabIndex = num;
  }
  output += attr.name + ".divContenuGlobal.tabIndex=-1;\n";
  output += attr.name + ".divExt.tabIndex=" + num + ";\n";
  output += attr.name + ".divExt.onfocus = function(e){" +
  		"focusObj=" + attr.name + ";};\n";
  
  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var tabFolderObj = new maskat.TabFolderClass(attr.name, _tabFolderNbTabs);
    pathObjArray.push(tabFolderObj);

    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);

  }

  //// 後変換
  
  _tabFolderNbTabs = tabFolderObj.nbTabs;
  
  if (attr.noActiveTab <= 0) {
    attr.noActiveTab = 1;
  }
  else if (attr.noActiveTab > _tabFolderNbTabs ){
    attr.noActiveTab = _tabFolderNbTabs ;
  }
  output += "layoutObj.components[\""+attr.name + "\"].activeTab((" + attr.noActiveTab + " - 1));\n";

  return output;
}

maskat.TabFolderClass = function(name, nbTabs){
  this.name = name;
  this.nbTabs = nbTabs;
}
maskat.TabFolderClass.prototype.isContainer = true;
maskat.TabFolderClass.prototype.getRefObj = function(){ return this.name; }
maskat.TabFolderClass.prototype.incrementNbTabs = function(){ this.nbTabs++; }


////////////////////////////////////////////////////////////
//
// tabItem
//
////////////////////////////////////////////////////////////

maskat.transTabItemTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、maskat.TabClassのインスタンスを取得する
  var tabFolderClassObj;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i] instanceof maskat.TabFolderClass){
      tabFolderClassObj = pathObjArray[i];
      break;
    }
  }
  if (tabFolderClassObj == undefined){
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "tabItem(name:'" + attr.name +"')の親要素としてtabFolder要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transTabItemTag"});
  }

  // maskat.TabClassインスタンスのgetRefObjメソッドの戻り値を取得する
  var refObjName = tabFolderClassObj.getRefObj();

  output += attr.name + " = layoutObj.components[\""+ refObjName + "\"].addTabItem("
                      + maskat.composeSingleParam(domElem, attr, "title") + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
  
  // maskat.TabClassインスタンスのタブの数をインクリメントする
  tabFolderClassObj.incrementNbTabs();

  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var tabItemObj = new maskat.TabItemClass(attr.name);
    pathObjArray.push(tabItemObj);
    
    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換

  return output;
}

maskat.TabItemClass = function(name){
  this.name = name;
}
maskat.TabItemClass.prototype.isContainer = true;
maskat.TabItemClass.prototype.getRefObj = function(){ return this.name; }


////////////////////////////////////////////////////////////
//
// splitter
//
////////////////////////////////////////////////////////////

maskat.transSplitterTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  if (attr["width"]!=null && attr["width"]!=""){
      attr["autoResizableW"]=false;
  }
  if (attr["height"]!=null && attr["height"]!=""){
      attr["autoResizableH"]=false;
  }
  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.Splitter(" + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var splitterObj = new maskat.SplitterClass(attr.name);
    pathObjArray.push(splitterObj);

    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);

  }

  //// 後変換

  return output;
}

maskat.SplitterClass = function(name){
  this.name = name;
  this.divSplitCount=0;//子ノードのdivSplitノード数
}
maskat.SplitterClass.prototype.isContainer = true;
maskat.SplitterClass.prototype.getRefObj = function(){ return this.name; }


////////////////////////////////////////////////////////////
//
// divSplit
//
////////////////////////////////////////////////////////////

maskat.transDivSplitTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  var thisRefObjName;

  // 親タグがmaskat.SplitterClassかどうか
  var pathObj = pathObjArray[pathObjArray.length - 1];
  if (pathObj instanceof maskat.SplitterClass){
    var parentRefObjName = pathObj.getRefObj();
    if (pathObj.divSplitCount>=2){
       throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "splitter(name:'" + parentRefObjName +"')要素のdivSplit子要素は二つしか定義できません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transDivSplitTag"});
    }
    pathObj.divSplitCount++;
    attr.name="div"+pathObj.divSplitCount;
    thisRefObjName = "layoutObj.components[\""+parentRefObjName + "\"]." + attr.name;

    if (attr.backgroundColor != ""){
      output += "layoutObj.components[\""+parentRefObjName + "\"]." + attr.name +".style.backgroundColor='"
             + attr.backgroundColor + "';\n";
    }
  }
  else{
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "divSplit(name:'" + attr.name +"')の親要素としてsplitter要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transDivSplitTag"});
  }

  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var divSplitObj = new maskat.DivSplitClass(attr.name, thisRefObjName);
    pathObjArray.push(divSplitObj);
    
    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換

  return output;
}

maskat.DivSplitClass = function(name, thisRefObjName){
  this.name = name;
  this.refObjName = thisRefObjName;
}
maskat.DivSplitClass.prototype.isContainer = true;
maskat.DivSplitClass.prototype.getRefObj = function(){ return this.refObjName; }


////////////////////////////////////////////////////////////
//
// image
//
////////////////////////////////////////////////////////////

maskat.transImageTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.Image("
                      + maskat.composeSingleParam(domElem, attr, "imageOut") + ", "
                      + maskat.composeSingleParam(domElem, attr, "left") + ", "
                      + maskat.composeSingleParam(domElem, attr, "top") + ", "
                      + maskat.composeSingleParam(domElem, attr, "parent") + ", "
                      + maskat.composeSingleParam(domElem, attr, "alternateText") + ", "
                      + maskat.composeSingleParam(domElem, attr, "imageOn") + ", "
                      + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  //// 子供の処理

  //// 後変換

  return output;
}

////////////////////////////////////////////////////////////
//
// label
//
////////////////////////////////////////////////////////////

maskat.transLabelTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.Label("
                      + maskat.composeSingleParam(domElem, attr, "name") + ", "
                      + maskat.composeSingleParam(domElem, attr, "top") + ", "
                      + maskat.composeSingleParam(domElem, attr, "left") + ", "
                      + maskat.composeSingleParam(domElem, attr, "parent") + ", "
                      + maskat.composeSingleParam(domElem, attr, "text") + ", "
                      + maskat.composeSingleParam(domElem, attr, "className") + ", "
                      + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]=" + attr.name + ";\n";
  
  //// 子供の処理

  //// 後変換

  return output;
}

////////////////////////////////////////////////////////////
//
// text
//
////////////////////////////////////////////////////////////

maskat.transTextTag = function(pathObjArray, domElem){

  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.Text("
                      + maskat.composeSingleParam(domElem, attr, "name") + ", "
                      + maskat.composeSingleParam(domElem, attr, "top") + ", "
                      + maskat.composeSingleParam(domElem, attr, "left") + ", "
                      + maskat.composeSingleParam(domElem, attr, "width") + ", "
                      + maskat.composeSingleParam(domElem, attr, "datatype") + ", "
                      + maskat.composeSingleParam(domElem, attr, "parent") + ", "
                      + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  // add keyNavi
  output += attr.name + ".onfocus = function(e){" +
		  "focusObj=" + attr.name + ";};\n";
  rialto.widget.Form.prototype.tabIndex++;

  //// 子供の処理

  //// 後変換

  return output;
}

////////////////////////////////////////////////////////////
//
// button
//
////////////////////////////////////////////////////////////

maskat.transButtonTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.Button("
                      + maskat.composeSingleParam(domElem, attr, "top") + ", "
                      + maskat.composeSingleParam(domElem, attr, "left") + ", "
                      + maskat.composeSingleParam(domElem, attr, "title") + ", "
                      + maskat.composeSingleParam(domElem, attr, "alt") + ", "
                      + maskat.composeSingleParam(domElem, attr, "parent") + ", "
                      + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  // add keyNavi
  var num = maskat.composeSingleParam(domElem, attr, "tabIndex");
  if(num >= 0){
  	rialto.widget.Form.prototype.tabIndex = num;
  }
  output += attr.name + ".divExt.tabIndex=" + num + ";\n";
  output += attr.name + ".divExt.onfocus = function(e){" +
  		"focusObj=" + attr.name + ";};\n";
  		
  //// 子供の処理

  //// 後変換

  return output;
}

////////////////////////////////////////////////////////////
//
// combo
//
////////////////////////////////////////////////////////////

maskat.transComboTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.Combo("
                      + maskat.composeSingleParam(domElem, attr, "tabData") + ", "
                      + maskat.composeSingleParam(domElem, attr, "name") + ", "
                      + maskat.composeSingleParam(domElem, attr, "top") + ", "
                      + maskat.composeSingleParam(domElem, attr, "left") + ", "
                      + maskat.composeSingleParam(domElem, attr, "width") + ", "
                      + maskat.composeSingleParam(domElem, attr, "parent") + ", "
                      + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  // add keyNavi
  var num = maskat.composeSingleParam(domElem, attr, "tabIndex");
  if(num >= 0){
  	rialto.widget.Form.prototype.tabIndex = num;
  }
  output += attr.name + ".text.champs.tabIndex=" + num + ";\n";
  output += attr.name + ".text.champs.onfocus = function(e){" +
  		"focusObj=" + attr.name + ";};\n";	
  		
  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var comboObj = new maskat.ComboClass(attr.name);
    pathObjArray.push(comboObj);
    
    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換

  return output;
}


maskat.ComboClass = function(name){
  this.name = name;
}
maskat.ComboClass.prototype.isContainer = false;

////////////////////////////////////////////////////////////
//
// comboItem
//
////////////////////////////////////////////////////////////

maskat.transComboItemTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、maskat.ComboClassのオブジェクト
  // のnameプロパティの値を取得する
  var comboName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i] instanceof maskat.ComboClass){
      comboName = pathObjArray[i].name;
      break;
    }
  }
  if (comboName == undefined){
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "comboItem(value:'" + attr.value +"')の親要素としてCombo要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transComboItemTag"});
  }

  output += comboName + ".addItem('" + attr.value + "', '" + attr.text + "');\n";

  //// 子供の処理

  //// 後変換

  return output;
}

////////////////////////////////////////////////////////////
//
// codeLib
//
////////////////////////////////////////////////////////////

maskat.transCodeLibTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.codeLabel("
                      + maskat.composeSingleParam(domElem, attr, "name") + ", "
                      + maskat.composeSingleParam(domElem, attr, "top") + ", "
                      + maskat.composeSingleParam(domElem, attr, "left") + ", "
                      + maskat.composeSingleParam(domElem, attr, "width") + ", "
                      + maskat.composeSingleParam(domElem, attr, "parent") + ", "
                      + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]=" + attr.name + ";\n";

  // add keyNavi
  var num = maskat.composeSingleParam(domElem, attr, "tabIndex");
  if(num >= 0){
  	rialto.widget.Form.prototype.tabIndex = num;
  }
  output += attr.name + ".divExt.tabIndex=-1;\n";
  output += attr.name + ".code.champs.tabIndex=" + num + ";\n";
  output += attr.name + ".code.champs.onfocus = function(e){" +
  		"focusObj=" + attr.name + ";};\n";
  output += attr.name + ".img.divExt.tabIndex=" + num + ";\n";
  output += attr.name + ".img.divExt.onfocus = function(e){" +
  		"focusObj=" + attr.name + ";};\n";  

  //// 子供の処理

  //// 後変換

  return output;
}


////////////////////////////////////////////////////////////
//
// radioGroup
//
////////////////////////////////////////////////////////////

maskat.transRadioGroupTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換
  output += attr.name + " = new maskat.RadioGroup('" + attr.name + "');\n";
  
  // add keyNavi
  var num = maskat.composeSingleParam(domElem, attr, "tabIndex");
  
  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var radioGroupObj = new maskat.RadioGroupClass(attr.name, num);
    pathObjArray.push(radioGroupObj);
    
    if (!maskat.radioGroupHash){
      maskat.radioGroupHash = new Object();
    }
    if(!maskat.radioGroupIndexHash){
    	maskat.radioGroupIndexHash = new Object();
    }
    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }
  
  //// 後変換
  return output;
}


maskat.RadioGroupClass = function(name, num){
  this.name = name;
  this.tabIndex=num;
}
maskat.RadioGroupClass.prototype.isContainer = false;


////////////////////////////////////////////////////////////
//
// radioMember
//
////////////////////////////////////////////////////////////

maskat.transRadioMemberTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、maskat.RadioGroupClassのオブジェクト
  // のnameプロパティの値を取得する
  var radioGroupName;
  var radioGroupIndex;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i] instanceof maskat.RadioGroupClass){
      radioGroupName = pathObjArray[i].name;
      radioGroupIndex = pathObjArray[i].tabIndex;
      break;
    }
  }
  if (radioGroupName == undefined){
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "radioMember(ref:'" + attr.ref +"')の親要素としてRadioGroup要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transRadioMemberTag"});
  }

  output += radioGroupName + ".addRadioMemberName('" + attr.ref + "');\n";
  
  maskat.radioGroupHash[attr.ref] = radioGroupName;
  maskat.radioGroupIndexHash[attr.ref] = radioGroupIndex;
  //// 子供の処理

  //// 後変換
  return output;
}


////////////////////////////////////////////////////////////
//
// radio
//
////////////////////////////////////////////////////////////

maskat.transRadioTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;
  
  var groupDefinedByRadioGroup = null;
  if (maskat.radioGroupHash){
    groupDefinedByRadioGroup = maskat.radioGroupHash[attr["name"]];
  }
  if (groupDefinedByRadioGroup==null){
      attr["group"]="";
  }else{
      attr["group"]=groupDefinedByRadioGroup;
  }
  
  output += attr.name + " = new rialto.widget.Radio("
                      + maskat.composeSingleParam(domElem, attr, "name") + ", "
                      + maskat.composeSingleParam(domElem, attr, "top") + ", "
                      + maskat.composeSingleParam(domElem, attr, "left") + ", "
                      + maskat.composeSingleParam(domElem, attr, "parent") + ", "
                      + maskat.composeSingleParam(domElem, attr, "group") + ", "
                      + maskat.composeSingleParam(domElem, attr, "text") + ", "
                      + maskat.composeSingleParam(domElem, attr, "checked") + ", "
                      + maskat.composeSingleParam(domElem, attr, "className") + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
  
  // add KeyNavi
  var num = -1;
  if(maskat.radioGroupIndexHash){
  	num = maskat.radioGroupIndexHash[attr["name"]];
  }
  if(num >= 0){
  	rialto.widget.Form.prototype.tabIndex = num;
  }
  output += attr.name + ".radio.tabIndex=" + num + ";\n";
//  output += attr.name + ".divExt.tabIndex=" + num + ";\n";
  output += attr.name + ".radio.onfocus = function(e){" +
  		"focusObj=" + attr.name + ";this.click();}\n";
  		
  if (groupDefinedByRadioGroup!=null)
      output += groupDefinedByRadioGroup + ".addRadioMember(" + attr["name"] + ");\n";

  //// 子供の処理

  //// 後変換
  return output;
}

////////////////////////////////////////////////////////////
//
// checkbox
//
////////////////////////////////////////////////////////////

maskat.transCheckboxTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  output += attr.name + " = new rialto.widget.Checkbox("
                      + maskat.composeSingleParam(domElem, attr, "name") + ", "
                      + maskat.composeSingleParam(domElem, attr, "top") + ", "
                      + maskat.composeSingleParam(domElem, attr, "left") + ", "
                      + maskat.composeSingleParam(domElem, attr, "parent") + ", "
                      + maskat.composeSingleParam(domElem, attr, "text") + ", "
                      + maskat.composeSingleParam(domElem, attr, "checked") + ", "
                      + maskat.composeSingleParam(domElem, attr, "className") + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  // add keyNavi
  var num = maskat.composeSingleParam(domElem, attr, "tabIndex");
  if(num >= 0){
  	rialto.widget.Form.prototype.tabIndex = num;
  }
  output += attr.name + ".checkbox.tabIndex=" + num + ";\n";
  output += attr.name + ".checkbox.onfocus = function(e){" +
  		"focusObj=" + attr.name + ";};\n";
  
  //// 子供の処理

  //// 後変換

  return output;
}

////////////////////////////////////////////////////////////
//
// alert
//
////////////////////////////////////////////////////////////

maskat.transAlertTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  output += attr.name + " = new rialto.widget.Alert("
                      + maskat.composeSingleParam(domElem, attr, "mess") + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  //// 子供の処理

  //// 後変換

  return output;
}

////////////////////////////////////////////////////////////
//
// divHtml
//
////////////////////////////////////////////////////////////

maskat.transDivHtmlTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  // "<rialto:divHtml><![CDATA[...]]></rialto:divHtml>"の"..."の部分を取得する
  var cdataValue = "";
  if (domElem.hasChildNodes()){
    for (var i = 0; i < domElem.childNodes.length; i++){
      if (domElem.childNodes[i].nodeType == 4){  // CDATA_SECTION
        cdataValue += domElem.childNodes[i].nodeValue;
      }
    }
  }
  if (cdataValue != ""){
    // cdataValueに改行が含まれると、3行下のinnerHTMLの文字列を作成した際に文字列が不正になるので、改行を取り除く
    cdataValue = maskat.removeNewLine(cdataValue);
  }
  
  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new maskat.widget.DivHtml("
                      + maskat.composeSingleParam(domElem, attr, "name") + ", "
                      + maskat.composeSingleParam(domElem, attr, "top") + ", "
                      + maskat.composeSingleParam(domElem, attr, "left") + ", "
                      + maskat.composeSingleParam(domElem, attr, "parent") + ", "
                      + "'" + cdataValue + "', "
                      + maskat.composeSingleParam(domElem, attr, "className") + ", "
                      + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
  
  //// 子供の処理

  //// 後変換

  return output;
  
}

////////////////////////////////////////////////////////////
//
// treeview
//
////////////////////////////////////////////////////////////

maskat.transTreeviewTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.Tree(" + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  // add keyNavi
  var num = maskat.composeSingleParam(domElem, attr, "tabIndex");
  if(num >= 0){
  	rialto.widget.Form.prototype.tabIndex = num;
  }
  tagIndexMap[attr.name]=num;
  output += attr.name + ".divExt.tabIndex=-1;\n";
  
  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var treeviewObj = new maskat.TreeviewClass(attr.name, num);
    pathObjArray.push(treeviewObj);
    
    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換

  return output;
}

maskat.TreeviewClass = function(name){
  this.name = name;
}
maskat.TreeviewClass.prototype.isContainer = true;
maskat.TreeviewClass.prototype.getRefObj = function(){ return this.name; }

////////////////////////////////////////////////////////////
//
// treeNode
//
////////////////////////////////////////////////////////////

maskat.transTreeNodeTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、maskat.TreeviewClassのオブジェクト
  // のnameプロパティの値を取得する
  var treeviewName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i] instanceof maskat.TreeviewClass){
      treeviewName = pathObjArray[i].name;
      break;
    }
  }
  
  if (treeviewName == undefined){
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "treeNode(name:'" + attr.name +"')の親要素としてtreeview要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transTreeNodeTag"});
  }
  
  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " =layoutObj.components[\""+ treeviewName + "\"].createAndAddNode("
         + refObjName + ".id, " + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  // add KeyNavi
  var num = tagIndexMap[treeviewName];
  output += attr.name + ".DIVENTETE.tabIndex=" + num + ";\n";
  output += attr.name + ".DIVENTETE.onfocus = function(e){" +
  		"focusObj=" + attr.name + ";};\n";
  
  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var treenodeObj = new maskat.TreeNodeClass(attr.name);
    pathObjArray.push(treenodeObj);

    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換

  return output;
}

maskat.TreeNodeClass = function(name){
  this.name = name;
}
maskat.TreeNodeClass.prototype.isContainer = true;
maskat.TreeNodeClass.prototype.getRefObj = function(){ return this.name; }


////////////////////////////////////////////////////////////
//
// grid
//
////////////////////////////////////////////////////////////

maskat.transGridTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  //// 子供の処理
  // 自タグのオブジェクトを作成
  var gridObj = new maskat.GridClass(attr.name);
  if (domElem.hasChildNodes()){
    pathObjArray.push(gridObj);
    
    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i].isContainer){
      refObjName = pathObjArray[i].getRefObj();
      break;
    }
  }

  attr["parent"] = refObjName;

  if (gridObj.strEntete == "" && attr.TabEntete == undefined){
    throw new MaskatError({name: "Grid Error",
                           message: "grid(grid名:'" + domElem.tagName + "')のヘッダ列(列名)が未定義です。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transGridTag"});
  }
  else{
    gridObj.strEntete = "[" + gridObj.strEntete.substring(0, gridObj.strEntete.length - 2) + "]";
  }

  if (gridObj.strTabTypeCol == "" && attr.tabTypeCol == undefined){
    throw new MaskatError({name: "Grid Error",
                           message: "grid(grid名:'" + domElem.tagName + "')のヘッダ列(列属性)が未定義です。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transGridTag"});
  }
  else{
    gridObj.strTabTypeCol = "[" + gridObj.strTabTypeCol.substring(0, gridObj.strTabTypeCol.length - 2) + "]";
  }

  if (attr.TabEntete == undefined){
    attr.TabEntete = gridObj.strEntete;
  }
  if (attr.tabTypeCol == undefined){
    attr.tabTypeCol = gridObj.strTabTypeCol;
  }

  var strObjPar = maskat.composeParam(domElem, attr);

  output += attr.name + " = new rialto.widget.Grid(" + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";

  // add keyNavi
  var num = maskat.composeSingleParam(domElem, attr, "tabIndex");
  if(num >= 0){
  	rialto.widget.Form.prototype.tabIndex = num;
  }
  tagIndexMap[attr.name] = num;
  output += attr.name + ".divExt.tabIndex=-1;\n";
  output += attr.name + ".tableauHTML.tabIndex=-1;\n";
  	
  if (gridObj.strLignes != ""){
    gridObj.strLignes = "[" + gridObj.strLignes.substring(0, gridObj.strLignes.length - 2) + "]";
    output += "layoutObj.components[\""+attr.name + "\"].fillGrid(" + gridObj.strLignes + ");\n";
  }

  return output;
}

maskat.GridClass = function(name){
  this.name = name;
  this.strEntete = "";
  this.strTabTypeCol = "";
  this.strLignes = "";
}
maskat.GridClass.prototype.isContainer = false;
maskat.GridClass.prototype.appendStrEntete = function(str){ this.strEntete += str; }
maskat.GridClass.prototype.appendStrTabTypeCol = function(str){ this.strTabTypeCol += str; }
maskat.GridClass.prototype.appendStrLignes = function(str){ this.strLignes += str; }

////////////////////////////////////////////////////////////
//
// gridHeader
//
////////////////////////////////////////////////////////////

maskat.transGridHeaderTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);
  
/*  //// 子供の処理
  // 自タグのオブジェクトを作成
  var gridHeaderObj = new maskat.GridHeaderClass();
  if (domElem.hasChildNodes()){
    pathObjArray.push(gridHeaderObj);
    
    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }*/

  //// 前変換

  // pathObjArrayの要素を降順に走査し、maskat.GridClassのオブジェクトを取得する
  var gridClassObj;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i] instanceof maskat.GridClass){
      gridClassObj = pathObjArray[i];
      break;
    }
  }
  if (gridClassObj == undefined){
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "gridHeader(title:'" + attr.title +"')の親要素としてgrid要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transGridHeaderTag"});
  }

  gridClassObj.appendStrEntete("'" + attr.title + "', ");
  //if (gridHeaderObj.cellCombo==""){
  gridClassObj.appendStrTabTypeCol("['" + attr.type + "', " + attr.width + "], ");
  //}else{
  //   gridClassObj.appendStrTabTypeCol("['" + attr.type + "', " + attr.width + ",[" +
  //           gridHeaderObj.cellCombo.substring(0,gridHeaderObj.cellCombo.length-2) + "]], ");
  //}

  //// 子供の処理

  //// 後変換

  return output;
}

/*maskat.GridHeaderClass = function(name){
  this.cellCombo = "";
}
maskat.GridHeaderClass.prototype.appendStrCellCombo = function(str){ this.cellCombo += str; }

maskat.transGridCellComboTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  // 属性の取得
  maskat.receiveAttributes(domElem, attr);
  
  // pathObjArrayの要素を降順に走査し、maskat.GridClassのオブジェクトを取得する
  var gridHeaderObj;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i] instanceof maskat.GridHeaderClass){
      gridHeaderObj = pathObjArray[i];
      break;
    }
  }
  if (gridHeaderObj == undefined){
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "gridCellCombo(value:'" + attr.value +"',text:'" + attr.text +"')の親要素としてgridHeader要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transGridCellComboTag"});
  }
  
  gridHeaderObj.appendStrCellCombo("['" + attr.value + "', '" + attr.text + "'], ");
  
  return output;
}*/

////////////////////////////////////////////////////////////
//
// gridLine
//
////////////////////////////////////////////////////////////

maskat.transGridLineTag = function(pathObjArray, domElem){
  var output = "";

  //// 属性の取得

  //// 前変換

  //// 子供の処理
  // 自タグのオブジェクトを作成
  var gridLineObj = new maskat.GridLineClass();
  if (domElem.hasChildNodes()){
    pathObjArray.push(gridLineObj);
    // 全ての子供の処理
    output += maskat.transChildNodes(pathObjArray, domElem);
  }

  //// 後変換

  // pathObjArrayの要素を降順に走査し、maskat.GridClassのオブジェクトを取得する
  var gridClassObj;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i] instanceof maskat.GridClass){
      gridClassObj = pathObjArray[i];
      break;
    }
  }
  if (gridClassObj == undefined){
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "gridLineの親要素としてgrid要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transGridLineTag"});
  }

  if (gridLineObj.strLigne != ""){
    gridLineObj.strLigne = gridLineObj.strLigne.substring(0, gridLineObj.strLigne.length - 2);
  }
  gridClassObj.appendStrLignes("[" + gridLineObj.strLigne + "], ");

  return output;
}


maskat.GridLineClass = function(){
  this.strLigne = "";
}
maskat.GridLineClass.prototype.isContainer = false;
maskat.GridLineClass.prototype.appendStrLigne = function(str){ this.strLigne += str; }


////////////////////////////////////////////////////////////
//
// gridCell
//
////////////////////////////////////////////////////////////

maskat.transGridCellTag = function(pathObjArray, domElem){
  var output = "";
  var attr = {};

  //// 属性の取得
  maskat.receiveAttributes(domElem, attr);

  //// 前変換

  // pathObjArrayの要素を降順に走査し、maskat.GridLineClassのオブジェクトを取得する
  var gridLineClassObj;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i] instanceof maskat.GridLineClass){
      gridLineClassObj = pathObjArray[i];
      break;
    }
  }
  if (gridLineClassObj == undefined){
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "gridCell(value:'" + attr.value + "')の親要素としてgridLine要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transGridCellTag"});
  }

  gridLineClassObj.appendStrLigne("'" + attr.value + "', ");

  //// 子供の処理

  //// 後変換

  return output;
}


////////////////////////////////////////////////////////////
//
// javaScript
//
////////////////////////////////////////////////////////////

maskat.transJavaScriptTag = function(pathObjArray, domElem){
  var output = "";

  //// 属性の取得

  //// 前変換

  // "<rialto:javaScript><![CDATA[...]]></rialto:javaScript>"の"..."の部分を取得する
  if (domElem.hasChildNodes()){
    for (var i = 0; i < domElem.childNodes.length; i++){
      if (domElem.childNodes[i].nodeType == 4){  // CDATA_SECTION
        output += domElem.childNodes[i].nodeValue + "\n";
      }
    }
  }

  //// 子供の処理

  //// 後変換

  return output;
}


////////////////////////////////////////////////////////////
//
// desc
//
////////////////////////////////////////////////////////////

maskat.transDescTag = function(pathObjArray, domElem){
  return "";
}


////////////////////////////////////////////////////////////
//
// 共通関数
//
////////////////////////////////////////////////////////////

maskat.receiveAttributes = function(domElem, attr){
  // ユーザ指定の属性値の設定
  for(var i = 0; i < domElem.attributes.length; i++){
    var attrName = domElem.attributes[i].nodeName;
    var attrValue = domElem.attributes[i].nodeValue;
    attr[attrName] = attrValue;
  }

  // デフォルト値があり、かつユーザが未設定の属性は、そのデフォルト値を設定
  var allAttr = maskat.syntax[domElem.nodeName];
  for(var allAttrItem in allAttr){
    if(allAttr[allAttrItem].def != undefined && attr[allAttrItem] == undefined){
      attr[allAttrItem] = allAttr[allAttrItem].def;
    }
  }
}

maskat.composeParam = function(domElem, attr){
  var strObjPar = "{";

  for(var attrItem in attr){
    var attrItemType = maskat.syntax[domElem.nodeName][attrItem].type;
    var alias = maskat.syntax[domElem.nodeName][attrItem].alias;
    var attributeName = attrItem;
    if (alias!=null)
       attributeName = alias;
    if (attrItemType == "string" || attrItemType == "enum"){
      strObjPar += attributeName + ":'" + attr[attrItem] + "', ";
    }
    else{
        if ((attr[attrItem]+"" !== ""))
//        if (attr[attrItem]!=null && attr[attrItem]!="")
          strObjPar += attributeName + ":" + attr[attrItem] + ", ";
    }
  }

  strObjPar = strObjPar.substring(0, strObjPar.length - 2);  //最後の", "を取り除く
  strObjPar += "}";
  
  return strObjPar;
}

maskat.composeSingleParam = function(domElem, attr, attrName){

  // 未定義の属性はnullに設定する
  if(attr[attrName] == undefined){
    return null;
  }
  var attrType = maskat.syntax[domElem.nodeName][attrName].type;
  if (attrType == "string" || attrType == "enum"){
    return "'" + attr[attrName] + "'";
  }
  else{
    if (attr[attrName]==""){
        return null; 
        // new rialto.widget.XXX('xx', 0, 00, parent, '', 'ラジオボックス',   , '');
        //　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　~~~を避けるために
    }
    return attr[attrName];
  }
}

maskat.transChildNodes = function(pathObjArray, domElem){
  var output = "";

  var processingLayoutChild = false;
  var layoutName = null;
  var parentObj = pathObjArray[pathObjArray.length-1];
  if (parentObj instanceof maskat.LayoutClass){
      processingLayoutChild = true;
      layoutName = parentObj.name;
  }
  // 各子供を順番に処理
  for (var i = 0; i < domElem.childNodes.length; i++){
    var domElemNext = domElem.childNodes[i];

    if(domElemNext.nodeType != 1){  // ELEMENT_NODE以外は無視
      continue;
    }

    var domElemNextNodeName = domElemNext.nodeName;

    var nextTransMethodName
      = "maskat.trans"
           + domElemNextNodeName.charAt(0).toUpperCase()
           + domElemNextNodeName.substring(1, domElemNextNodeName.length)
           + "Tag"

    /* maskat.interpretLayoutXML関数の最初でmaskat.syntax.validate関数を実行していれば以下のチェックは不要。
    if (eval(nextTransMethodName) == undefined){
      throw new MaskatError({name: "layoutXML Syntax Error",
                             message: "要素名'" + domElemNext.nodeName + "'は不正です。",
                             fileName: "layoutXMLInterpreter.js",
                             functionName: "maskat.transChildNodes"});
    }
    */

    // pathObjArrayの要素数を保存
    var pathObjArraylength = pathObjArray.length;

    output += eval(nextTransMethodName + "(pathObjArray, domElemNext)");
    
    if (processingLayoutChild==true){
        //レイアウトのレベル１子ノード
        var nameNode = domElemNext.getAttributeNode("name");
        if (nameNode!=null){
            var childName = nameNode.nodeValue;
            output += "maskat.layouts[\"" + layoutName + "\"].componentsLevel1[\""+childName+"\"] " + 
                  "= maskat.layouts[\"" + layoutName + "\"].components[\""+childName+"\"];\n";
        }
    }

    // pathObjArrayを、子供の処理をする前の状態に戻す
    while(pathObjArraylength < pathObjArray.length){
      pathObjArray.pop();
    }

  }
  
  return output;
}

maskat.removeNewLine = function(str){
  while (str.indexOf("\r") != -1){
    str = str.substring(0, str.indexOf("\r")) + str.substring(str.indexOf("\r") + 1, str.length);
  }
  while (str.indexOf("\n") != -1){
    str = str.substring(0, str.indexOf("\n")) + str.substring(str.indexOf("\n") + 1, str.length);
  }
  return str;
}

/**
 * JavaScriptオブジェクトとRialtoオブジェクトをWrapして統一のインターフェースを提供する。
 */

function ObjWrapper(object){
  this.obj = object;
}

ObjWrapper.prototype.isMultiSelect = function(){
  if (maskat.isRialtoObj(this.obj)){
    switch (this.obj.type){ // [RialtoAPI依存]
      case "grid":
        return this.obj.multiSelect; // [RialtoAPI依存]
      case "treeview":
        return false; // treeviewは現状、複数選択不可能
      default:
        break;
    }
  }
  throw new MaskatError({name: "Type Error",
                         message: "このオブジェクトに対してこの関数は実行できません。",
                         fileName: "objWrapper.js",
                         functionName: "ObjWrapper.prototype.isMultiSelect"});
}

ObjWrapper.prototype.isSingleDataObj = function(){
  if (maskat.isRialtoObj(this.obj)){
    // this.objはRialtoオブジェクト
    switch (this.obj.type){  // [RialtoAPI依存]
      case "label":
      case "text":
      case "combo":
      case "checkbox":
      case "radioGroup":
      case "codelib":
      case "divHtml":
        return true;
      default:
      	if(this.obj.isSingle){
      		return true;
      	}
        return false;
    }
  }
  else {
    // this.objはJavaScriptオブジェクト
    return !maskat.isArray(this.obj);
  }
}

ObjWrapper.prototype.isMultiDataObj = function(){
  if (maskat.isRialtoObj(this.obj)){
    // this.objはRialtoオブジェクト
    switch (this.obj.type){ // [RialtoAPI依存]
      case "grid":
      case "treeview":
        return true;
      default:
      	if(this.obj.isMulti){
      		return true;
      	}
        return false;
    }
  }
  else {
    // this.objはJavaScriptオブジェクト
    return maskat.isArray(this.obj);  // TODO: 2次元配列指定にする？
  }
}


ObjWrapper.prototype.getSingleValue = function(){
  if (!this.isSingleDataObj()){
    throw new MaskatError({name: "Type Error",
                           message: "複数データ型のオブジェクトに対してこの関数は実行できません。",
                           fileName: "objWrapper.js",
                           functionName: "ObjWrapper.prototype.getSingleValue"});
  }
  else {
    if (maskat.isRialtoObj(this.obj)){
      switch (this.obj.type){
        case "label":
          return this.obj.text;  // [RialtoAPI依存] getterAPIがないので直接textプロパティを参照
        case "text":
          return this.obj.getValue();  // [RialtoAPI依存] rialto.widget.Text.prototype.getValue
        case "combo":
          return this.obj.getSelValue();  // [RialtoAPI依存] rialto.widget.Combo.prototype.getSelValue
        case "checkbox":
          // boolean値ではなく文字列として返す
          return "" + this.obj.isCheck();  // [RialtoAPI依存] rialto.widget.Checkbox.prototype.getCheck, rialto.widget.Radio.prototype.getCheck
        case "radioGroup":
          return this.obj.getSelValue();
        case "codelib":
          return this.obj.getValue();
        default:
          if(this.obj.getSingleValue){
            return this.obj.getSingleValue();
          }
          break;
      }
    }
    else{
      // JavaScriptオブジェクト
      return this.obj;
    }
  }
}

ObjWrapper.prototype.setSingleValue = function(val){
  if (!this.isSingleDataObj()){
    throw new MaskatError({name: "Type Error",
                           message: "複数データ型のオブジェクトに対してこの関数は実行できません。",
                           fileName: "objWrapper.js",
                           functionName: "ObjWrapper.prototype.setSingleValue"});
  }
  else {
    if (maskat.isRialtoObj(this.obj)){
      switch (this.obj.type){  // [RialtoAPI依存]
        case "label":
          this.obj.setText(val);  // [RialtoAPI依存] rialto.widget.Label.prototype.setText
          break;
        case "text":
          this.obj.setValue(val);  // [RialtoAPI依存] rialto.widget.Text.prototype.setValue
          break;
        case "combo":
          this.obj.selWithValue(val);  // [RialtoAPI依存] rialto.widget.Combo.prototype.selWithValue
          break;
        case "checkbox":
          if (val == "true"){
            this.obj.setCheck(true);  // [RialtoAPI依存] rialto.widget.Checkbox.prototype.setCheck, rialto.widget.Radio.prototype.setCheck
          }
          else {
            this.obj.setCheck(false);  // [RialtoAPI依存] rialto.widget.Checkbox.prototype.setCheck, rialto.widget.Radio.prototype.setCheck
          }
          break;
        case "radioGroup":
          this.obj.setSelValue(val);
          break;
        case "divHtml":
          this.obj.setElement(val);
          break;
        default:
          if(this.obj.setSingleValue){
            this.obj.setSingleValue(val);
          }
          break;
      }
    }
    else{
      // TODO: JavaScriptオブジェクトへのsetValue
      throw new Error("非rialtoオブジェクトはsetValueできない。"+this.obj.base);
    }
  }
}

ObjWrapper.prototype.setMultiValue = function(val){
  if (!this.isMultiDataObj()){
    throw new MaskatError({name: "Type Error",
                           message: "単一データ型のオブジェクトに対してこの関数は実行できません。",
                           fileName: "objWrapper.js",
                           functionName: "ObjWrapper.prototype.setValue"});
  }
  else {
    if (maskat.isRialtoObj(this.obj)){
      switch (this.obj.type){  // [RialtoAPI依存]
        case "grid":
          this.setGridValue(val);
          break;
        case "treeview":
          this.setTreeValue(val);
          break;
        default:
          if(this.obj.setMultiValue){
            return this.obj.setMultiValue(val);
          }
          break;
      }
    }
    else{
      // TODO: JavaScriptオブジェクトへのsetValue
    }
  }
}


ObjWrapper.prototype.setTreeValue = function(val){
  try {
    // 現在のツリーの全てのノードを削除
    if (this.obj.rootNode != null){  // [RialtoAPI依存]
        this.obj.rootNode.remove();  // このAPIでいいのか要チェック
        this.obj.rootNode = null;
    }

    for (var i = 0; i < val.length; i++){
      var parentName;
      if (!val[i]["PARENT"]){
        // ルートノードの場合
        parentName = this.obj.name;
      }
      else {
        parentName = val[i]["PARENT"];
      }
      eval(val[i]["NAME"] + "= " + this.obj.name + ".createAndAddNode(" + parentName + ".id,{name:'" + val[i]["NAME"] + "',text:'" + maskat.escapeDoubleQuote(val[i]["TEXT"]) + "',icon:'images/imTreeview/pict_synthetik_off.gif',icon2:'',open:true,reload:false,onclick:''});" );  // [RialtoAPI依存]
      
      // add keyNavi
      var num = tagIndexMap[this.obj.name];
	  output = "";
	  output += val[i]["NAME"] + ".DIVENTETE.tabIndex=" + num + ";\n";
      output += val[i]["NAME"] + ".DIVENTETE.onfocus = function(e){" +
  		   "focusObj=" + val[i]["NAME"] + ";};\n";
      eval(output);
      
      for (var key in val[i]){
        if (key.charAt(0) == "_"){
          if(!(eval(val[i]["NAME"] + ".maskatHiddenField"))){
            eval(val[i]["NAME"] + ".maskatHiddenField = new Object();");
          }
          eval(val[i]["NAME"] + ".maskatHiddenField['" + key + "'] = '" + val[i][key] + "';");
        }
      }
      
    }
  }
  catch (e){
    throw e;
  }
}

ObjWrapper.prototype.setGridValue = function(val){
  try {
    if (val.length==0){
        this.obj.deleteLines();
        return;
    }
    var gridJSStr = "[";
    for (var i = 0; i < val.length; i++){
      gridJSStr += "[";
      for (var j in val[i]){
        var colIndex = parseInt(j);
        if (!isNaN(colIndex)) {// && colIndex < this.obj.NbreCol){  // [RialtoAPI依存] Gridオブジェクトの列数
          gridJSStr += '"' + maskat.escapeDoubleQuote(val[i][j]) + '",';  // TODO: itemValueから"を\"に変換
        }
      }
      gridJSStr = gridJSStr.substring(0, gridJSStr.length - 1);  // 最後の','を取り除く
      gridJSStr += "],";
    }
    gridJSStr = gridJSStr.substring(0, gridJSStr.length - 1);  // 最後の','を取り除く
    gridJSStr += "]";

    eval("this.obj.fillGrid(" + gridJSStr + ", 0, false)");
  }
  catch (e){
    throw e;
  }
}

ObjWrapper.prototype.getSelectedIndex = function(){
  if (maskat.isRialtoObj(this.obj)){
    switch (this.obj.type){ // [RialtoAPI依存]
      case "grid":
        return this.obj.indLineClic; // [RialtoAPI依存]
      case "treeview":
        if (this.obj.currentSelNode){
          return maskat.getTreeRowNumByName(this.obj, this.obj.currentSelNode.name);
        }
        else {
          return -1;
        }
      default:
        break;
    }
  }
  throw new MaskatError({name: "Type Error",
                         message: "このオブジェクトに対してこの関数は実行できません。",  // TODO: 詳細に
                         fileName: "objWrapper.js",
                         functionName: "ObjWrapper.prototype.getSelectedIndex"});
}


maskat.getTreeRowNumByName = function(treeview, name){
  if (!treeview.rootNode){
    return -1;
  }
  
  var treeNodeStack = new Array();
  treeNodeStack.push(treeview.rootNode);
  
  var rowNum = -1;
  
  while (treeNodeStack.length != 0){
    var treeNode = treeNodeStack.pop();
    rowNum++;
    if (treeNode.name == name){
      return rowNum;
    }
    else {
      if (treeNode.hasChild()){  // [RialtoAPI依存]
        for (var i = treeNode.arrChildNode.length - 1; i >= 0 ; i--){
          treeNodeStack.push(treeNode.arrChildNode[i]);
        }
      }
    }
  }
  
  // 最終的に見つからなかった場合(ありえない)
  return -1;
}


ObjWrapper.prototype.getSelectedIndexes = function(){
  if (maskat.isRialtoObj(this.obj)){
    switch (this.obj.type){ // [RialtoAPI依存]
      case "grid":
        var indexArray = new Array();
        for (var i = 0; i < this.obj.tabData.length; i++){ // [RialtoAPI依存]
          var lineData = this.obj.tabData[i]; // [RialtoAPI依存]
          if (lineData.sel == true){ // [RialtoAPI依存]
            indexArray.push(i);
          }
        }
        return indexArray;
      case "treeview":
        // TODO: 
      default:
        break;
    }
  }

  throw new MaskatError({name: "Type Error",
                         message: "このオブジェクトに対してこの関数は実行できません。",  // TODO: 詳細に
                         fileName: "objWrapper.js",
                         functionName: "ObjWrapper.prototype.getSelectedIndexes"});
}

ObjWrapper.prototype.getColNum = function(){
  if (maskat.isRialtoObj(this.obj)){
    switch (this.obj.type){ // [RialtoAPI依存]
      case "grid":
        return this.obj.NbreCol;  // [RialtoAPI依存]
      case "treeview":
        // TODO: 対象APIを探す。
      default:
        break;
    }
  }
  
  throw new MaskatError({name: "Type Error",
                         message: "このオブジェクトに対してこの関数は実行できません。",  // TODO: 詳細に
                         fileName: "objWrapper.js",
                         functionName: "ObjWrapper.prototype.getColLength"});
}

ObjWrapper.prototype.getRowNum = function(){
  if (maskat.isRialtoObj(this.obj)){
    switch (this.obj.type){ // [RialtoAPI依存]
      case "grid":
        if (this.obj.tabData){ // [RialtoAPI依存]
          return this.obj.tabData.length;  // [RialtoAPI依存]
        }
        else {
          return 0;
        }
      case "treeview":
        return maskat.countDescendantTreeNode(this.obj);
      default:
        break;
    }
  }
  else if (maskat.isArray(this.obj)){
    return this.obj.length;
  }
  
  throw new MaskatError({name: "Type Error",
                         message: "このオブジェクトに対してこの関数は実行できません。",  // TODO: 詳細に
                         fileName: "objWrapper.js",
                         functionName: "ObjWrapper.prototype.getRowNum"});
}


maskat.countDescendantTreeNode = function(treeview){
  if (!treeview.rootNode){  // [RialtoAPI依存]
    return 0;
  }

  var num = 0;
  var treeNodeArray = new Array();
  treeNodeArray.push(treeview.rootNode);  // [RialtoAPI依存]

  while (treeNodeArray.length != 0){
    treeNode = treeNodeArray.shift();
    num++;
    if (treeNode.hasChild()){
      for (var i = 0; i < treeNode.arrChildNode.length; i++){  // [RialtoAPI依存]
        treeNodeArray.push(treeNode.arrChildNode[i]);
      }
    }
  }
  return num;
}

ObjWrapper.prototype.getValueFromMultiData = function(row, col){
  if (maskat.isRialtoObj(this.obj)){
    switch (this.obj.type){ // [RialtoAPI依存]
      case "grid":
        return this.obj.tabData[row][col];  // [RialtoAPI依存]
      case "treeview":
        // row:行数, col:fromkey(ID/TEXT/PARENT)
        var treeNode = maskat.findTreeNodeByRowNum(this.obj, row);  // 同じ引数でfromkey分呼ばれるのでキャッシュすべき
        if (!treeNode){
          return null;
        }
        
        if (col.charAt(0) == "_"){
          if (!treeNode.maskatHiddenField){
            return "";
          }
          return treeNode.maskatHiddenField[col];
        }
        else{
          switch (col){
            case "NAME":
              return treeNode.name;
            case "TEXT":
              return treeNode.text;
            case "PARENT":
              if (treeNode.fatherNode){
                return treeNode.fatherNode.name;
              }
              else {
                return null;
              }
            default:
              throw new MaskatError({name: "EventXML Syntax Error",
                                     message: "Treeviewオブジェクトに対するfromkey'" + col + "'は未対応です。",
                                     fileName: "objWrapper.js",
                                     functionName: "ObjWrapper.prototype.getValueFromMultiData"});
          }
        }
      default:
        break;
    }
  }
  else if (maskat.isArray(this.obj)){  // TODO: 2次元配列チェックする？
    return this.obj[row][col];
  }
  else {
    throw new MaskatError({name: "Type Error",
                           message: "このオブジェクトに対してこの関数は実行できません。",  // TODO: 詳細に
                           fileName: "objWrapper.js",
                           functionName: "ObjWrapper.prototype.getValueFromMultiData"});
  }
}

maskat.findTreeNodeByRowNum = function(treeview, row){
  if (!treeview.rootNode || row == -1){
    return null;
  }
  
  var treeNodeStack = new Array();
  treeNodeStack.push(treeview.rootNode);

  var currentRow = -1;

  while (treeNodeStack.length != 0){
    var treeNode = treeNodeStack.pop();
    currentRow++;
    if (currentRow == row){
      return treeNode;
    }
    else {
      if (treeNode.hasChild()){  // [RialtoAPI依存]
        for (var i = treeNode.arrChildNode.length - 1; i >= 0 ; i--){
          treeNodeStack.push(treeNode.arrChildNode[i]);
        }
      }
    }
  }

  return null;

}




ObjWrapper.prototype.isJSObj = function(){
  return !maskat.isRialtoObj(this.obj);  // 将来Rialto以外のライブラリを利用する際は変更する
}

ObjWrapper.prototype.clear = function(){
  if (maskat.isRialtoObj(this.obj)){
    switch (this.obj.type){
      case "label":
        this.obj.setText("");  // [RialtoAPI依存] rialto.widget.Label.prototype.setText
        break;
      case "text":
        this.obj.setValue("");  // [RialtoAPI依存] rialto.widget.Text.prototype.setValue
        break;
      case "checkbox":
        this.obj.setCheck(false);  // [RialtoAPI依存] rialto.widget.Checkbox.prototype.setCheck, rialto.widget.Radio.prototype.setCheck
        break;
      case "radioGroup":
        this.obj.initRadio();
        break;
      case "grid":
        this.obj.initTab();
        break;
      case "treeview":
        if (this.obj.rootNode){  // [RialtoAPI依存]
          this.obj.rootNode.remove();  // このAPIでいいのか要チェック
          this.obj.rootNode = null;
        }
        break;
    }
  }
}

maskat.isRialtoObj = function(obj){
  return (obj && (typeof obj == "object") && (obj instanceof rialto.widget.AbstractComponent));
}

maskat.isArray = function(obj) {
  return (obj && (typeof obj == "object") && (obj.constructor == Array));
}

maskat.escapeDoubleQuote = function(str){
  return(str.split('"').join('\\"'));
}

//受信電文コンシューマー
//受信電文ノードからデータを取得して、オブジェクトに入れる
ObjWrapper.pluggableTeleConsumers={};

ObjWrapper.registerTeleConsumer = function(name,teleConsumer){
    ObjWrapper.pluggableTeleConsumers[name]=teleConsumer;
}

ObjWrapper.unregisterTeleConsumer = function(name){
    ObjWrapper.pluggableTeleConsumers[name]=null;
}

ObjWrapper.findTeleConsumer = function(teleType){
    return ObjWrapper.pluggableTeleConsumers[teleType];
}

//送信電文maker
//オブジェクトからデータを取得して、受信電文を組み立てる
ObjWrapper.pluggableTeleMakers={};

ObjWrapper.registerTeleMaker = function(name,maker){
    ObjWrapper.pluggableTeleMakers[name]=maker;
}

ObjWrapper.unregisterTeleMaker = function(name){
    ObjWrapper.pluggableTeleMakers[name]=null;
}

ObjWrapper.findTeleMaker = function(teleType){
    return ObjWrapper.pluggableTeleMakers[teleType];
}


//ワーカー、ローカルデータバインディング処理
ObjWrapper.pluggableLocalWorkers={};

ObjWrapper.registerLocalWorker = function(name,localWorker){
    ObjWrapper.pluggableLocalWorkers[name]=localWorker;
}

ObjWrapper.unregisterLocalWorker = function(name){
    ObjWrapper.pluggableLocalWorkers[name]=null;
}

ObjWrapper.findLocalWorker = function(workType){
    return ObjWrapper.pluggableLocalWorkers[workType];
}

maskat.soap={};

maskat.soap.wrapMessage = function(xmlMessage,paramNode){
    var prev = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2001/12/soap-envelope\">"+
        " <soap:Body>";
    return prev + xmlMessage + "</soap:Body></soap:Envelope>";
}

/**
 * 受信電文(soapの場合)から、soap bodyのDOMノードを取得
 * 
 * @param teleDOM 受信電文
 * @return bodyの中身ノード
 */
maskat.soap.unwrapDOM = function(teleDOM,resultNode){
    var children = teleDOM.childNodes;
    var hasBody = false;
    for (var i=0;i<children.length;i++){
        if (children[i].nodeName.indexOf("Body")!=-1){
            //SOAP仕様にしたがって、SOAPメッセージには、HeaderとBody二つ子要素しかないので、
            //nodeNameに「Body」があれば、Body要素であるはず。
            hasBody=true;
            if (children[i].childNodes.length==0){
                throw new MaskatError({name: "Received Tele Error",
                               message: "受信SOAPメッセージのBody要素には子要素がありません。",
                               fileName: "soap.js",
                               functionName: "maskat.soap.unwrapDOM"});
            }
            return children[i].childNodes[0];
        }
    }
    if (!hasBody){
        throw new MaskatError({name: "Received Tele Error",
                       message: "受信SOAPメッセージのBody要素はありません。",
                       fileName: "soap.js",
                       functionName: "maskat.soap.unwrapDOM"});
    }
}
 
 /**
 * デフォルトのエラー処理関数(alertで全部のエラーを表示)
 * maskat.validationErrorHandlerカスタマイズすることができます。
 */
maskat.validationErrorHandler=function(errors){
	for (var i=0;i<errors.length;i++){
		var error = errors[i];
		alert(error.vTarget.desc+ " " + error.message);
	}
}

maskat.getValidator = function(throwOnErrorPar){
    var validator = maskat.globalVar.validator;
    validator.throwOnError = throwOnErrorPar;
    validator.exValidators = new Object;
    validator.errors = new Array;
    return validator;
}

/**
 * validationエラー
 */
maskat.ValidationError = function(vTarget,message){
    this.vTarget = vTarget;
    this.message = message;
}
maskat.ValidationError.prototype = new Error;

/**
 * NullValidatorはvalidation操作何もしない
 * それを使えば、validationを無効にすることができます
 */
maskat.NullValidator=function(){
    this.throwOnError=false;
    this.errors = new Array;
};
maskat.NullValidator.prototype.acceptError = function(error){
    //何もしない
}
maskat.NullValidator.prototype.validate=function(objName,value,type,desc){
    //何もしない。
}
maskat.NullValidator.prototype.regValidator=function(value,type){
    //何もしない。
}

/**
 * デフォルトvalidationオブジェクト
 */
maskat.DefaultValidator=function(){
    this.throwOnError = true;
    //true:バリデーションエラーがあったら、すぐthrow new Error
    //false:バリデーションエラーがあったら、validatorに保存する
    this.exValidators = new Object;
    this.errors = new Array;
}

maskat.DefaultValidator.prototype.acceptError = function(error){
    this.errors.push(error);
}

/**
 * カスタマイズvalidatorを登録することができます。
 * 拡張validatorを登録する
 */
maskat.DefaultValidator.prototype.regValidator=function(typeName,validator){
    this.exValidators[typeName] = validator;
}

maskat.DefaultValidator.prototype.validate=function(objName,value,type,desc,min,max,regexp){
    var vTarget = new Object;//validation target
    vTarget.objName = objName;
    vTarget.value = value;
    vTarget.desc = desc;
    vTarget.minVal = parseInt(min);
    vTarget.maxVal = parseInt(max);
    vTarget.regexp = regexp;
    try{
        if (type=="byte"){
            this.validateByte(vTarget);
        }
        if (type=="short"){
            this.validateShort(vTarget);
        }
        if (type=="int"){
            this.validateInt(vTarget);
        }
        if (type=="long"){
            this.validateLong(vTarget);
        }
        if (type=="float"){
            this.validateFloat(vTarget);
        }
        if (type=="string"){
            this.validateString(vTarget);
        }
        if (type=="date"){
            this.validateDate(vTarget);
        }
        if (type=="time"){
            this.validateTime(vTarget);
        }
        //拡張validatorでバリデーション
        var exValidator = this.exValidators[type];
        if (exValidator)
            exValidator.validate(vTarget);
    }catch(e){
       if (e instanceof maskat.ValidationError){
           if (!this.throwOnError){
              this.acceptError(e);
              return;
           }
       }
       throw e;
    }

}

maskat.DefaultValidator.prototype.validateIntegralNumRange=function(vTarget,minVal,maxVal,minLength,maxLength){
    if (!this.isIntegralNum(vTarget.value)) {
        throw new maskat.ValidationError(vTarget,"数字チェックに失敗しました。");
    }else{
        if (!isNaN(minLength)){
            if (vTarget.value.length<minLength)
               throw new maskat.ValidationError(vTarget,"長さチェック失敗。最小桁数："+minLength);
        }
        if (!isNaN(maxLength)){
            if (vTarget.value.length>maxLength)
                throw new maskat.ValidationError(vTarget,"長さチェック失敗。最大桁数："+maxLength);
        }
        var iValue = parseInt(vTarget.value);
        if (isNaN(iValue) || !(iValue >= minVal && iValue <= maxVal)) {
            throw new maskat.ValidationError(vTarget,"データの範囲不正(" + 
                minVal + " ... " + maxVal + ")。");
        }
    }
}

maskat.DefaultValidator.prototype.validateByte=function(vTarget){
    this.validateIntegralNumRange(vTarget,-128,127,vTarget.minVal,vTarget.maxVal);
}

maskat.DefaultValidator.prototype.validateShort=function(vTarget){
    this.validateIntegralNumRange(vTarget,-32768,32767,vTarget.minVal,vTarget.maxVal);
}

maskat.DefaultValidator.prototype.validateInt=function(vTarget){
    this.validateIntegralNumRange(vTarget,-2147483648,2147483647,vTarget.minVal,vTarget.maxVal);
}

maskat.DefaultValidator.prototype.validateLong=function(vTarget){
    this.validateIntegralNumRange(vTarget,-9223372036854775808,9223372036854775807,vTarget.minVal,vTarget.maxVal);
    //注：javascriptの整数はdouble-precision、16位のprecisionだけ。
    //だから、longチェックは-9223372036854776000~9223372036854776000の範囲になってしまう
}

maskat.DefaultValidator.prototype.validateFloat=function(vTarget){
    //vTargetは正しい数字であろうかチェック....
    // remove '.' before checking digits
    var tempArray = vTarget.value.split('.');
    if (tempArray.length>2){
        throw new maskat.ValidationError(vTarget,"floatチェック失敗。");
    }
    //Strip off leading '0'
    var zeroIndex = 0;
    var joinedString= tempArray.join('');
    while (joinedString.charAt(zeroIndex) == '0') {
        zeroIndex++;
    }
    var noZeroString = joinedString.substring(zeroIndex,joinedString.length);

    if (!this.isIntegralNum(noZeroString)) {
        throw new maskat.ValidationError(vTarget,"floatチェック失敗。");
    }
    var iValue = parseFloat(vTarget.value);
    if (isNaN(iValue)) {
        throw new maskat.ValidationError(vTarget,"floatチェック失敗。");
    }
}

maskat.DefaultValidator.prototype.isIntegralNum = function(argvalue) {
    argvalue = argvalue.toString();
    var validChars = "0123456789";
    var startFrom = 0;
    if (argvalue.charAt(0) == "0") {
        return false;
    }
    if (argvalue.charAt(0) == "-") {
        startFrom = 1;
    }

    for (var n = startFrom; n < argvalue.length; n++) {
        if (validChars.indexOf(argvalue.substring(n, n+1)) == -1) return false;
    }
    return true;
}

maskat.DefaultValidator.prototype.validateTime=function(vTarget){
    var bValid = true;
    var timeRegexp = new RegExp("^(\\d{2})[:](\\d{2})[:](\\d{2})$");
    var matched = timeRegexp.exec(vTarget.value);
    if (matched!=null){
        if (!isValidTime(matched[1],matched[2],matched[3])){
            bValid=false;
        }
    } else {
        bValid=false;
    }
     if (!bValid)
        throw new maskat.ValidationError(vTarget,"time チェック失敗。hh:mm:ss");
}

maskat.DefaultValidator.prototype.validateString=function(vTarget){
    if (!vTarget.value instanceof String){
        alert("vTarget.valueはStringではありません。チェックできません。");
        return;
    }
    if (!isNaN(vTarget.minVal)){
        if (vTarget.value.length<vTarget.minVal)
           throw new maskat.ValidationError(vTarget,"長さチェック失敗。最小文字数："+vTarget.minVal);
    }
    if (!isNaN(vTarget.maxVal)){
        if (vTarget.value.length>vTarget.maxVal)
            throw new maskat.ValidationError(vTarget,"長さチェック失敗。最大文字数："+vTarget.maxVal);
    }
    
    var regexp = vTarget.regexp;
    if (regexp){
    	var regexpObj = new RegExp(regexp);
    	if (!vTarget.value.match(regexpObj)){
    		throw new maskat.ValidationError(vTarget,"入力フォーマット不正です。");
    	}
    }
//  throw new Error("定義不正：type=stringの場合、必ずmin或いはmaxを数字値で定義してください。");
}

maskat.DefaultValidator.prototype.validateDate=function(vTarget,datePattern) {
     var bValid = true;
     var MONTH = "MM";
     var DAY = "dd";
     var YEAR = "yyyy";
     var i = 0;
     var fields = new Array();

     if (datePattern == null)
         datePattern="yyyy-MM-dd";//デフォルトdatePattern

     var orderMonth = datePattern.indexOf(MONTH);
     var orderDay = datePattern.indexOf(DAY);
     var orderYear = datePattern.indexOf(YEAR);
     if ((orderDay < orderYear && orderDay > orderMonth)) {
         var iDelim1 = orderMonth + MONTH.length;
         var iDelim2 = orderDay + DAY.length;
         var delim1 = datePattern.substring(iDelim1, iDelim1 + 1);
         var delim2 = datePattern.substring(iDelim2, iDelim2 + 1);
         if (iDelim1 == orderDay && iDelim2 == orderYear) {
            dateRegexp = new RegExp("^(\\d{2})(\\d{2})(\\d{4})$");
         } else if (iDelim1 == orderDay) {
            dateRegexp = new RegExp("^(\\d{2})(\\d{2})[" + delim2 + "](\\d{4})$");
         } else if (iDelim2 == orderYear) {
            dateRegexp = new RegExp("^(\\d{2})[" + delim1 + "](\\d{2})(\\d{4})$");
         } else {
            dateRegexp = new RegExp("^(\\d{2})[" + delim1 + "](\\d{2})[" + delim2 + "](\\d{4})$");
         }
         var matched = dateRegexp.exec(vTarget.value);
         if(matched != null) {
            if (!isValidDate(matched[2], matched[1], matched[3])) {
               bValid =  false;
            }
         } else {
            bValid =  false;
         }
     } else if ((orderMonth < orderYear && orderMonth > orderDay)) {
         var iDelim1 = orderDay + DAY.length;
         var iDelim2 = orderMonth + MONTH.length;
         var delim1 = datePattern.substring(iDelim1, iDelim1 + 1);
         var delim2 = datePattern.substring(iDelim2, iDelim2 + 1);
         if (iDelim1 == orderMonth && iDelim2 == orderYear) {
             dateRegexp = new RegExp("^(\\d{2})(\\d{2})(\\d{4})$");
         } else if (iDelim1 == orderMonth) {
             dateRegexp = new RegExp("^(\\d{2})(\\d{2})[" + delim2 + "](\\d{4})$");
         } else if (iDelim2 == orderYear) {
             dateRegexp = new RegExp("^(\\d{2})[" + delim1 + "](\\d{2})(\\d{4})$");
         } else {
             dateRegexp = new RegExp("^(\\d{2})[" + delim1 + "](\\d{2})[" + delim2 + "](\\d{4})$");
         }
         var matched = dateRegexp.exec(vTarget.value);
         if(matched != null) {
             if (!isValidDate(matched[1], matched[2], matched[3])) {
                 bValid =  false;
              }
         } else {
             bValid =  false;
         }
     } else if ((orderMonth > orderYear && orderMonth < orderDay)) {
         var iDelim1 = orderYear + YEAR.length;
         var iDelim2 = orderMonth + MONTH.length;
         var delim1 = datePattern.substring(iDelim1, iDelim1 + 1);
         var delim2 = datePattern.substring(iDelim2, iDelim2 + 1);
         if (iDelim1 == orderMonth && iDelim2 == orderDay) {
             dateRegexp = new RegExp("^(\\d{4})(\\d{2})(\\d{2})$");
         } else if (iDelim1 == orderMonth) {
             dateRegexp = new RegExp("^(\\d{4})(\\d{2})[" + delim2 + "](\\d{2})$");
         } else if (iDelim2 == orderDay) {
             dateRegexp = new RegExp("^(\\d{4})[" + delim1 + "](\\d{2})(\\d{2})$");
         } else {
             dateRegexp = new RegExp("^(\\d{4})[" + delim1 + "](\\d{2})[" + delim2 + "](\\d{2})$");
         }
         var matched = dateRegexp.exec(vTarget.value);
         if(matched != null) {
             if (!isValidDate(matched[3], matched[2], matched[1])) {
                 bValid =  false;
             }
         } else {
              bValid =  false;
         }
     } 
     if (!bValid)
        throw new maskat.ValidationError(vTarget,"dateチェック失敗。"+datePattern);
}

function isValidDate(day, month, year) {
    if (month < 1 || month > 12) {
        return false;
    }
    if (day < 1 || day > 31) {
        return false;
    }
    if ((month == 4 || month == 6 || month == 9 || month == 11) &&
        (day == 31)) {
        return false;
    }
    if (month == 2) {
        var leap = (year % 4 == 0 &&
           (year % 100 != 0 || year % 400 == 0));
        if (day>29 || (day == 29 && !leap)) {
            return false;
        }
    }
    return true;
}

function isValidTime(hour,minute,second){
    if (hour < 0 || hour > 23)
        return false;
    if (minute < 0 || minute > 59)
        return false;
    if (second < 0 || second > 59)
        return false;
    return true;
}

maskat.globalVar.validator = new maskat.DefaultValidator();

/**
 * validation errorが検出されたら、onValidationErrorに
 */
//maskat.DefaultValidator.prototype.onValidationError=function(outputObj){
//    this.context.accept(outputObj);
//}

/**
 * 
 */
//maskat.ValidationContext=function(){
//    this.errors = new Array();
//}

//maskat.ValidationContext.prototype.accept=function(outputObj){
//    this.errors.push(outputObj);
//}

//maskat.ValidationContext.prototype.validationFeedback=function(){
//    for (var i=0;i<this.errors.length;i++){
//        alert(this.errors[i].objName+"のバリデーションに以下のようなエラー："+this.errors[i].message);
//    }
//}


maskat.widget={};

maskat.widget.DivHtml=function(name,top,left,parent,element,className,objPar){
	var objParam=new Object;
	objParam.name=name;
	objParam.type="divHtml";
	objParam.left=left;
	objParam.top=top;
	if(objPar!=null){objParam.position=objPar.position;}
	
	this.base=rialto.widget.AbstractComponent;
	this.base(objParam);
	objPar=null;
	objParam=null;
	this.element=element;
	if(className!=''&&className!=null){
		this.className=className;
	}
	else{
		this.className="libNormal";
	}
	var oThis=this;
	this.divExt.id=this.id+"_DivGen";
	this.divExt.style.position=this.position;
	this.divExt.style.left=this.left+"px";
	this.divExt.style.top=this.top+"px";
	this.divExt.className=this.className;
	this.divExt.innerHTML=this.element;
	this.divExt.style.whiteSpace="nowrap";
	if(parent){this.placeIn(parent);};
}
maskat.widget.DivHtml.prototype=new rialto.widget.AbstractComponent;
maskat.widget.DivHtml.prototype.setElement=function(element){
	this.element=element;
	this.divExt.innerHTML=this.element;
}

maskat.setForcus = function(e){
	if (!e) e=window.event;
	code = e.keyCode;
	if(focusObj){
		// ボタンの場合
		if(focusObj.type == "button"){
			if(code == 13 || code == 32){
				focusObj.divExt.onclick();
				return false;
			}
		// テキストの場合
		} else if(focusObj.type == "text"){
			// なし		
		// タブの場合
		} else if(focusObj.type == "tabFolder"){
			var currentActiveIndex = focusObj.indActiveTab;
			var maxIndex = focusObj.arrTabItem.length - 1;
			if(code == 39){
				if (currentActiveIndex < maxIndex){
	         		focusObj.activeTab(currentActiveIndex + 1);
	         		return false;
	        	}
			} else if(code == 37){
				if (currentActiveIndex > 0){
					focusObj.activeTab(currentActiveIndex - 1);
					return false;
				}			
			}
		// コードリブの場合
		} else if(focusObj.type == "codelib"){
			if(code == 13){
				focusObj.img.onclick();
			}
		// ラジオボタンの場合
		} else if(focusObj.type == "radio"){
			// なし
		// コンボボックスの場合
		} else if(focusObj.type == "combo"){
			// なし
		// ツリーノードの場合
		} else if(focusObj.type == "treenode"){
			if(code == 13 || code == 32){
				if(focusObj.hasChild()){
					focusObj.toggle();
					return false;
				} else {
					focusObj.click();
					return false;
				}
			} else if(code == 37){
				if(focusObj.hasChild() && focusObj.open){
					focusObj.toggle();
					return false;
				}
			} else if(code == 39){
				if(focusObj.hasChild() && !focusObj.open){
					focusObj.toggle();
					return false;
				}			
			} else if(code == 40){
				var next = null; 
				if(focusObj.hasChild() && focusObj.open){
					next = focusObj.first();
				} else {
					if(!focusObj.isLast()){
						next = focusObj.next();
					} else {
						var buff = focusObj.fatherNode;
						while(buff){
							if(!buff.isLast()){
								buff = buff.next();
								break;
							}
							buff = buff.fatherNode;
						}
						if(buff){
							next = buff;
						}
					}
				}
				if(next){
					next.DIVENTETE.focus();
					return false;
				}
			} else if(code == 38){
				var previous = null;
				if(focusObj.isFirst()){
					if(focusObj.fatherNode){
						previous = focusObj.fatherNode;
					}
				} else {
					var buff = focusObj.previous();
					while(buff.hasChild() && buff.open){
						buff = buff.last();
					}
					if(buff){
						previous = buff;
					}
				}
				if(previous){
					previous.DIVENTETE.focus();
					return false;
				}
			}
		// チェックボックスの場合
		} else if(focusObj.type == "checkbox"){
			if(code == 13){
				if(focusObj.checked){
					focusObj.setCheck(false, false);
					return false;
				} else {
					focusObj.setCheck(true, false);
					return false;
				}
			}
		// グリッドの場合
		} else if(focusObj.type == "grid"){
			if(code == 13 || code == 32){
				focusObj.afterOnClick(focusObj.getLineIndex(focusNode), focusObj.getCellIndex(focusNode));
				return false;
			} else {
				var next = null;
				if(focusObj.cellActive){
					var currentActiveLineIndex = focusObj.getLineIndex(focusNode);
					var currentActiveColIndex = focusObj.getCellIndex(focusNode);
					var maxLineIndex = focusObj.NbreLig - 1;
					var maxColIndex = focusObj.NbreCol - 1;
					if(code == 37){
						if(0 < currentActiveColIndex){
							next = focusObj.getHtmlCellFromIndex(currentActiveLineIndex, --currentActiveColIndex);
						}
					} else if(code == 39){
						if(maxColIndex > currentActiveColIndex){
							next = focusObj.getHtmlCellFromIndex(currentActiveLineIndex, ++currentActiveColIndex);
						}
					} else if(code == 40){
						if(maxLineIndex > currentActiveLineIndex){
							next = focusObj.getHtmlCellFromIndex(++currentActiveLineIndex, currentActiveColIndex);
						}
					} else if(code == 38){
						if(0 < currentActiveLineIndex){
							next = focusObj.getHtmlCellFromIndex(--currentActiveLineIndex, currentActiveColIndex);
						}
					}
				} else {
					var currentActiveIndex = focusObj.getLineIndex(focusNode);
					var maxIndex = focusObj.NbreLig - 1;
					if(code == 40){
						if(maxIndex > currentActiveIndex){
							next = focusObj.getHtmlLineFromIndex(++currentActiveIndex);
						}
					} else if(code == 38){
						if(0 < currentActiveIndex){
							next = focusObj.getHtmlLineFromIndex(--currentActiveIndex);
						}
					}
				}
				if(next){
					next.focus();
					return false;
				}
			}
		}
		
	}
}


rialto.widget.Grid.prototype.refreshGrid = function () {
    this.deleteLines(true);
    this.idInt = 0;
    this.mapArray = new Array;
    if (this.navigation) {
        this.majZoneNavigation();
    }
    var tabINNERHTML = new Array();
    for (var i = this.debInd; i < this.finInd; i++) {
        tabINNERHTML.push(this.addLineWithINNER(i));
    }
    this.tableauHTML.innerHTML = tabINNERHTML.join("");
    this.updateLineCell();
    
    var oThis = this;
    num = tagIndexMap[this.name];
    for (var i = this.debInd; i < this.finInd; i++){
    	if (this.cellActive) {
    		for (var j = 0;j < this.NbreCol; j++) {
    			var node = this.getHtmlCellFromIndex(i,j);
    			node.tabIndex = num;
    			node.onfocus = function(e){
    				focusObj = oThis;
    				focusNode = this;
    			}
    		}
    	} else {
    		var line = this.getHtmlLineFromIndex(i);
    		line.tabIndex = num;
    		line.onfocus = function(e){
    			focusObj = oThis;
    			focusNode = this;
    		}
    	}
    }

};