/*
 * 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.
 */

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"},  // 名前変更
    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での追加属性
  },
  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"}
  },
  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"}
  },
  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"},
    url: {type: "string"},
    submitOnload: {type: "boolean"},
    alwaysRefresh: {type: "boolean"},
    codeWidth: {type: "number"}
  },
  radioGroup: {
    name: {type: "string"}
  },
  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"}
  },
  alert: {
    name: {type: "string"},
    mess: {type: "string"}
  },
  divHtml: {
  },
  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"}
  },
  treeNode: {
    typeInfo: {type: "string"},
    sText: {type: "string"},
    sIcon: {type: "string"},
    sIcon2: {type: "string"},
    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"}
  },
  gridHeader: {
    width: {type: "number"},
    title: {type: "string"},
    type: {type: "enum", elem: ["number", "date", "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);

  //// 前変換
  output += attr.name + ".prototype.nbreInstance = 0;\nfunction " + attr.name
              + "(){\nthis.id = '" + attr.name + "_' + (" + attr.name
              + ".prototype.nbreInstance++);\nrialto.session.objects[this.id] = this;\nvar oThis = this;\n";

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

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

  //// 後変換
  output += "}\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";

  //// 子供の処理
  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);

  //// 前変換

  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") + ", "
                      + maskat.composeSingleParam(domElem, attr, "modeContainer") + ", "
                      + maskat.composeSingleParam(domElem, attr, "bSansBtonClose") + ", "
                      + maskat.composeSingleParam(domElem, attr, "oCiuLie") + ");\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";

  //// 子供の処理
  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";

  //// 子供の処理
  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";

  //// 子供の処理
  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 += 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 + " = " + refObjName + ".addTabItem("
                      + maskat.composeSingleParam(domElem, attr, "title") + ");\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";

  //// 子供の処理
  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;
}
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かどうか
  if (pathObjArray[pathObjArray.length - 1] instanceof maskat.SplitterClass){
    var parentRefObjName = pathObjArray[pathObjArray.length - 1].getRefObj();
    thisRefObjName = parentRefObjName + "." + attr.name;

    if (attr.backgroundColor != ""){
      output += 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";

  //// 子供の処理

  //// 後変換

  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";
  
  //// 子供の処理

  //// 後変換

  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";

  //// 子供の処理

  //// 後変換

  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";

  //// 子供の処理

  //// 後変換

  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";

  //// 子供の処理
  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";

  //// 子供の処理

  //// 後変換

  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";

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


maskat.RadioGroupClass = function(name){
  this.name = name;
}
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;
  for (var i = pathObjArray.length - 1; i >= 0; i--){
    if (pathObjArray[i] instanceof maskat.RadioGroupClass){
      radioGroupName = pathObjArray[i].name;
      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;

  //// 子供の処理

  //// 後変換
  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";
  
  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";

  //// 子供の処理

  //// 後変換

  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";

  //// 子供の処理

  //// 後変換

  return output;
}

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

maskat.transDivHtmlTag = function(pathObjArray, domElem){
  var output = "";
  var 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;
    }
  }

  // "<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);
    output += "var divHTML = document.createElement('div');\n";
    output += "divHTML.innerHTML = '" + cdataValue + "';\n";
    output += "if(" + refObjName + ".add){ " + refObjName + ".add(divHTML) }\n";
    output += "else{ " + refObjName + ".appendChild(divHTML) };\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";

  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var treeviewObj = new maskat.TreeviewClass(attr.name);
    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 + " ="+ treeviewName + ".createAndAddNode("
         + refObjName + ".id, " + strObjPar + ");\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";

  if (gridObj.strLignes != ""){
    gridObj.strLignes = "[" + gridObj.strLignes.substring(0, gridObj.strLignes.length - 2) + "]";
    output += 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);

  //// 前変換

  // 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 + "', ");
  gridClassObj.appendStrTabTypeCol("['" + attr.type + "', " + attr.width + "], ");

  //// 子供の処理

  //// 後変換

  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;
    if (attrItemType == "string" || attrItemType == "enum"){
      strObjPar += attrItem + ":'" + attr[attrItem] + "', ";
    }
    else{
      strObjPar += attrItem + ":" + 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{
    return attr[attrName];
  }
}

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

  // 各子供を順番に処理
  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)");

    // 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;
}

