/*
 * Copyright (c)  2006-2007 Maskat 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.getFWLog = function(){
	return maskat.frameworkLog;
}

/** マスカットフレームワーク通信ログ */
maskat.getCMULog = function(){
	return maskat.commuLog;
}

/** マスカットアプリケーションログ */
maskat.getAppLog = function(){
	return maskat.appLog;
}

/** log4javascriptは初期化できない場合、仮ログオブジェクト */
maskat.FakeLog = function(){
}
maskat.FakeLog.prototype.addAppender = function(){};
maskat.FakeLog.prototype.removeAppender = function(){};
maskat.FakeLog.prototype.removeAllAppenders = function(){};
maskat.FakeLog.prototype.getLevel = function(){};
maskat.FakeLog.prototype.setLevel = function(){};
maskat.FakeLog.prototype.log = function(){};
maskat.FakeLog.prototype.trace = function(){};
maskat.FakeLog.prototype.debug = function(){};
maskat.FakeLog.prototype.info = function(){};
maskat.FakeLog.prototype.warn = function(message,exception){
	if (exception != null) {
		alert(message+":"+exception);
 	} else {
		alert(message);
	}
};
maskat.FakeLog.prototype.error = maskat.FakeLog.prototype.warn;
maskat.FakeLog.prototype.fatal = maskat.FakeLog.prototype.warn;

maskat.initLog = function(){
    if (typeof log4javascript=="undefined"){
    	// alert("log4javascript初期化できません。ログ機能使えません。");
    	maskat.frameworkLog = new maskat.FakeLog();
    	maskat.commuLog = new maskat.FakeLog();
    	maskat.appLog = new maskat.FakeLog();
    	return;
    }
    // %dは時間   %cはlogger種類  %pはログレベル  %mは出力メッセージ
    // またはオブジェクト
	var layout = new log4javascript.PatternLayout("%d{HH:mm:ss,SSS} %-6c [%-5p] %m{2}");

	var popUpAppender = new log4javascript.PopUpAppender(true);
	//閉じる後でも、ログ出力があれば、もう一度ログウィンドウを開く
	popUpAppender.setReopenWhenClosed(true);
	//最大メッセージ数
	popUpAppender.setMaxMessages(100);
	popUpAppender.setLayout(layout);

	var criticalAppender = new log4javascript.PopUpAppender(true);
	criticalAppender.setReopenWhenClosed(true);
	//ログ出力があったら、ログウィンドウをフォーカスに当たる
	criticalAppender.setFocusPopUp(true);
	criticalAppender.setMaxMessages(100);
	//このログウィンドウでERROR以上のログしか出力しない
	criticalAppender.setThreshold(log4javascript.Level.ERROR);
	criticalAppender.setLayout(layout);

	maskat.frameworkLog = log4javascript.getLogger("一般");
	maskat.frameworkLog.addAppender(popUpAppender);
	maskat.frameworkLog.addAppender(criticalAppender);
	maskat.frameworkLog.setLevel(log4javascript.Level.TRACE);

	maskat.commuLog = log4javascript.getLogger("通信");
	maskat.commuLog.addAppender(popUpAppender);
	maskat.commuLog.addAppender(criticalAppender);
	maskat.commuLog.setLevel(log4javascript.Level.TRACE);

	var popAppenderForApp = new log4javascript.PopUpAppender(true);
	popAppenderForApp.setReopenWhenClosed(true);
	popAppenderForApp.setMaxMessages(10);
	popAppenderForApp.setLayout(layout);

	maskat.appLog = log4javascript.getLogger("アプリ");
	maskat.appLog.addAppender(popAppenderForApp);
	//INFO以下のレベルのログはこのアプリloggerに出力しない
	maskat.appLog.setLevel(log4javascript.Level.INFO);
	//例外のスタックトレース出力
	log4javascript.setShowStackTraces(true);
}

/**
 * フレームワーク例外処理共通関数
 */
maskat.handleFrameworkError = function(message,e){
    if (e instanceof MaskatError){
       maskat.getFWLog().error(message
           + "\nname: " + e.name + "\nmessage: " + e.message
           + "\nfileName: " + e.fileName + "\nfunctionName: " 
           + e.functionName);
    }
    else{
       maskat.getFWLog().error(message,e);
    }
}

maskat.initLog();

function BackgroundLoad(){
}

/* Initialization of background load */
BackgroundLoad.init = function(){

  /* initialize the internal variables */
  // key: layout name, value: parent dom object or temporary dom object
  BackgroundLoad.layoutHash = new Object();  
 // key: dom object's id, value: the name of the layout shown in the dom object
  BackgroundLoad.containerHash = new Object();  
  BackgroundLoad.divUniqueID = 0;
  BackgroundLoad.HIDE_ZONE = {top:3000, left:3000};

  /* create the progress bar */
  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";
}

/* show the progress bar */
BackgroundLoad.showProgressBar = function(){

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

  /* show it in the middle of the browser window */
  BackgroundLoad.progressBarWindow.style.top = 
    (document.body.clientHeight 
    - BackgroundLoad.progressBarWindow.offsetHeight) / 2;
  BackgroundLoad.progressBarWindow.style.left =
    (document.body.clientWidth 
    - BackgroundLoad.progressBarWindow.offsetWidth) / 2;

}

/* hide the progress bar */
BackgroundLoad.hideProgressBar = function(){

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

}

/* load layout in background */
/* parameter: {'fileName':<layout xml file name>, 
'refParentObjText':<親DIVタグのDOMのテキスト表現>} の配列 */
BackgroundLoad.loadLayout = function(args){

  // TODO: setTimeoutで引数に渡せなかった。後で直す
  BackgroundLoad.args = args;  
  BackgroundLoad.showProgressBar();
  
  BackgroundLoad.progressBarWindow.innerHTML = args.length 
  	+ "つのファイルの取得・コンパイル中";
  
  // Pause for 0.5 second for the progress bar to be shown
  setTimeout(BackgroundLoad.loadLayout2, 500);  
}

BackgroundLoad.loadLayout2 = function(){

	// TODO: setTimeoutで引数に渡せなかった。後で直す
  var args = BackgroundLoad.args;  
 	// TODO: setTimeoutで引数に渡せなかった。後で直す
  BackgroundLoad.args = null;  
  
  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 = "ロード中";
	// Pause for 0.5 second for the screen to be updated    
    setTimeout(BackgroundLoad.loadLayout3_2, 500);  
  }
}

BackgroundLoad.loadLayout3_2 = function(){
	//loadLayout(BackgroundLoad.layoutNameArray[BackgroundLoad.nextLayoutIndex]);
  maskat.layouts[BackgroundLoad.layoutNameArray[BackgroundLoad.nextLayoutIndex]].initiator();  

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


  BackgroundLoad.nextLayoutIndex++;
  // Pause for 0.5 second for the screen to be updated
  setTimeout(BackgroundLoad.loadLayout3_1, 500);  
}


/* Helper function of 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", arg.fileName, false);
    xmlhttp.send(null);
    if (xmlhttp.status == 200) {
      BackgroundLoad.loadLayout4(xmlhttp.responseText, arg.refParentObjText);
    } else {
      maskat.getFWLog().error("リソースの取得に失敗しました");
    }
  }
  else {
    maskat.getFWLog().error('非同期通信モジュールの取得に失敗しました。\n処理を停止します。');
    return;
  }
}

/* Helper function of BackgroundLoad.loadLayout */
BackgroundLoad.loadLayout4 = function(layoutXML, refParentObjText){
	// TODO: What if the layout has already been loaded

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

	// if refParentObj a "div" dom object
  if (refParentObj.tagName != null && refParentObj.tagName.toUpperCase() == "DIV"){

    /* create a "div" dom object which is located out of the screen, 
       and load layout into that dom object(the div is out of the screen so that the layout is "invisible") */

    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){
      maskat.handleFrameworkError("",e);
    }
    maskat.loadJSSrc(rialtoJSSrc);
    
    BackgroundLoad.layoutNameArray.push(layoutName);

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

  }
  // TODO: if refParentObj is a rialto container object
  

}

BackgroundLoad.unloadLayout = function(layoutName){
  if (BackgroundLoad.layoutHash[layoutName] != undefined){
    // TODO: remove all the components belong to the layout

    BackgroundLoad.hideLayout(layoutName);

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

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

BackgroundLoad.showLayout = function(layoutName){
  if (BackgroundLoad.layoutHash[layoutName] != undefined){
    var currentLayoutName = BackgroundLoad.containerHash[BackgroundLoad.layoutHash[layoutName].refParentObj.id];
    if (currentLayoutName != null){
      // hide the current layout
      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 {
    maskat.getFWLog().error(layoutName + "レイアウトはロードされていないので、表示できません。");
  }
}

BackgroundLoad.hideLayout = function(layoutName){
  if (BackgroundLoad.layoutHash[layoutName] != undefined){
    var currentLayoutName = BackgroundLoad.containerHash[BackgroundLoad.layoutHash[layoutName].refParentObj.id];
    /* Only when the name specified is the name of the layout currently displayed */
    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 {
    maskat.getFWLog().error(layoutName + "レイアウトはロードされていないので、非表示にできません。");
  }
}

BackgroundLoad.init();

/*
 * Cross Browser utility function class
 */

function CrossBrowser(){
}

// Set the internal variables indicating browser type
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 {
    maskat.getFWLog().fatal("お使いのブラウザは動作保障対象外です。本システムは正しく機能しません。");
  }
}

// transfer the parameter string into a xml dom object
CrossBrowser.XML2DOM = function(srcXML){
  var desDOM;

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

  return desDOM;
}

// The cross browser implementation of getElementsByTagName(IE: namespace is needed, Firefox: namespace is not needed)
CrossBrowser.getElementsByTagName = function(srcDOM, tagName){
  if (CrossBrowser.isIE){
    return(srcDOM.getElementsByTagName(srcDOM.documentElement.prefix + ":" + tagName));
  }
  else if (CrossBrowser.isFF){
    return(srcDOM.getElementsByTagName(tagName));
  }
}

// transfer a xml dom object into xml string
CrossBrowser.getInnerContents = function(srcElm){
  if (CrossBrowser.isIE){
    return(srcElm.xml);
  }
  else if (CrossBrowser.isFF){
    return((new XMLSerializer).serializeToString(srcElm));
  }
}

CrossBrowser.init();

 
//// Dynamically load JavaScript file ////

// "script" tag is given a unique id by using this variable
maskat.loadJSFile_i = 0;  

maskat.loadJSFile = function(fileName){
//  elementScript.parentNode.replaceChild(elementScript, elementScript);
  var elementScript = document.createElement("script");
  document.acsync = false;
  elementScript.id = "forDynamicJSFileLoad" + maskat.loadJSFile_i++;  
  elementScript.src = fileName;
  document.getElementsByTagName("head").item(0).appendChild(elementScript);
}

//// Dynamically load CSS file ////

// "script" tag is given a unique id by using this variable
maskat.loadCSSFile_i = 0;  

maskat.loadCSSFile = function(fileName){
  //  elementLink.parentNode.replaceChild(elementLink, elementLink);
  var elementLink = document.createElement("link");
  elementLink.id = "forDynamicCSSFileLoad" + maskat.loadCSSFile_i++;  
  elementLink.href = fileName;
  document.getElementsByTagName("head").item(0).appendChild(elementLink);
}

//// Dynamically load JavaScript source ////

// "script" tag is given a unique id by using this variable
maskat.loadJSSrc_i = 0; 

maskat.loadJSSrc = function(jsSrc){
eval(jsSrc);
/*  var elementScript = document.createElement("script");
  document.async = false;
  elementScript.id = "forDynamicJSSrcLoad" + maskat.loadJSSrc_i++;  
  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;

/**
 * manipulate the UI on a per-layout basis
 */
maskat.Layout = function(name){
    this.name = name;
    this.components=new Object;
    this.componentsLevel1=new Object;
    this.isLoaded = false;
    this.initiator = function(){};
    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){
        //load the layout
        this.initiator();
		//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];

    // update
	maskat.keyLoggerObj.removeZombies();   
}

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();
    }
}
/**
 * Notice: the parameter targetDiv should not be a dom object, but a string 
 * by which we could get a dom object. For example: "document.getElement('div')"
 */
maskat.loadLayoutFile = function(layoutDefFileName, targetDiv, bToShow) {
    try{
        var paramDiv;
        if (targetDiv.indexOf("document.getElementById") == 0){
            paramDiv = targetDiv;
        } else{
            var div = document.getElementById(targetDiv);
            if (div!=null){
                paramDiv = "document.getElementById('" + targetDiv + "')";
            }else{
                paramDiv = targetDiv;
            }
        }
        var layoutDOM = maskat.loadXMLFile(layoutDefFileName);
        //このファイルはすでにロードされたかチェック
        var isAlreadyLoaded = false;
        for (var key in maskat.layouts){
            if (maskat.layouts[key].fileName == layoutDefFileName){
                isAlreadyLoaded = true;
            }
        }
        //alert(layoutDefFileName + "  loaded:" + isAlreadyLoaded);
        if (!isAlreadyLoaded){
        	// javascript source after the transformation
            var rialtoJSSrc; 
            rialtoJSSrc = maskat.interpretLayoutXML(layoutDOM, paramDiv);
            maskat.loadJSSrc(rialtoJSSrc);

            var layoutElements = layoutDOM.getElementsByTagName("layout");
            for (var i = 0; i < layoutElements.length; i++){
              var layoutName = layoutElements[i].getAttribute("name");
              maskat.layouts[layoutName].fileName = layoutDefFileName;
            }
        }

        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){
        maskat.handleFrameworkError("レイアウトファイルロードにエラーが発生しました。",e);
    }
}

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

    maskat.loadLayoutEvents(eventDefDOM);
    maskat.loadComponentEvents(eventDefDOM);
  }
  catch (e){
    maskat.handleFrameworkError("イベント処理中エラーが発生しました。",e);
  }
}

maskat.loadLayoutEvents = function(eventDefDOM){
    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();
    }
}

maskat.loadComponentEvents = function(eventDefDOM){
    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: "maskat.js",
                                 functionName: "maskat.loadComponentEvents"});
        }
        componentObj[IDs.event] = maskat.autoGenEventFunc(eventNode, eventDefDOM, IDs, componentObj);

// update
        if ( maskat.xpath(eventNode, '@key') )
        {
        	if (maskat.keyLoggerObj.getHasRunInit() == false)
        	{      		 
			    maskat.keyLoggerObj.initKeyLogging();
        	}
        	
        	maskat.keyLoggerObj.connectEventKeyFunc(IDs, maskat.xpath(eventNode, '@key'), maskat.xpath(eventNode, '@keymod'));
        }

        maskat.getFWLog().trace("コンポーネント[" + componentID + "]の[" + eventID + "]はバインディングされました。");
      }
    }
}


maskat.localEventFunc = function(eventNode, eventDefDOM, IDs){
   try {
     maskat.getFWLog().trace("コンポーネント[" + IDs.component + "]の[" + IDs.event + "]イベントが発行される");
     //maskat.startFunc(eventNode, IDs);
     
     var validator = maskat.getValidator(false);

     // processing of <result> tag
     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, IDs);

     maskat.showEndDialog(eventNode);

     maskat.tryTransition(IDs.component, IDs.event);
   }
   catch (e){
     if (e instanceof MaskatProcessInterruption){
       // Do Nothing
     }else
         maskat.handleFrameworkError("イベント実行時にエラーが発生しました。",e);
   }
}

maskat.showEndDialog = function(eventNode){
    var endDialogN = maskat.xpath(eventNode,"@endDialog");
    var endDialog;
    try{
        endDialog = eval(endDialogN);
    }catch(e){
        return;
    }
    if (endDialog instanceof maskat.widget.EndDialog){
        endDialog.initialize();
    }
}

maskat.remoteEventFunc = function(eventNode, eventDefDOM, IDs, hostComponent){
   try {
     maskat.getFWLog().trace("コンポーネント[" + IDs.component + "]の[" + IDs.event + "]イベントが発行される");
     //maskat.startFunc(eventNode, IDs);
     
     var validator = maskat.getValidator(false);

     // create the XML to be sent
     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: "maskat.js",
                                    functionName: "maskat.remoteEventFunc"});
           }
         }

         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){
     // Output the log message here.
     // これより上にエラーをthrowできないので(呼び出し元はWebブラウザとなる)、ここでログを出力する
     if (e instanceof MaskatProcessInterruption){
       // Do Nothing
     }else
         maskat.handleFrameworkError("イベント実行時にエラーが発生しました。",e);
   }
}

//generate a processing function for the event node.
maskat.autoGenEventFunc = function(eventNode, eventDefDOM, IDs, hostComponent){
  try {
  
    // the processing of event tag
    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));
        }
        // ref属性を二度と利用できなくする
        // eventNode.removeAttribute("ref");  
      }
      else {
        throw new MaskatError({name: "EventXML Syntax Error",
                               message: "id値'" + eventRefID + "'を持つeventRef要素が見つかりません。",
                               fileName: "maskat.js",
                               functionName: "maskat.autoGenEventFunc"});
      }
    }

    var confirm = maskat.getConfirmWindow(eventNode);
    // processing of the <event type="local" ...> tag
    if (maskat.xpath(eventNode, '@type') == "local"){
      return function(){
      	 try{
            maskat.startFunc(eventNode, IDs);
            if (confirm != null){
                confirm.onOK = function() {try { confirm.runOkFunc();maskat.localEventFunc(eventNode, eventDefDOM, IDs); } catch(ex) {}};
                confirm.onCancel = function() {try { confirm.runCancelFunc()} catch(ex) {}};
                confirm.initialize();
            }else{
                maskat.localEventFunc(eventNode, eventDefDOM, IDs);
            }
         } catch(e){
         }
      }
    }
    // processing of <event type="remote" ...> tag
    else {
      return function(){
      	 try{
            maskat.startFunc(eventNode, IDs);
            if (confirm != null){
                confirm.onOK = function() {try { confirm.runOkFunc();maskat.remoteEventFunc(eventNode, eventDefDOM, IDs, hostComponent); } catch(ex) {}};
                confirm.onCancel = function() {try { confirm.runCancelFunc()} catch(ex) {}};
                confirm.initialize();
            }else{
                maskat.remoteEventFunc(eventNode, eventDefDOM, IDs, hostComponent);
            }
         } catch(e){
         }
      }
    }
  }
  catch (e){
    throw e;
  }
}

maskat.getConfirmWindow = function(eventNode){
  var confirm =  maskat.xpath(eventNode, '@confirmDialog');
  var result = null;
  try{
     result = eval(confirm);
  }catch(e){
     return null;
  }
  if (result instanceof maskat.widget.ConfirmDialog){
      return result;
  }
  return null;
}

maskat.parseLocalTarget = function(targetNode, validator){
  try {
    var inName = maskat.xpath(targetNode, '@in');
    var inObj = maskat.getObjByName(inName);
    var inObjWrap;
    if (eval("typeof " + inName) == "undefined") {
        throw new MaskatError({name: "inエラー",
                         message: "ローカルマッピングのinオブジェクト:["+inName+"]は定義されていませんでした。",
                         fileName: "maskat.js",
                         functionName: "maskat.parseLocalTarget"});
    }
    if (inObj!=null){
      inObjWrap = new ObjWrapper(inObj);
    }

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

    //find an appropriate "worker" by the workType attribute.
    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: "maskat.js",
                             functionName: "maskat.parseLocalTarget"});
        }
        worker.work(outObj,inObj,targetNode);
        return;
    }

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

    if (!inName && outObjWrap){
      // clear the out object's content
      outObjWrap.clear();
    }
    else if (outObjWrap && (maskat.isRialtoObj(outObj) || !outObjWrap.isSingleDataObj())){
      //if outObj is a javascript object, the setValue cannot function. So avoid this.
      var value;
      if (inObjWrap!=null)
          value = inObjWrap.getSingleValue();
      else
          value = "";
      if (value && value != ""){
        if (typeName && typeName != "" && validator != null){
          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: check in and out are all "single value object"(like string,number)
        maskat.getFWLog().trace("["+outName+"]に単一値["+value+"]をセットしました。");
        outObjWrap.setSingleValue(value);
      }
      else {
        if (typeName == "required"){
          var vTarget = new Object;
          vTarget.desc = descName;
          vTarget.objName = inName;
          validator.acceptError(new maskat.ValidationError(vTarget, "入力してください。"));
        }
        else {
          outObjWrap.setSingleValue(value);
          return;
        }
      }
    }
    else if (outName!=null && 
       ((outObjWrap==null) || (!maskat.isRialtoObj(outObj) && outObjWrap.isSingleDataObj() ))){
      //if outObj is a javascript object
      var value;
      if (inObjWrap!=null)
          value = inObjWrap.getSingleValue();
      else
          value = "";
      if (value && value != ""){
        if (typeName && typeName != "" && validator != null){
          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);
        }

        //surround the value with quotation("), in case that value is the name of a variable or const like "true", "window".
        var statement = "window." + outName + " = \"" + value + "\";";
        maskat.getFWLog().trace("ローカルマッピング："+statement);
        eval(statement);
      }
      else {
        if (typeName == "required"){
          var vTarget = new Object;
          vTarget.desc = descName;
          validator.acceptError(new maskat.ValidationError(vTarget, "入力してください。"));
        }
        else {
          var statement = "window." + outName + " = \"\";";
          maskat.getFWLog().trace("ローカルマッピング："+statement);
          eval(statement);
          return;
        }
      }
    }    
    else {
      throw new MaskatError({name: "Mapping Error",
                             message: "in'" + inName + "'からout'" + outName + "'へのマッピングに対応していません。",
                             fileName: "maskat.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: "maskat.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: "maskat.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');

      // If it is of an empty value, then send it only when sendBlankElementName == "true"
      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;
          vTarget.objName = objName;
          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){
        // the value of the specified column of the selected line is sent

        var selectedIndex = objObjWrap.getSelectedIndex();
        if (selectedIndex != -1){
        
          var targetObjWrap = objObjWrap;
			// TODO: 二重宣言
          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",
									// TODO:more detailed
                                     message: "idxRefは複数データ型オブジェクトを指定して下さい",  
                                     fileName: "maskat.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){
        // send the data of the selected line

//        if (objObjWrap.isMultiSelect()){
          var childNodeName = maskat.xpath(sourceNode, '@childNode');
/*          if (!childNodeName){
            throw new MaskatError({name: "EventXML Syntax Error",
                                   message: "複数行選択データの送信マッピングの際には、childNode属性の指定が必須です。",  // TODO:詳細に
                                   fileName: "maskat.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",
              						// TODO:詳細に
                                     message: "idxRefは複数データ型オブジェクトを指定して下さい",  
                                     fileName: "maskat.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 != ""){
              if (childNodeName!=null)
                 resultXMLRow = "<" + childNodeName + ">" + resultXMLRow + "</" + childNodeName + ">";
            }
            resultXML += resultXMLRow;
          }
          if (resultXML != "" && nodeName!=null && nodeName!=""){
            resultXML = "<" + nodeName + ">" + resultXML + "</" + nodeName + ">";
          }
          
          return resultXML;
/*        } else {
          //single selection
          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: "maskat.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 {
        // send all the datas of a plural data

        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 != ""){
              if (childNodeName!=null)
                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: "maskat.js",
                                 functionName: "maskat.intprRecvTele"});
        }
      }
      else {
        // process it with the defaule error handling method processErrorTele
        maskat.processErrorTele(teleDOM);
      }
      throw new MaskatProcessInterruption(
          {name: "intprRecvTele Function Interruption",
           message: "エラー電文処理関数実行後の処理停止",
           fileName: "maskat.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: "maskat.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);
          }
        }
      }
    }
  }
  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);
    }

    //if teleType is presented, then find the corresponding teleconsumer to parse the xml
    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: "maskat.js",
                             functionName: "maskat.parseRemoteTarget"});
        }
        pluggableTeleConsumer.consume(outObj,maskat.xpath(teleDOM, maskat.xpath(targetNode, '@in')));
        return;
    }

    // Check if the data from the received xml can be set into the target object.
    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: "maskat.js",
                             functionName: "maskat.parseRemoteTarget"});
    }

    // get the data from the received xml.
    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){
        // No data from the received xml.
        // 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] = "";
			}                
          }
        }
      }
    }

    //TODO 受信電文データのデバッグ出力
    /*
    // 受信電文データのデバッグ出力
    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("window."+ 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: "maskat.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);
        }
        else {
          throw new MaskatError({name: "File Error",
                               message: "サーバから取得したファイル'" + xmlFile + "'が正規のXML文書ではありません。\nファイル内のテキスト文字列: " + xhr.responseText,
                               fileName: "maskat.js",
                               functionName: "maskat.loadXMLFile"});
        }
      }
      else {
        throw new MaskatError({name: "XMLHttpRequest Error",
                               message: "サーバからファイル'" + xmlFile + "'を正常に取得できませんでした。\nXMLHttpRequest#readyState: " + xhr.readyState + "\nXMLHttpRequest#status: " + xhr.status,
                               fileName: "maskat.js",
                               functionName: "maskat.loadXMLFile"});
      }
    }
  }
  else{
    throw new MaskatError({name: "XMLHttpRequest Error",
                           message: "XMLHttpRequestオブジェクトが取得できませんでした。",
                           fileName: "maskat.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: "maskat.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: "maskat.js",
                               functionName: "maskat.asyncTele"});
      }
    }

    // async属性値の取得
    var async = maskat.xpath(eventNode, '@async');
    //デフォルトは非同期
    if (async==null || async == "true"){
      async = true;
    }
    else {
      async = false;
    }
    // async=true(同期通信)でも内部的には非同期通信を行う
    xhr.open("POST", remoteUrl, true);  
    maskat.getCMULog().trace("XmlHttpRequestのopenメソッドを呼び出されました。url:「" + remoteUrl + "」");

    // ヘッダ処理
    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: "maskat.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;
// 起動時はfalse
maskat.globalVar.syncConn = 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.getCMULog().trace("送信電文：[" + 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();
	  }
      if (e instanceof MaskatProcessInterruption){
          //Do Nothing
      }
      // これより上にエラーをthrowできないので(非同期通信時のmaskat.autoCallBackFuncの
      // 呼び出し元はWebブラウザとなる)、ここでログを出力
      else
          maskat.handleFrameworkError("maskat.sendQueueThread.prototype.sendCheck呼び出し時にエラーが発生しました。",e);
  }
}
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){
          maskat.getCMULog().trace("受信電文[" + sendObj.xhr.responseText + "]");
          // タイムアウト解除
          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: "maskat.js",
                                 functionName: "maskat.autoCallBackFunc"});
        }
      }
    }
    catch (e){
      if (sendObj!=null) {
         sendObj.commuEnd();
	  }		
      if (e instanceof MaskatProcessInterruption){
        // Do Nothing
      }
      // これより上にエラーをthrowできないので(非同期通信時のmaskat.autoCallBackFuncの
      // 呼び出し元はWebブラウザとなる)、ここでログを出力
      else
          maskat.handleFrameworkError("maskat.autoCallBackFunc呼び出し時(受信電文処理)にエラーが発生しました。",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, sendObj.IDs);

  maskat.showEndDialog(sendObj.eventNode);

  maskat.tryTransition(sendObj.IDs.component, sendObj.IDs.event);
}


maskat.startFunc = function(eventNode, IDs){
    var startFunc = maskat.xpath(eventNode, '@start');
    if (startFunc){
      var param = new Object();
      param.stopProcess = false;
      try{
        eval(startFunc + "(param);");
      }
      catch (e){
        maskat.getFWLog().error("["+IDs.component+"]の["+IDs.event+"]イベントのstart関数実行中、エラーが発生。");
        throw e;
      }
      if (param.stopProcess){
        throw new MaskatProcessInterruption(
          {name: "Start Function Interruption",
           message: "componentID'" + IDs.component + "',eventID'" + IDs.event + "'のstart関数内で処理停止",
           fileName: "maskat.js",
           functionName: "maskat.startFunc"});
      }
    }
}

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){
        maskat.getFWLog().error("["+IDs.component+"]の["+IDs.event+"]イベントのbefore関数実行中、エラーが発生。");
        throw e;
      }
      if (param.stopProcess){
        throw new MaskatProcessInterruption(
          {name: "Before Function Interruption",
           message: "componentID'" + IDs.component + "',eventID'" + IDs.event + "'のbefore関数内で処理停止",
           fileName: "maskat.js",
           functionName: "maskat.beforeFunc"});
      }
    }
}

maskat.afterFunc = function(sendObj){
    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){
        maskat.getFWLog().error("["+sendObj.IDs.component+"]の["+sendObj.IDs.event+"]イベントのafter関数実行中、エラーが発生。");
        throw e;
      }
      if (param.stopProcess){
        throw new MaskatProcessInterruption(
          {name: "After Function Interruption",
           message: "componentID'" + sendObj.IDs.component + "',eventID'" + sendObj.IDs.event + "'のafter関数内で処理停止",
           fileName: "maskat.js",
           functionName: "maskat.afterFunc"});
      }
    }
}

maskat.finishFunc = function(eventNode, IDs){
    var finishFunc = maskat.xpath(eventNode, '@finish');
    if (finishFunc){
      try{
        eval(finishFunc + "();");
      }
      catch(e){
        maskat.getFWLog().error("["+IDs.component+"]の["+IDs.event+"]イベントのfinish関数実行中、エラーが発生。");
        throw e;
      }
    }
}

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

maskat.xpath = function(dom, locationPath){
  var locationStep = locationPath.split("/");
  var i;
  var j;
  var k;
  // ELEMENT_NODE
  if (!dom || dom.nodeType != 1){
    throw new MaskatError({name: "Maskat XPath Syntax Error",
                           message: "引数domが不正です。引数domにはDOMの要素ノードを指定して下さい。",
                           fileName: "maskat.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: "Maskat XPath Syntax Error",
                                 message: "attribute軸はロケーションステップの最後、かつ単一Nodeに対してのみ利用可能です。\nエラーが発生したロケーションパス: " + locationPath,
                                 fileName: "maskat.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: "Maskat XPath Syntax Error",
                                 message: "text()ノードテストはロケーションステップの最後、かつ単一親Nodeに対してのみ利用可能です。\nエラーが発生したロケーションパス: " + locationPath,
                                 fileName: "maskat.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: "Maskat XPath Syntax Error",
                                   message: "text()ノードテストを指定したノードのXML形式が不正です。\nエラーが発生したロケーションパス: " + locationPath,
                                   fileName: "maskat.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: "Maskat XPath Syntax Error",
                                     message: "述語が不正です。\nエラーが発生したロケーションパス: " + locationPath,
                                     fileName: "maskat.js",
                                     functionName: "maskat.xpath"});
            }
          }
          
          if (i == locationStep.length - 1){
            isLastPredicate = true;
          }
          
        }
        else{
          nodeTest = locationStep[i];
        }
        // 述語[n]を処理するために利用
        var currentNodePos = 0;  

        for (k = 0; k < domArray[j].childNodes.length; k++){
          var childNode = domArray[j].childNodes[k];
           // ELEMENT_NODE
          if (childNode.nodeType != 1){ 
            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"},
    // AutoScrollを指定するとRialtoエラー
    modeContainer: {type: "enum", elem: ["AutoScroll", "nonFen"]},  
    bSansBtonClose: {type: "boolean"},
    // TODO: 要チェック
    oCiuLie: {type: "unknown"}  
  },
  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"},
    orientation: {type: "enum", elem: ["t", "b", "l", "r"]},
    widthTabName: {type: "number"},
    parent: {type: "object"},
    // taglibでの追加属性
    noActiveTab: {type: "number", def: 1},  
    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"},
    width: {type: "number"},
    widthMin:{type: "number"},
    adaptToText: {type: "boolean"},
    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},
    enable: {type: "boolean"}
  },
  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"},
    // レイアウト定義XML的には使用してはいけないが、処理上許可
    group: {type: "string"}, 
    text: {type: "string"},
    checked: {type: "boolean"},
    className: {type: "string"},
    enable: {type: "boolean"}
  },
  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},
    enable: {type: "boolean"}
  },
  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},
    sortCol: {type: "number"},
    sortType: {type: "string", elem: ["asc", "desc"]}
  },
  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: "maskat.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: "maskat.js",
                                 functionName: "maskat.syntax.validateElement"});
        }
      }
    }
  }

  // 子要素を再帰的にvalidation
  if (domElem.hasChildNodes()){
    for (i = 0; i < domElem.childNodes.length; i++){
    // ELEMENT_NODE
      if (domElem.childNodes[i].nodeType == 1){  
        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];
    // ELEMENT_NODE以外は無視
    if (domElem.nodeType != 1){  
      continue;
    }
    else if (domElem.nodeName == "layout"){
      if (layoutNum > 0){
        throw new MaskatError({name: "layoutXML Syntax Error",
                               message: "layout要素は、1つのレイアウト定義XMLファイルに1つしか存在できません。",
                               fileName: "maskat.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++){
		// CDATA_SECTION
          if (domElem.childNodes[j].nodeType == 4){  
            output += domElem.childNodes[j].nodeValue + "\n";
          }
        }
      }
    }
    else if (domElem.nodeName == "desc"){
      continue;
    }
    else{
      throw new MaskatError({name: "layoutXML Syntax Error",
                             message: "ルート要素の子要素として、不正な要素'" + domElem.nodeName + "'があります。",
                             fileName: "maskat.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: "maskat.js",
                               functionName: "maskat.transLayoutTag"});
  }
  new maskat.Layout(attr.name);
  //// 前変換
  output += "maskat.layouts[\"" + attr.name + "\"].initiator = function(){\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: "maskat.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;
  //子ノードのdivSplitノード数
  this.divSplitCount=0;
}
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: "maskat.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: "maskat.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: "maskat.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";
  if (attr["enable"]=="false"){
    output += attr.name + ".setEnable(false);";
  }
  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){" +
  		 attr.name + ".code.afterOnFocus(); 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: "maskat.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";
  if (attr["enable"]=="false"){
    output += attr.name + ".setEnable(false);";
  }
  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";
  if (attr["enable"]=="false"){
    output += attr.name + ".setEnable(false);";
  }
  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: "maskat.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名:'" + attr.name + "')のヘッダ列(列名)が未定義です。",
                           fileName: "maskat.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名:'" + attr.name + "')のヘッダ列(列属性)が未定義です。",
                           fileName: "maskat.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";
  }
  
  if (attr.sortCol!=null && (!rialto.lang.isNumber(attr.sortCol) || parseInt(attr.sortCol) < 0 || parseInt(attr.sortCol) > gridObj.colNum -1)){
    throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "grid(grid名:'" + attr.name + "')のsortColの値は不正です。",
                           fileName: "maskat.js",
                           functionName: "maskat.transGridTag"});
  }
  if ((attr.sortable=="true" || attr.sortable==null) && attr.sortCol != null){
      var boolOrder = attr.sortType == "desc" ? true:false;
      output += attr.name + ".triColonne(" + attr.sortCol + "," + boolOrder + ");\n";
      output += attr.name + ".refreshGrid();\n";
  }
  return output;
}

maskat.GridClass = function(name){
  this.name = name;
  this.strEntete = "";
  this.strTabTypeCol = "";
  this.strLignes = "";
  this.colNum = 0;
}
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: "maskat.js",
                           functionName: "maskat.transGridHeaderTag"});
  }

  gridClassObj.colNum++;
  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: "maskat.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: "maskat.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: "maskat.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.retrieveChildNodes = function(originalChildNodes){
  var result = new Array(originalChildNodes.length);
  var frontIdx = 0;
  var endIdx = originalChildNodes.length-1;
  for (var i=0;i<originalChildNodes.length;i++){
      if (originalChildNodes[i].nodeName == "frame" || originalChildNodes[i].nodeName == "tabFolder"
          || originalChildNodes[i].nodeName == "splitter"){
          result[endIdx--] = originalChildNodes[i];
      }else{
          result[frontIdx++] = originalChildNodes[i];
      }
  }
  return result;
}

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;
  }
  // 各子供を順番に処理
  var childsToBeProcessed = maskat.retrieveChildNodes(domElem.childNodes);
  for (var i = 0; i < childsToBeProcessed.length; i++){
    var domElemNext = childsToBeProcessed[i];
	// ELEMENT_NODE以外は無視
    if(domElemNext.nodeType != 1){  
      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: "maskat.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;
  if (typeof this.obj.type == "string"){
    tmp = this.obj.type.substring(0,5);
    if (tmp == "image") {
      this.obj.type = tmp;
    }
  }
}

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

ObjWrapper.prototype.isSingleDataObj = function(){
  if (maskat.isRialtoObj(this.obj)){
    // this.objはRialtoオブジェクト
    // [RialtoAPI依存]
    switch (this.obj.type){  
      case "image":
      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オブジェクト
    // [RialtoAPI依存]
    switch (this.obj.type){ 
      case "grid":
      case "treeview":
        return true;

// update      
      case "ChildMenuEntry":
      case "SubMenuEntry":
      
      case "maskat.widget.MenuItem":
      case "maskat.widget.MenuCheckboxItem":
      case "maskat.widget.Menu":
      	return true;
      	
      default:
      	if(this.obj.isMulti){
      		return true;
      	}
        return false;
    }
  }
  else {
    // this.objはJavaScriptオブジェクト
    // TODO: 2次元配列指定にする？
    return maskat.isArray(this.obj);  
  }
}


ObjWrapper.prototype.getSingleValue = function(){
  if (!this.isSingleDataObj()){
    throw new MaskatError({name: "Type Error",
                           message: "複数データ型のオブジェクトに対してこの関数は実行できません。",
                           fileName: "maskat.js",
                           functionName: "ObjWrapper.prototype.getSingleValue"});
  }
  else {
    if (maskat.isRialtoObj(this.obj)){
      switch (this.obj.type){
        case "label":
        // [RialtoAPI依存] getterAPIがないので直接textプロパティを参照
          return this.obj.text;  
        case "text":
          if (this.obj.datatype=="DT" || this.obj.datatype=="DA" || this.obj.datatype=="D")
             return this.obj.getDateTimeValue();
          else
             return this.obj.getValue();
        case "combo":
         // [RialtoAPI依存] rialto.widget.Combo.prototype.getSelValue
          return this.obj.getSelValue(); 
        case "checkbox":
          // boolean値ではなく文字列として返す
          // [RialtoAPI依存] rialto.widget.Checkbox.prototype.getCheck, rialto.widget.Radio.prototype.getCheck
          return "" + this.obj.isCheck();  
        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: "maskat.js",
                           functionName: "ObjWrapper.prototype.setSingleValue"});
  }
  else {
    if (maskat.isRialtoObj(this.obj)){
    // [RialtoAPI依存]
      switch (this.obj.type){  
        case "image":
		// [RialtoAPI依存] rialto.widget.Label.prototype.setImages
          this.obj.setImages(val);  
          break;
        case "label":
		// [RialtoAPI依存] rialto.widget.Label.prototype.setText
          this.obj.setText(val);  
          break;
        case "text":
        // [RialtoAPI依存] rialto.widget.Text.prototype.setValue
          this.obj.setValue(val);  
          break;
        case "combo":
        // [RialtoAPI依存] rialto.widget.Combo.prototype.selWithValue
          this.obj.selWithValue(val);  
          break;
        case "checkbox":
          if (val == "true"){
          // [RialtoAPI依存] rialto.widget.Checkbox.prototype.setCheck, rialto.widget.Radio.prototype.setCheck
            this.obj.setCheck(true);  
          }
          else {
           // [RialtoAPI依存] rialto.widget.Checkbox.prototype.setCheck, rialto.widget.Radio.prototype.setCheck
            this.obj.setCheck(false); 
          }
          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{
      throw new Error("非rialtoオブジェクトはsetValueできない。"+this.obj.base);
    }
  }
}

ObjWrapper.prototype.setMultiValue = function(val){
  if (!this.isMultiDataObj()){
    throw new MaskatError({name: "Type Error",
                           message: "単一データ型のオブジェクトに対してこの関数は実行できません。",
                           fileName: "maskat.js",
                           functionName: "ObjWrapper.prototype.setValue"});
  }
  else {
    if (maskat.isRialtoObj(this.obj)){
		// [RialtoAPI依存]
      switch (this.obj.type){  
        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 {
    // 現在のツリーの全てのノードを削除
    // [RialtoAPI依存]
    if (this.obj.rootNode != null){
	// このAPIでいいのか要チェック
        this.obj.rootNode.remove();  
        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"];
      }
      // [RialtoAPI依存]
      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:''});" );
      
      // 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 {
    var gridJSStr = "[";
    for (var i = 0; i < val.length; i++){
      gridJSStr += "[";
      for (var j in val[i]){
        var colIndex = parseInt(j);
        // && colIndex < this.obj.NbreCol){  // [RialtoAPI依存] Gridオブジェクトの列数
        if (!isNaN(colIndex)) {
        	// TODO: itemValueから"を\"に変換
          gridJSStr += '"' + maskat.escapeDoubleQuote(val[i][j]) + '",';
        }
      }
      // 最後の','を取り除く
      gridJSStr = gridJSStr.substring(0, gridJSStr.length - 1);  
      gridJSStr += "],";
    }
    if (gridJSStr.length>1) {
    	// 最後の','を取り除く
		gridJSStr = gridJSStr.substring(0, gridJSStr.length - 1);  
		gridJSStr += "]";
	}	
    if (this.obj.oldColCLic != null){
        eval("this.obj.fillGrid(" + gridJSStr + ", this.obj.oldColCLic.ind, this.obj.oldColCLic.boolOrder)");
    } else {
        eval("this.obj.fillGrid(" + gridJSStr + ")");
	}
  }
  catch (e){
    throw e;
  }
}

ObjWrapper.prototype.getSelectedIndex = function(){
  if (maskat.isRialtoObj(this.obj)){
    switch (this.obj.type){ 
		// [RialtoAPI依存]      
      case "grid":
		// [RialtoAPI依存]      
        return this.obj.indLineClic; 
      case "treeview":
        if (this.obj.currentSelNode){
          return maskat.getTreeRowNumByName(this.obj, this.obj.currentSelNode.name);
        }
        else {
          return -1;
        }

// update      
      case "ChildMenuEntry":
      case "SubMenuEntry":
      
      case "maskat.widget.MenuItem":
      case "maskat.widget.MenuCheckboxItem":      
      case "maskat.widget.Menu":
      	break;

      default:
        break;
    }
  }
  throw new MaskatError({name: "Type Error",
						// TODO: 詳細に
                         message: "このオブジェクトに対してこの関数は実行できません。",  
                         fileName: "maskat.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 {
		// [RialtoAPI依存]    
      if (treeNode.hasChild()){ 
        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)){
	// [RialtoAPI依存]  
    switch (this.obj.type){ 
      case "grid":
        var indexArray = new Array();
        // [RialtoAPI依存]
        for (var i = 0; i < this.obj.tabData.length; i++){ 
		// [RialtoAPI依存]
          var lineData = this.obj.tabData[i];
		// [RialtoAPI依存]           
          if (lineData.sel == true){ 
            indexArray.push(i);
          }
        }
        return indexArray;
      case "treeview":
        var indexArray = new Array();
        if (this.obj.currentSelNode){
          indexArray.push(maskat.getTreeRowNumByName(this.obj, this.obj.currentSelNode.name));
        }
        else {
          indexArray.push(-1);
        }
        return indexArray;
      default:
        break;
    }
  }

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

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

ObjWrapper.prototype.getRowNum = function(){
  if (maskat.isRialtoObj(this.obj)){
	// [RialtoAPI依存]
    switch (this.obj.type){ 
      case "grid":
      // [RialtoAPI依存]
        if (this.obj.tabData){ 
         // [RialtoAPI依存]
          return this.obj.tabData.length; 
        }
        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",
						// TODO: 詳細に
                         message: "このオブジェクトに対してこの関数は実行できません。", 
                         fileName: "maskat.js",
                         functionName: "ObjWrapper.prototype.getRowNum"});
}


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

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

  while (treeNodeArray.length != 0){
    treeNode = treeNodeArray.shift();
    num++;
    if (treeNode.hasChild()){
    // [RialtoAPI依存]
      for (var i = 0; i < treeNode.arrChildNode.length; i++){  
        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":
      // [RialtoAPI依存]
        return this.obj.tabData[row][col];  
      case "treeview":
        // row:行数, col:fromkey(ID/TEXT/PARENT)
        // 同じ引数でfromkey分呼ばれるのでキャッシュすべき
        var treeNode = maskat.findTreeNodeByRowNum(this.obj, row);  
        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: "maskat.js",
                                     functionName: "ObjWrapper.prototype.getValueFromMultiData"});
          }
        }
      default:
        break;
    }
  }
  // TODO: 2次元配列チェックする？
  else if (maskat.isArray(this.obj)){  
    return this.obj[row][col];
  }
  else {
    throw new MaskatError({name: "Type Error",
							// TODO: 詳細に
                           message: "このオブジェクトに対してこの関数は実行できません。",  
                           fileName: "maskat.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 {
	// [RialtoAPI依存]
      if (treeNode.hasChild()){  
        for (var i = treeNode.arrChildNode.length - 1; i >= 0 ; i--){
          treeNodeStack.push(treeNode.arrChildNode[i]);
        }
      }
    }
  }

  return null;

}




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

ObjWrapper.prototype.clear = function(){
if (maskat.isRialtoObj(this.obj)){
    switch (this.obj.type){
        case "image":
		// [RialtoAPI依存] rialto.widget.Label.prototype.setImages
          this.obj.setImages("");  
          break;
      case "label":
      // [RialtoAPI依存] rialto.widget.Label.prototype.setText
        this.obj.setText("");  
        break;
      case "text":
      // [RialtoAPI依存] rialto.widget.Text.prototype.setValue
        this.obj.setValue("");  
        break;
      case "checkbox":
      // [RialtoAPI依存] rialto.widget.Checkbox.prototype.setCheck, rialto.widget.Radio.prototype.setCheck
        this.obj.setCheck(false);
        break;
      case "radioGroup":
        this.obj.initRadio();
        break;
      case "grid":
        this.obj.fillGrid(new Array());
        break;
      case "treeview":
		// [RialtoAPI依存]
        if (this.obj.rootNode){  
		// このAPIでいいのか要チェック
          this.obj.rootNode.remove();  
          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: "maskat.js",
                               functionName: "maskat.soap.unwrapDOM"});
            }
            return children[i].childNodes[0];
        }
    }
    if (!hasBody){
        throw new MaskatError({name: "Received Tele Error",
                       message: "受信SOAPメッセージのBody要素はありません。",
                       fileName: "maskat.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){
	//validation target
    var vTarget = new Object;
    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);
        }
        if (type=="url"){
            this.validateUrl(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.validateUrl=function(vTarget){
    var bValid = true;
    var urlRegexp = new RegExp("^(http|https|ftp)(://)([A-Z]*|[0-9]*|[;/?:@&=+$,-_.!~*'()%]*)$", "i");
    var matched = urlRegexp.exec(vTarget.value);
    if (matched==null){
        bValid=false;
    }
	if (!bValid) {
        throw new maskat.ValidationError(vTarget,"URLを正しく入力してください。(http://...)");
	}
}

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
         datePattern="yyyy-MM-dd";
	}
     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 (typeof focusObj.isEnable == "function"){
	        if (focusObj.isEnable() == false){
	            return;
	        }
	    }
		// ボタンの場合
		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 (focusObj.text != null){
				return true;
			}
			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 () {
    var debInd = this.debInd;
    var finInd = this.finInd;
    var indLineClic = this.indLineClic;
    this.deleteLines();
    this.debInd = debInd;
    this.finInd = finInd;
    this.indLineClic = indLineClic;
    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;
    		}
    	}
    }

};


/**
 * テキストコンポーネントのデートタイム値取得関数
 * datatype="DA"の場合 YYYY-MM-DD   datatype="DT"の場合 YYYY-MM-DDThh:mm:ss(hh:mm:ssは現在時刻)
 */
rialto.widget.Text.prototype.getDateTimeValue = function(){
  var value = this.getValue();
  if (value.length!=11){
     return "";
  }
  if (this.datatype=="D"){
     return this.month() + "/" + this.day() + "/" + this.year();
  }
  if (this.datatype=="DA"){
     return this.year() + "-" + this.month() + "-" + this.day();
  }
  if (this.datatype=="DT"){
     var datePart =  this.year() + "-" + this.month() + "-" + this.day();
     var now = new Date();
     var hours = now.getHours();
     var strHours = hours<10? "0"+hours:""+hours;
     var minutes = now.getMinutes();
     var strMinutes = minutes<10? "0"+minutes:""+minutes;
     var seconds = now.getSeconds();
     var strSeconds = seconds<10? "0"+seconds:""+seconds;
     return datePart + "T" + strHours + ":" + strMinutes + ":" + strSeconds;
  }
  return "";
}
rialto.widget.Text.prototype.year = function(){
  var value = this.champs.value;
  if (value.length != 11){
    return "";
  }
  return value.substring(0,4);
}
rialto.widget.Text.prototype.month = function(){
  var value = this.champs.value;
  if (value.length != 11){
    return "";
  }
  return value.substring(5,7);
}
rialto.widget.Text.prototype.day = function(){
  var value = this.champs.value;
  if (value.length != 11){
    return "";
  }
  return value.substring(8,10);
}


/**
 * 画面遷移機構対応
 */
maskat.appInit = function(){
  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", "transition.xml", false);
    xhr.send(null);
    if (xhr.readyState == 4 && xhr.status == 200) {
      try{
          var transDOM = xhr.responseXML;

          maskat.parseTransition(transDOM);

          var initElement = transDOM.getElementsByTagName("init").item(0);
          for (var i = 0; i < initElement.childNodes.length; i++){
            if (initElement.childNodes.item(i).nodeType != 1){
              continue;
            }
            var commandElement = initElement.childNodes.item(i);

            switch(commandElement.nodeName){
              case "loadLayout":
                var xmlFile = commandElement.getAttribute("xmlFile");
                var target = commandElement.getAttribute("target");
                var show = commandElement.getAttribute("show");
                if (show == "true"){ show = true; }
                else {show = false;}
              
                var pos = xmlFile.lastIndexOf(".");
                maskat.loadLayoutFile(xmlFile, target, show);
                maskat.loadEventFile(xmlFile.substring(0, pos) + "_e.xml");
                break;

              default:
                break;
            }
          }
      }catch(e){
        alert("Error");
        throw(e);
      }

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

maskat.parseTransition = function(transDOM){
  maskat.globalVar.transition = new Array();
  var transitionElements = transDOM.getElementsByTagName("transition");
  for (var i = 0; i < transitionElements.length; i++){
    maskat.parseTransition2(transitionElements.item(i));
  }
}

maskat.parseTransition2 = function(transitionElement){
  var component = transitionElement.getAttribute("component");
  var event = transitionElement.getAttribute("event");
  var branch = transitionElement.getAttribute("branch");

  if (maskat.globalVar.transition[component] == undefined){
    maskat.globalVar.transition[component] = new Array();
  }

  if (branch != undefined){
    if (maskat.globalVar.transition[component][event] == undefined){
      maskat.globalVar.transition[component][event] = new Array();
    }
    maskat.globalVar.transition[component][event][branch] = maskat.parseTransition3(transitionElement, component, event);
  }
  else {
    maskat.globalVar.transition[component][event] = maskat.parseTransition3(transitionElement, component, event);
  }
}

maskat.parseTransition3 = function(transitionElement, component, event){
  return function(){
    for (var i = 0; i < transitionElement.childNodes.length; i++){
      var layoutCommandElement = transitionElement.childNodes.item(i);
      if (layoutCommandElement.nodeType != 1){
        continue;
      }
      switch(layoutCommandElement.nodeName){
        case "loadLayout":
          var xmlFile = layoutCommandElement.getAttribute("xmlFile");
          var target = layoutCommandElement.getAttribute("target");
          var show = layoutCommandElement.getAttribute("show");
          if (show == "true"){ show = true; }
          else {show = false;}
          var pos = xmlFile.lastIndexOf(".");
          maskat.loadLayoutFile(xmlFile, target, show);
          maskat.loadEventFile(xmlFile.substring(0, pos) + "_e.xml");
          break;
        case "showLayout":
          var layout = layoutCommandElement.getAttribute("layout");
          maskat.showLayout(layout);
          break;
        case "hideLayout":
          var layout = layoutCommandElement.getAttribute("layout");
          maskat.hideLayout(layout);
          break;
        case "removeLayout":
          var layout = layoutCommandElement.getAttribute("layout");
          maskat.removeLayout(layout);
          break;
      }
    }
  }
}

maskat.tryTransition = function(component, event){
  if (component && maskat.globalVar.transition != null){
    var branch = eval(component + ".branch")
    if (maskat.globalVar.transition[component] && maskat.globalVar.transition[component][event]){
      if (branch != undefined){
        maskat.globalVar.transition[component][event][branch]();
      }
      else {
        maskat.globalVar.transition[component][event]();
      }
    }
  }
}

maskat.widget.ConfirmDialog = function(objPar){
    if (rialto.lang.isString(objPar.name)) {
        this.name = objPar.name;
    }
    this.title = "確認";
    if (rialto.lang.isString(objPar.title)) {
        this.title = objPar.title;
    }
    this.message = "";
    if (rialto.lang.isString(objPar.message)) {
        this.message = objPar.message;
    }
    if (rialto.lang.isString(objPar.btnOKTxt)) {
        this.btnOKTxt = objPar.btnOKTxt;
    }else{
        this.btnOKTxt = "OK";
    }
    if (rialto.lang.isString(objPar.btnCancelTxt)) {
        this.btnCancelTxt = objPar.btnCancelTxt;
    }else{
        this.btnCancelTxt = "Cancel";
    }
    if (rialto.lang.isNumber(objPar.btnOnFocus)){
        this.btnOnFocus = objPar.btnOnFocus;
    }else{
        this.btnOnFocus = 2;
    }
    this.okFunc = objPar.okFunc;
    this.cancelFunc = objPar.cancelFunc;
}

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

maskat.widget.ConfirmDialog.prototype.runOkFunc = function(){
    try{
        if (this.okFunc != null)
        	eval(this.okFunc + "();");
    } catch (e){
        maskat.getFWLog().error("ConfirmDialog["+this.name+"]のokFunc関数実行中、エラーが発生。",e);
        throw e;
    } 
}

maskat.widget.ConfirmDialog.prototype.runCancelFunc = function(){
    try{
        if (this.cancelFunc != null)
	        eval(this.cancelFunc + "();");
    } catch (e){
        maskat.getFWLog().error("ConfirmDialog["+this.name+"]のcancelFunc関数実行中、エラーが発生。",e);
        throw e;
    }
}

maskat.widget.ConfirmDialog.prototype.initialize = function(){

    if (this.popup != null){
        this.popup.setVisible(true);
        if (this.btnOnFocus==1){
            this.btnOK.getHtmlExt().focus();
        } else {
            this.btnCancel.getHtmlExt().focus();
        }
        return;
    }
    var widthGlobal = document.body.clientWidth;
    var heightGlobal = document.body.clientHeight;
    var top = (heightGlobal / 2) - 120;
    var left = (widthGlobal / 2) - 100;
    this.width = getTailleTexte(this.title) + 40;
    if (this.width < 300) {
        this.width = 300;
    }
    var objPopupPar = {withCloseButon:false};
    this.popup= new rialto.widget.PopUp(this.name+"_Popup_Message", top, left, this.width, 50, null, this.title, "transparent", objPopupPar);
    this.textDiv = document.createElement("div");
    this.textDiv.innerHTML = this.message;
    this.popup.getHtmlCont().appendChild(this.textDiv);
    var oThis = this;

    this.btnOK = new rialto.widget.Button(25,parseInt(this.width) / 2 - 114,this.btnOKTxt,
        this.btnOKTxt,this.popup);
    this.btnOK.onclick=function(e){
        oThis.popup.setVisible(false);
        oThis.onOK();
    }
    this.btnOK.getHtmlExt().tabIndex = 32767;
    this.btnOK.getHtmlExt().onfocus = function(e){
        focusObj = oThis.btnOK;
    }

    this.btnCancel = new rialto.widget.Button(25,parseInt(this.width) / 2 + 6,this.btnCancelTxt,
        this.btnCancelTxt,this.popup);
    this.btnCancel.onclick=function(e){
        oThis.popup.setVisible(false);
        oThis.onCancel();
    }
    this.btnCancel.getHtmlExt().tabIndex = 32767;
    this.btnCancel.getHtmlExt().onfocus = function(e){
        focusObj = oThis.btnCancel;
    }
    if (this.btnOnFocus==1){
        this.btnOK.getHtmlExt().focus();
    } else {
        this.btnCancel.getHtmlExt().focus();
    }

    this.layout();
}
maskat.widget.ConfirmDialog.prototype.setMsg = function (msg) {
    this.textDiv.innerHTML = msg;
    this.layout();
}
maskat.widget.ConfirmDialog.prototype.layout = function(){
    var contentHeight = this.textDiv.offsetHeight + 30;
    this.height = contentHeight + 46;
    this.popup.getHtmlExt().style.height = this.height;
    this.popup.getHtmlCont().style.height = contentHeight;
    this.btnOK.getHtmlExt().style.top = contentHeight - 25;
    this.btnCancel.getHtmlExt().style.top = contentHeight - 25;

    //幅を計算
    var contentWidth = getTailleTexte(this.textDiv.innerHTML) + 30;
    if (contentWidth < 300){
        contentWidth = 300;
    }
    this.width = contentWidth;
    this.popup.getHtmlExt().style.width = this.width;
    this.popup.getHtmlCont().style.width = this.width;
    this.btnOK.getHtmlExt().style.left = parseInt(this.width) / 2 - 114;
    this.btnCancel.getHtmlExt().style.left = parseInt(this.width) / 2 + 6;
}
maskat.widget.ConfirmDialog.prototype.setTitle = function (title) {
    this.popup.setTitle(title);
}
maskat.widget.ConfirmDialog.prototype.onOK = function (e) {
};
maskat.widget.ConfirmDialog.prototype.onCancel = function (e) {
};

maskat.widget.ConfirmDialog.prototype.placeIn = function (par) {
    this.popup.placeIn(par);
};
maskat.widget.ConfirmDialog.prototype.isContainer = false;

maskat.widget.ConfirmDialog.prototype.setVisible = function(visible){
    if (this.popup != null) {
        this.popup.setVisible(visible);
    }
}

maskat.widget.ConfirmDialog.prototype.remove = function(){
    if (this.popup != null) {
        this.popup.remove();
        this.popup = null;
    }
}

maskat.syntax["confirmDialog"]= {
    name: {type: "string"},
    title: {type: "string"},
    message: {type: "string"},
    btnOKTxt: {type: "string"},
    btnCancelTxt: {type: "string"},
    btnOnFocus: {type: "number"},
    okFunc: {type: "string"},
    cancelFunc: {type: "string"}
  };

maskat.transConfirmDialogTag = function(pathObjArray, domElem){
  var attr = {};

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

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

  var output = attr.name + " = new maskat.widget.ConfirmDialog(" + strObjPar + ");\n";
  output += "layoutObj.components[\"" + attr.name + "\"]="+attr.name+";\n";

  return output;
}

maskat.widget.EndDialog = function(objPar){
    if (rialto.lang.isString(objPar.name)) {
        this.name = objPar.name;
    }
    this.message = "メッセージ";
    if (rialto.lang.isString(objPar.message)) {
        this.message = objPar.message;
    }
}

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

maskat.widget.EndDialog.prototype.initialize = function(){
    this.alertComp = new rialto.widget.Alert(this.message);
}

maskat.widget.EndDialog.prototype.setVisible = function(visible){
    if (this.alertComp!=null)
        this.alertComp.fen.setVisible(visible);
}

maskat.widget.EndDialog.prototype.remove = function(){
    if (this.alertComp!=null)
        this.alertComp.remove();
}

maskat.syntax["endDialog"]= {
    name: {type: "string"},
    message: {type: "string"}
  };
  
maskat.transEndDialogTag = function(pathObjArray, domElem){
  var attr = {};

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

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

  var output = attr.name + " = new maskat.widget.EndDialog(" + strObjPar + ");\n";
  output += "layoutObj.components[\"" + attr.name + "\"]="+attr.name+";\n";

  return output;
}





/**
 * コードリブ
 */
maskat.codeLabelTeleConsumer={};

/**
 * 以下のような電文のconsumerです：
 * <param><code>1</code><label>ラベル</label></param>
 */
maskat.codeLabelTeleConsumer.consume=function(targetObj,teleNode){
    if ((targetObj==null) || !(targetObj instanceof rialto.widget.codeLabel)){
        throw new MaskatError({name: "codeLabelTeleConsumerエラー",
                         message: "targetObjはrialto.widget.codeLabelではありません",
                         fileName: "codeLabelWrapper.js",
                         functionName: "maskat.codeLabelTeleConsumer.consume"});
    }
    //電文にteleNodeは一個しかないであるはず
    var code = maskat.xpath(teleNode[0], 'code/text()');
    var theLabel = maskat.xpath(teleNode[0], 'label/text()');
    targetObj.setValue(code,theLabel);
}

ObjWrapper.registerTeleConsumer("codeLabel.codeLabel",maskat.codeLabelTeleConsumer);




/**
 * グーグルマップ
 */
maskat.syntax["googleMap"]= {
    name: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    width: {type: "number"},
    height: {type: "number"},
    initialLongitude: {type: "number"},
    initialLatitude: {type: "number"},
    initialZoomLevel: {type: "number"},
    parent: {type: "object"},
    mapControl: {type:"enum", elem: ["large","small"]},
    typeControl: {type:"boolean"},
    doubleClickZoom: {type:"boolean"},
    continuousZoom: {type:"boolean"}
  };

maskat.transGoogleMapTag = function(pathObjArray, domElem){
  var attr = {};

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

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName=null;
  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);

  var output = attr.name + " = new maskat.widget.GoogleMap(" + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
  return output;
}

if (typeof maskat.widget == "undefined"){
    maskat.widget={};
}

maskat.widget.GoogleMap = function(objPar){
    //if parent is not specified then create a div DOM object as the parent
    var parentObj = objPar.parent;
    if (parentObj==null){
        parentObj = document.body;
        objPar.parent = document.body;
    }

    this.base=rialto.widget.AbstractComponent;
    this.base(objPar);
    this.parent = objPar.parent;

    var gmap2Defined = true;
    try{
        GMap2;
    }catch(e){gmap2Defined=false;}
    //check if gmap2 object is already defined(google maps API is already loaded)
    if (gmap2Defined==false){
        if (objPar.key==null) {
            throw new MaskatError({name: "layoutXML Syntax Error",
                           message: "グーグルマップコンポーネント予めロードされていない場合key属性が必須です。",
                           fileName: "googleMapEx.js",
                           functionName: "maskat.widget.GoogleMap"});
        } else{
            //if not,load gmap2 object with the key
            //
            maskat.loadJSFile("http://maps.google.com/maps?file=api&amp;v=2&amp;key="+objPar.key);
            if (GMap2==null){
                throw new MaskatError({name: "グーグルマップAPIロード失敗",
                           message: "グーグルマップAPIロードに失敗しました。",
                           fileName: "googleMapEx.js",
                           functionName: "maskat.widget.GoogleMap"});
            }
        }
    }

    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.style.width=this.width+"px";
    this.divExt.style.height=this.height+"px";
    this.divExt.style.overflow='hidden';
    this.divExt.style.textOverflow="ellipsis";
    this.divExt.style.whiteSpace="nowrap";
    if(this.parent){this.placeIn(this.parent);};

    this.map = new GMap2(this.divExt);
    var longitude=0;
    var latitude=0;
    if (objPar.initialLongitude !=null && objPar.initialLatitude!=null){
    	longitude=objPar.initialLongitude;
    	latitude=objPar.initialLatitude;
    }
    var zoomLevel = 10;
    if (objPar.initialZoomLevel !=null){
    	zoomLevel=objPar.initialZoomLevel;
    }
    this.map.setCenter(new GLatLng(latitude, longitude), zoomLevel);
    if (objPar.mapControl=="large"){
        this.map.addControl(new GLargeMapControl());
    }
    if (objPar.mapControl=="small"){
        this.map.addControl(new GSmallMapControl());
    }
    if (objPar.typeControl==true){
        this.map.addControl(new GMapTypeControl());
    }
    if (objPar.doubleClickZoom==true){
    	this.map.enableDoubleClickZoom();
    }
    if (objPar.continuousZoom==true){
    	this.map.enableContinuousZoom();
    }
}

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

maskat.widget.GoogleMap.prototype.setCenter = function(latitude,longitude){
    this.map.setCenter(new GLatLng(latitude,longitude));
}

maskat.widget.GoogleMap.prototype.setMarkerAt = function(latitude,longitude){
	var mp = new GLatLng(latitude, longitude);
	var marker = new GMarker(mp);
	this.map.addOverlay(marker);
	return marker;
}

maskat.widget.GoogleMap.prototype.getCenter = function(){
    return this.map.getCenter();
}

maskat.widget.GoogleMap.prototype.openInfoWindow = function(latitude,longitude,text){
    this.map.openInfoWindow(new GLatLng(latitude, longitude),document.createTextNode(text));
}

maskat.widget.GoogleMap.prototype.closeInfoWindow = function(){
    this.map.closeInfoWindow();
}

maskat.widget.GoogleMap.prototype.setDoubleClickZoom = function(doubleClickZoom){
    if (doubleClickZoom==true){
        this.map.enableDoubleClickZoom();
    }else{
        this.map.disableDoubleClickZoom();
    }
}

maskat.googleMap={};


//以下は電文マッピングラッパー拡張

/**
 * 電文サンプル<mapData><lat>123.456</lat><lng>12.23</lng></mapData>
 * 電文に指定する座標位置に移動する
 */
maskat.googleMap.panToLatLngTeleConsumer={};
maskat.googleMap.panToLatLngTeleConsumer.consume=function(targetObj,teleNode){
    if ((targetObj==null) || !(targetObj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "panToLatLngTeleConsumerエラー",
                         message: "targetObjはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.panToLatLngTeleConsumer.consume"});
    }
    //電文にteleNodeは一個しかないであるはず
    var lat = maskat.xpath(teleNode[0], 'lat/text()');
    var lng = maskat.xpath(teleNode[0], 'lng/text()');
    targetObj.setCenter(lat,lng);
}
ObjWrapper.registerTeleConsumer("googleMap.panToLatLng",maskat.googleMap.panToLatLngTeleConsumer);

/**
 * 電文サンプル<mapData><lat>123.456</lat><lng>12.23</lng></mapData>
 * 電文に指定する座標位置にマーカーを作る
 */
maskat.googleMap.markAtLatLngTeleConsumer={};
maskat.googleMap.markAtLatLngTeleConsumer.consume=function(targetObj,teleNode){
    if ((targetObj==null) || !(targetObj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "markAtLatLngTeleConsumerエラー",
                         message: "targetObjはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.markAtLatLngTeleConsumer.consume"});
    }
    //電文にteleNodeは一個しかないであるはず
    var lat = maskat.xpath(teleNode[0], 'lat/text()');
    var lng = maskat.xpath(teleNode[0], 'lng/text()');
    targetObj.setMarkerAt(lat,lng);
}
ObjWrapper.registerTeleConsumer("googleMap.markAtLatLng",maskat.googleMap.markAtLatLngTeleConsumer);

/**
 * 電文サンプル<mapData><lat>123.456</lat><lng>12.23</lng><text>吹き出しテキスト</text></mapData>
 * 電文に指定する座標位置に吹き出しを作る
 */
maskat.googleMap.infoWinAtLatLngTeleConsumer={};
maskat.googleMap.infoWinAtLatLngTeleConsumer.consume=function(targetObj,teleNode){
    if ((targetObj==null) || !(targetObj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "infoWinAtLatLngTeleConsumerエラー",
                         message: "targetObjはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.infoWinAtLatLngTeleConsumer.consume"});
    }
    //電文にteleNodeは一個しかないであるはず
    var lat = maskat.xpath(teleNode[0], 'lat/text()');
    var lng = maskat.xpath(teleNode[0], 'lng/text()');
    var text = maskat.xpath(teleNode[0], 'text/text()');
    targetObj.openInfoWindow(lat,lng,text);
}
ObjWrapper.registerTeleConsumer("googleMap.infoWinAtLatLng",maskat.googleMap.infoWinAtLatLngTeleConsumer);

/**
 * 電文サンプル<mapData><lat>123.456</lat><lng>12.23</lng><text>吹き出しテキスト</text></mapData>
 * 電文に指定する座標でマーカーを作って、マーカーのonclick度にテキスト吹き出しを表示
 */
maskat.googleMap.markExAtLatLngTeleConsumer={};
maskat.googleMap.markExAtLatLngTeleConsumer.consume=function(targetObj,teleNode){
    if ((targetObj==null) || !(targetObj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "markExAtLatLngTeleConsumerエラー",
                         message: "targetObjはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.markExAtLatLngTeleConsumer.consume"});
    }
	//電文にteleNodeは一個しかないであるはず
    var lat = maskat.xpath(teleNode[0], 'lat/text()');
    var lng = maskat.xpath(teleNode[0], 'lng/text()');
    var text = maskat.xpath(teleNode[0], 'text/text()');
    targetObj.setMarkerAt(lat,lng);
    GEvent.addListener(targetObj.map, 'click', function(overlay, point) {
        if (overlay && overlay.openInfoWindow!=null) {
          overlay.openInfoWindow(document.createTextNode(text));
        }
    });
}
ObjWrapper.registerTeleConsumer("googleMap.markExAtLatLng",maskat.googleMap.markExAtLatLngTeleConsumer);


/**
 * 電文サンプル
 * <mapData><lat>123.456</lat><lng>12.23</lng><name>吹き出しテキスト１</name></mapData>
 * <mapData><lat>122.334</lat><lng>32.23</lng><name>吹き出しテキスト２</name></mapData>
 * 電文に指定する座標でマーカーを作って、マーカーのonclick度にテキスト吹き出しを表示
 */
maskat.googleMap.marksExAtLatLngTeleConsumer={};
maskat.googleMap.marksExAtLatLngTeleConsumer.consume=function(targetObj,teleNode){
    if ((targetObj==null) || !(targetObj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "marksExAtLatLngTeleConsumerエラー",
                         message: "targetObjはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.marksExAtLatLngTeleConsumer.consume"});
    }
    //電文にteleNodeは一個しかないであるはず
    for (var i=0;i<teleNode.length;i++){
        var lat = maskat.xpath(teleNode[i], 'lat/text()');
        var lng = maskat.xpath(teleNode[i], 'lng/text()');
        var text = maskat.xpath(teleNode[i], 'name/text()');
	    var mp = new GLatLng(lat, lng);
       	targetObj.map.addOverlay(maskat.googleMap.createMarker(mp,text));
    }
}
ObjWrapper.registerTeleConsumer("googleMap.marksExAtLatLng",maskat.googleMap.marksExAtLatLngTeleConsumer);

maskat.googleMap.createMarker = function (point, text) {
  var marker = new GMarker(point);
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindow(text);
  });
  return marker;
}

//電文メーカー
maskat.googleMap.latLngTeleMaker={};
maskat.googleMap.latLngTeleMaker.make = function(obj,validator,sourceNode){
    if ((obj==null) || !(obj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "latLngTeleMakerエラー",
                         message: "objはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.latLngTeleMaker.make"});
    }
    var center = obj.getCenter();
    var content = "<lat>"+center.lat()+"</lat><lng>"+center.lng()+"</lng>";
    
    var nodeName = maskat.xpath(sourceNode,"@node");
    if (nodeName!=null) {
      return "<" + nodeName + ">" + content + "</" + nodeName + ">";
    } else {
      return content;
	}
}
ObjWrapper.registerTeleMaker("googleMap.latLng",maskat.googleMap.latLngTeleMaker);


maskat.googleMap.panToLatLngLocalWorker={};
maskat.googleMap.panToLatLngLocalWorker.work = function(obj,inObj){
    if ((obj==null) || !(obj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "panToLatLngLocalWorkerエラー",
                         message: "objはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.panToLatLngLocalWorker.work"});
    }
    if (inObj == null){
    	//TODO エラーをスロー？
        return;
    }
    obj.setCenter(inObj.lat,inObj.lng);
}
ObjWrapper.registerLocalWorker("googleMap.panToLatLng",maskat.googleMap.panToLatLngLocalWorker);

maskat.googleMap.markAtLatLngLocalWorker={};
maskat.googleMap.markAtLatLngLocalWorker.work=function(targetObj,inObj){
    if ((targetObj==null) || !(targetObj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "markAtLatLngLocalWorkerエラー",
                         message: "targetObjはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.markAtLatLngLocalWorker.consume"});
    }
    //電文にteleNodeは一個しかないであるはず
    targetObj.setMarkerAt(inObj.lat,inObj.lng);
}
ObjWrapper.registerLocalWorker("googleMap.markAtLatLng",maskat.googleMap.markAtLatLngLocalWorker);

maskat.googleMap.marksExAtLatLngLocalWorker={};
maskat.googleMap.marksExAtLatLngLocalWorker.work=function(targetObj,inObj){
    if ((targetObj==null) || !(targetObj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "marksExAtLatLngLocalWorkerエラー",
                         message: "targetObjはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.marksExAtLatLngLocalWorker.consume"});
    }
    //inObjは配列
    for (var i=0;i<inObj.length;i++){
        var oneObj = inObj[i];
	    var mp = new GLatLng(oneObj.lat, oneObj.lng);
       	targetObj.map.addOverlay(maskat.googleMap.createMarker(mp,oneObj.name));
    }
}
ObjWrapper.registerLocalWorker("googleMap.marksExAtLatLng",maskat.googleMap.marksExAtLatLngLocalWorker);

maskat.googleMap.infoWinAtLatLngLocalWorker={};
maskat.googleMap.infoWinAtLatLngLocalWorker.work = function(obj,inObj){
    if ((obj==null) || !(obj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "infoWinAtLatLngLocalWorkerエラー",
                         message: "objはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.infoWinAtLatLngLocalWorker.work"});
    }
    if (inObj == null){
    	//TODO エラーをスロー？
        return;
    }
    obj.openInfoWindow(inObj.lat,inObj.lng,inObj.text);
}
ObjWrapper.registerLocalWorker("googleMap.infoWinAtLatLng",maskat.googleMap.infoWinAtLatLngLocalWorker);

maskat.googleMap.storeLatLngLocalWorker={};
maskat.googleMap.storeLatLngLocalWorker.work = function(obj,inObj,targetNode){
    //inObjはGoogleMapオブジェクト
    if ((inObj==null) || !(inObj instanceof maskat.widget.GoogleMap)){
        throw new MaskatError({name: "storeLatLngLocalWorkerエラー",
                         message: "inObjはmaskat.widget.GoogleMapではありません",
                         fileName: "googleMapEx.js",
                         functionName: "maskat.googleMap.storeLatLngLocalWorker.work"});
    }
    if (obj == null){
        var outName = maskat.xpath(targetNode, '@out');
        eval(outName+"={};");
        obj = eval(outName);
    }
    var center = inObj.getCenter();
    obj.lat = center.lat();
    obj.lng = center.lng();
}
ObjWrapper.registerLocalWorker("googleMap.storeLatLng",maskat.googleMap.storeLatLngLocalWorker);




/**
 * アイフレーム
 */
maskat.syntax["iFrame"]= {
    name: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    width: {type: "string"},
    height: {type: "string"},
    url: {type: "string"},
    parent: {type: "object"}
  };
  
maskat.transIFrameTag = function(pathObjArray, domElem){
  var attr = {};

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

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName=null;
  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);

  var output = attr.name + " = new maskat.widget.IFrame(" + strObjPar + ");\n";
  output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
  return output;
}

maskat.widget.IFrame = function(objPar){
    //if parent is not specified then create a div DOM object as the parent
    var parentObj = objPar.parent;
    if (parentObj==null){
        parentObj = document.body;
        objPar.parent = document.body;
    }
	objPar.type = "iFrame";
    this.base=rialto.widget.AbstractComponent;
    this.base(objPar);
    this.method = objPar.method;
    this.parent = objPar.parent;
    
    // マスカット用
    this.isSingle = true;
    // 複数データの場合
    //this.isMulti = true;
    
    // フレーム設定
    objPar["title"] = "";
    objPar["initial"] = true;
    objPar["dynamic"] = false;
    objPar["position"] = "absolute";
    objPar["draggable"] = false;
    objPar["boolMaxi"] = false;
    this.frame = new rialto.widget.Frame(objPar);
    this.frame.cadre.style.overflow="hidden";
    this.iframe = document.createElement("iframe");
    this.iframe.id = this.id + "_iFrame";
    this.iframe.style.width = this.width;
    this.iframe.style.height = this.height;
    if(objPar.url){
	   	this.iframe.src = objPar.url;
    }
    this.frame.add(this.iframe);
    this.parent.add(this.frame);
}

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

// 値の設定（シングル版）
maskat.widget.IFrame.prototype.setSingleValue = function(val){
	if(val){
		this.iframe.src = val;
    }
}

// 値の設定（マルチ版）
maskat.widget.IFrame.prototype.setMultiValue = function(val){
	// 未使用
}

// 値の取得（シングル版）
maskat.widget.IFrame.prototype.getSingleValue = function(){
	return this.iframe.src;
}

maskat.widget.IFrame.prototype.remove = function(){
	this.frame.remove();
}




/**
 * メニュー
 */
/**********************************************
***********************************************
*
*			MENU BAR
*
*
**********************************************/
maskat.widget.MenuBar = function(parent, objPar)
{
	this.menuEntriesArray 		= new Array();
	this.arrChild				= null;
	
	this.name					= "";
	
	// base constructor
	this.base	= rialto.widget.AbstractContainer;
	objPar.type	= "maskat.widget.MenuBar"
	this.base(objPar);
	
	this.title = "MenuBar";
	
	// default values Rialto/Menu
	this.widthEntry			= 100;
    this.resizable
    this.autoResizeContenu 	= false;    
    this.autoResizeParent 	= false;
    this.isClosable 		= false;
    this.draggableItem 		= false;
    
    
    // init values with the properties of the objPar object
    if (rialto.lang.isNumber(objPar.widthEntry))
    {
    	this.widthEntry
    }
    if (objPar && objPar.name != null)
	{
		this.name = objPar.name;
	}	
    
   	objPar = null;
    
    var oThis	= this;
    
	// *******************************************
	// GENERATION OF DOM ELEMENTS
	// *******************************************    
   	this.baseCSSClassName		= "maskat_widget_menu_bar";
    
	this.divExt.style.top		= "0px";
    this.divExt.style.left		= "0px";
    this.divExt.style.height	= "20";
    this.divExt.style.width		= "100%";                
	
	this.divExt.className		= this.baseCSSClassName;
/*	
	this.divEntries					= document.createElement("DIV");
	this.divEntries.id				= "DIV_MAINCONTAINER";
	this.divEntries.style.height	= "auto";
	this.divEntries.className		= this.baseCSSClassName + "_center";
	
	this.divExt.appendChild(this.divEntries);
*/	
	if (parent)
	{	
		this.placeIn(parent);
	}	
}

maskat.widget.MenuBar.prototype = new rialto.widget.AbstractContainer;

maskat.widget.MenuBar.prototype.add = function(newEntry, bValue)
{
	this.menuEntriesArray.push(newEntry);
//	this.divEntries.appendChild(newEntry.divExt);
	this.divExt.appendChild(newEntry.divExt);
	
	/* For Rialot remove() */
	this.arrChild = this.menuEntriesArray;	
} 

maskat.widget.MenuBar.prototype.removeEntry = function(entry)
{
	// ToDo
}

maskat.widget.MenuBar.prototype.getPath = function()
{
	return this.name;
}


/*********************************************************
*
*		MENU ANIMATION
*
**********************************************************/
maskat.widget.MenuBar.prototype.closeOpenMenus = function(activeMenuRef, event)
{
	for(var i = 0; i < this.menuEntriesArray.length; i++)
	{
		if (this.menuEntriesArray[i] != activeMenuRef)
		{
			this.menuEntriesArray[i].closeOpenMenu(event);
		}
	}
}

// maskat.widget.MenuContainer.prototype.adaptAfterSizeChange
// maskat.widget.MenuContainer.prototype.adaptToContext
// maskat.widget.MenuContainer.prototype.updateSize
// maskat.widget.MenuContainer.prototype.updateWidth
// maskat.widget.MenuContainer.prototype.updateHeight

/**********************************************************
*
*		REMOVING COMPONENT
*
**********************************************************/
maskat.widget.MenuBar.prototype.release = function()
{
	// Should remove all children
	// called in Rialot -> remove
}
/**********************************************
***********************************************
*
*			MENU ENTRY
*
*
**********************************************/
maskat.widget.MenuEntry = function(parentContainerObj, title, objPar)
{	
	// base constructor
	this.base	= rialto.widget.AbstractComponent;
	objPar.type	= "maskat.widget.Menu";
	
	this.base(objPar);

    this.parentContainerObj	= null;
	this.childContainerObj	= null;
	this.name				= "";
	
	// Values for server communication
/*	this.enabled				= true;*/
	this.visible				= true;
	this.value					= null;



/*	if(rialto.lang.isBoolean(objPar.enabled))
	{
		this.enabled	= objPar.enabled;
	}*/
	if(rialto.lang.isBoolean(objPar.visible))
	{
		this.visible	= objPar.visible;
	}
	if (objPar && objPar.value != null)
	{
		this.value = objPar.value;
	}
	
	// Default values rialto/Menu
	this.title				= title;
	this.enable 			= true;
	this.height				= "18px";
	this.widthMin			= "20px";
	this.width				= "auto";
		
	this.autoResizeParent 	= parent.autoResizeParent;   
    this.autoResizableH		= false;
    this.autoResizableW		= false; 
    	
	if(rialto.lang.isBoolean(objPar.enable))
	{
		this.enable	= objPar.enable;
	}
	if (objPar && objPar.name != null)
	{
		this.name = objPar.name;
	}	
	
	objPar 		= null;
	this.base 	= null;
	
	var oThis			= this;
	
	// *******************************************
	// GENERATION OF DOM ELEMENTS
	// *******************************************
	this.baseCSSClassName		= "maskat_widget_menu_entry_"
	
	if (window.opera)
	{
		this.top += 2; 
	}
	this.divExt.style.top		= this.top;
    this.divExt.style.left		= this.left;
    this.divExt.style.height	= this.height;
    this.divExt.style.minHeight = this.height;
    this.divExt.style.width		= this.width; 
    
    this.divExt.title			= this.title;   
	this.divExt.innerHTML		= this.title;
		
	this.divExt.onmouseover		= this.makeMouseOverFunc(oThis);
	this.divExt.onmouseout		= this.makeMouseOutFunc(oThis);
	this.divExt.onclick			= this.makeOnClickFunc(oThis);
	
	if (parentContainerObj)
	{
		this.parentContainerObj = parentContainerObj;
		this.placeIn(parentContainerObj);
	}
	
	this.updateVisibleDiv();
	this.updateEnabledDiv();
	
}

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

maskat.widget.MenuEntry.prototype.add = function(containerObj, bValue)
{
	this.childContainerObj = containerObj;
}

/*********************************************************
*
*		GETTER/SETTER
*
**********************************************************/
maskat.widget.MenuEntry.prototype.getParent = function()
{
	return 	this.parentContainerObj;
}

maskat.widget.MenuEntry.prototype.getPath = function()
{
	parentPath	= this.getParent().getPath();
	path		= parentPath + "/" + this.name;

	return path
}

maskat.widget.MenuEntry.prototype.getTitle = function()
{
	return 	this.title;
}

maskat.widget.MenuEntry.prototype.setTitle = function(sValue)
{
	this.title = sValue;
	this.divExt.innerHTML	= this.title;
}

/*
maskat.widget.MenuEntry.prototype.getEnable = function()
{
	return 	this.enable;
}
*/

maskat.widget.MenuEntry.prototype.setEnable = function(bValue)
{
/*	this.enabled = bValue;*/
	this.enable  = bValue;
	this.updateEnabledDiv();
}
/*
maskat.widget.MenuEntry.prototype.getVisible = function()
{
	return 	this.visible;
}
*/
maskat.widget.MenuEntry.prototype.setVisible = function(bValue)
{
	this.visible = bValue;
	this.updateVisibleDiv();
}

maskat.widget.MenuEntry.prototype.getValue = function()
{
	return 	this.value;
}

maskat.widget.MenuEntry.prototype.setValue = function(value)
{
	this.value = value;
}


maskat.widget.MenuEntry.prototype.setMultiValue = function(mulVal) 
{
	path	= mulVal[0]["PATH"];
	title 	= mulVal[0]["TITLE"];
	enable	= mulVal[0]["ENABLE"];
	visible = mulVal[0]["VISIBLE"];
	value	= mulVal[0]["VALUE"];

	str = 	  "path:\t" 	+ path 		+ "\n" 
			+ "enable:\t" 	+ enable 	+ "\n"
			+ "title:\t" 	+ title 	+ "\n"
			+ "visible:\t" 	+ visible 	+ "\n"
			+ "value:\t"	+ value		+ "\n";

	if (enable == "true") 
	{	
		this.setEnable(true);
	}
	else if (enable == "false")
	{
		this.setEnable(false);
	}
	if (title != null)
	{
		this.setTitle(title);
	}
	
	if (visible == "true")
	{
		this.setVisible(true);
	}
	else if (visible == "false")
	{
		this.setVisible(false);
	}
	
	if (value != null)
	{
		this.setValue(value);
	}
};


MenuEntryGetData = {};

MenuEntryGetData.menuValue = {};

MenuEntryGetData.menuValue.make = function(obj, validator, sourceNode)
{
	if ( (obj == null) || !(obj instanceof maskat.widget.MenuEntry) )
	{
		throw new MaskatError({name: "menuEntryTeleMarker error",
                         message: "obj is not of type <MenuEntryGetValue.menuData>",
                         fileName: "MenuEntry.js",
                         functionName: "MenuEntryGetValue.menuValue.make"});
	}
		
	var valueToSend = obj.getValue(); 
	
	var menuValueXML 	 = "<value>" + valueToSend + "</value>";
	
	var nodeName = maskat.xpath(sourceNode, "@node");
	
	if (nodeName != null)
	{
		return "<" + nodeName + ">" + valueToSend + "</" + nodeName + ">";
	}
	else
	{
		return menuValueXML;
	}
}

ObjWrapper.registerTeleMaker("menuEntry.value", MenuEntryGetData.menuValue);


MenuEntryGetData.menuData = {};

MenuEntryGetData.menuData.make = function (obj, validator, sourceNode)
{
	if ( (obj == null) || !(obj instanceof maskat.widget.MenuEntry) )
	{
		throw new MaskatError({name: "menuDataTeleMarker error",
                        message: "obj is not of type <MenuEntryGetData.menuData>",
                        fileName: "MenuEntry.js",
                        functionName: "MenuEntryGetData.menuData.make"});

	}

	var path 		= obj.getPath();
	var visible 	= obj.isVisible();
	var enable		= obj.isEnable();
	var title 		= obj.getTitle();
	var value		= obj.getValue();

	var menuDataXML	=	"<path>" 		+ path 		+ "</path>" 	+ 
						"<enable>"		+ enable   + "</enable>" 	+
						"<title>" 		+ title 	+ "</title>" 	+
						"<visible>" 	+ visible 	+ "</visible>"  +
						"<value>"		+ value		+ "</value>";

	var nodeName = maskat.xpath(sourceNode, "@node");
	
	if (nodeName != null)
	{
		return "<" + nodeName + ">" + menuDataXML + "</" + nodeName + ">";
	}
	else
	{	
		return menuDataXML;
	}
}

ObjWrapper.registerTeleMaker("menuEntry.data", MenuEntryGetData.menuData);
/*********************************************************
*
*		MENU ANIMATION
*
**********************************************************/
maskat.widget.MenuEntry.prototype.hideEntry = function()
{
	this.divExt.className	= this.baseCSSClassName + "passive" + " " + this.baseCSSClassName + "enabled";
}

maskat.widget.MenuEntry.prototype.forceCloseMenu = function()
{
	this.hideEntry();
}

maskat.widget.MenuEntry.prototype.closeOpenMenu = function(event)
{
	if(this.childContainerObj != null)
	{				
		this.childContainerObj.menuItemContainerCloses(event);
	}
	else
	{
		this.updateEnabledDiv()
	}
}

maskat.widget.MenuEntry.prototype.updateVisibleDiv = function()
{
	if (this.visible == false)
	{
		this.divExt.style.display = "none";
	}
	else
	{
		this.divExt.style.display = "inline";
	}
}

maskat.widget.MenuEntry.prototype.updateEnabledDiv = function()
{
	if (this.enable == true)
	{
    	this.divExt.className	= this.baseCSSClassName + "passive" + " " + this.baseCSSClassName + "enabled";
	}
	else 
	{
    	this.divExt.className	= this.baseCSSClassName + "passive" + " " + this.baseCSSClassName + "disabled";
	}
}




/**********************************************************
*
*		EVENT HANDLING
*
**********************************************************/
maskat.widget.MenuEntry.prototype.makeMouseOverFunc = function (oThis)
{

	return function(e)
	{
		if(!e)
		{
			e = window.event;
		}
		
		/* close all other menu entries */
		oThis.parentContainerObj.closeOpenMenus(oThis, e);
		
		if (oThis.enable)
		{	
			if (!window.opera)
			{

			
			/*	tmpArray = document.getElementsByTagName("input");
				
				for (var i = 0; i < tmpArray.length; i++)
				{
					tmpArray[i].blur();
				}
				
				tmpArray = document.getElementsByTagName("textarea");
				
				for (var i = 0; i < tmpArray.length; i++)
				{
					tmpArray[i].blur();
				}*/
			}
			
			this.className	= oThis.baseCSSClassName + "focus" + " " + oThis.baseCSSClassName + "enabled";		
			
			if(oThis.childContainerObj)
			{
				offsetTop	= this.offsetHeight;				
				offsetLeft	= this.offsetLeft;
								
				oThis.childContainerObj.showContainer(offsetLeft, offsetTop);
			}
			
			oThis.onmouseover(e);
		}
	}
}

maskat.widget.MenuEntry.prototype.makeMouseOutFunc = function(oThis)
{
	return function(e)
	{
		if(oThis.enable)
		{
			if (!e)
			{
				e = window.event;
			}

			if(oThis.childContainerObj != null)
			{				
				oThis.childContainerObj.hideContainer(e);
			}
			else
			{
				this.className	= oThis.baseCSSClassName + "passive" + " " + oThis.baseCSSClassName + "enabled";
			}
		}
	}
}

maskat.widget.MenuEntry.prototype.makeOnClickFunc = function(oThis)
{
	return function(e)
	{			
		if (oThis.childContainerObj == null)
		{
			if (oThis.enable)
			{			
				oThis.onclick(e);
				
				stopEvent(e);	    
			}
			else
			{
				// Do nothing -> could show child popup box
			}
		}
	}
}



/**********************************************************
*
*		REMOVING COMPONENT
*
**********************************************************/
maskat.widget.MenuEntry.prototype.release = function()
{
	this.divExt.onmouseover	= null;
	this.divExt.onmouseout	= null;
	this.divExt.onclick		= null;	

	if (this.childContainerObj)
	{
		// true: container calls remove must not remove itself from DOM tree
		//       container will "cut line"
		this.childContainerObj.remove(true);
	}
}


/**********************************************
***********************************************
*
*			MENU POPUP BOX
*
*
**********************************************/
maskat.widget.MenuPopup = function(parentEntryObj, parentDiv, objPar)
{
	this.cssClassName		= "maskat_widget_menu_popup";
	this.menuEntriesArray 	= new Array();
	this.speratorArray		= new Array();
	
	/* needed for Rialto Remove */
	this.arrChild			= null;
	
	this.parentEntryObj	  	= parentEntryObj;
	this.parentDiv			= parentDiv;
	this.name				= "";

	this.childMenuItemContainerHasFocus	= false;
	this.closeMenu						= false;
	
	/*
	* showContainer
	* onuseout 
	*/
	this.containerVisible				= false;
	
	// base constructor
	this.base	= rialto.widget.AbstractContainer;
	objPar.type	= "maskat.widget.MenuPopup"
	this.base(objPar);
	
	// default values Rialto/Menu
	this.widthEntry			= 100;
	this.width				= 130;
    this.autoResizeContenu 	= false;
    this.autoResizeParent 	= false;
    this.isClosable 		= false;
    this.draggableItem 		= false;
    
    // set the value with the properties of the objPar object
    if (rialto.lang.isNumber(objPar.width))
    {
    	this.width = objPar.width
    }
    if (objPar && objPar.name != null)
	{
		this.name = objPar.name;
	}	
    
    objPar 		= null;
  
	var oThis	= this;
	
    // *******************************************
	// GENERATION OF DOM ELEMENTS
	// *******************************************
	this.divExt.style.top		= "0px";
    this.divExt.style.left		= "0px";
    this.divExt.style.width		= this.width + "px";            		
	this.divExt.className		= this.cssClassName;  
	
	this.divExt.onmouseover	= this.makeMouseOverFunc(oThis);
	this.divExt.onmouseout	= this.makeMouseOutFunc(oThis);
	
	if (parentEntryObj)
	{
		this.placeIn(parentEntryObj);
		parentDiv.appendChild(this.divExt);
	}	  
}

maskat.widget.MenuPopup.prototype = new rialto.widget.AbstractContainer;

maskat.widget.MenuPopup.prototype.add = function(newEntry, bValue)
{
	this.menuEntriesArray.push(newEntry);
	this.divExt.appendChild(newEntry.divExt);
	
	this.arrChild = this.menuEntriesArray;
}

maskat.widget.MenuPopup.prototype.addSeperator = function()
{
	seperator 	= new maskat.widget.MenuSeparator();
	
	this.speratorArray[this.speratorArray.length] = seperator;
	
	this.divExt.appendChild(seperator.domNode);
	
	seperator	= null;
}

maskat.widget.MenuPopup.prototype.removeEntry = function(entry)
{
	// ToDo
}


/*********************************************************
*
*		GETTER/SETTER
*
**********************************************************/
maskat.widget.MenuPopup.prototype.getParent = function()
{
	return this.parentEntryObj;
}

maskat.widget.MenuPopup.prototype.getPath = function()
{
	parentPath	= this.getParent().getPath();

	path		= parentPath + "/" + this.name;

	return path
}



/*********************************************************
*
*		MENU ANIMATION
*
**********************************************************/
maskat.widget.MenuPopup.prototype.showContainer = function(xPos, yPos)
{
	this.divExt.style.left 	= xPos;
	this.divExt.style.top	= yPos;	
	
	this.divExt.style.display = "block";

	var maxLength = 0;	
	
	for (var i = 0; i < this.menuEntriesArray.length; i++)
	{

		this.menuEntriesArray[i].showItem();

		if (this.menuEntriesArray[i].acceleratorDiv.offsetWidth > maxLength)
		{
			maxLength = this.menuEntriesArray[i].acceleratorDiv.offsetWidth;
		}
	}
	
	for (var i = 0; i < this.menuEntriesArray.length; i++)
	{
		this.menuEntriesArray[i].acceleratorDiv.style.width = maxLength + "px";
	}
	
	this.containerVisible = true;
}

maskat.widget.MenuPopup.prototype.hideContainer = function(e)
{
		if (this.childMenuItemContainerHasFocus == false)
		{
			this.divExt.onmouseout(e);
		}
}

maskat.widget.MenuPopup.prototype.menuItemContainerCloses = function(e)
{
	if (this.childMenuItemContainerHasFocus == false && this.containerVisible == true)
	{
		this.divExt.onmouseout(e);
	}
}

maskat.widget.MenuPopup.prototype.forceCloseMenu = function()
{
	this.closeMenu 				= true;
	
	this.divExt.style.display 	= "none";
	
	this.parentEntryObj.forceCloseMenu();
}

maskat.widget.MenuPopup.prototype.setChildMenuItemHasFocus = function(bHasFocus)
{
	this.childMenuItemContainerHasFocus = bHasFocus;
}

/**********************************************************
*
*		EVENT HANDLING
*
**********************************************************/
maskat.widget.MenuPopup.prototype.makeMouseOverFunc = function (oThis)
{
	return function(e)
	{
		if (oThis.parentEntryObj.type == "maskat.widget.MenuItem")
		{
			oThis.parentEntryObj.setChildContainerHasFocus (true);
		}

	}
}

maskat.widget.MenuPopup.prototype.makeMouseOutFunc = function(oThis)
{
	return function(e)
	{
		// TODO: rewrite so that not needed anymore
		// to avoid reapearing of menu after mouse click
		if (oThis.closeMenu == false)
		{
			/* 
				- needed for opera other wise menu will close before mouse can hover over
				- neede for IE other wise sub container will not close proper 
					because ...?
			*/
			this.style.display = "block";
		}
		
		oThis.closeMenu = false;
		
		if (oThis.childMenuItemContainerHasFocus == false)
		{
			if(maskat.menuUtilsObj.checkIfMouseIsOut(e, this, oThis) == true)
			{
				this.style.display = "none";
				
				if (oThis.parentEntryObj.type == "maskat.widget.MenuItem")
				{
					oThis.parentEntryObj.setChildContainerCloses (e);
				}
				else
				{
					oThis.parentEntryObj.hideEntry();		
				}
				
				oThis.containerVisible = false;
			}
			else
			{
				if (oThis.parentEntryObj.type == "maskat.widget.MenuItem")
				{
					oThis.parentEntryObj.setChildContainerHasFocus (true);	
				}
				else
				{
					// Do nothing
				}				
			}
		}
	}
}



/**********************************************************
*
*		REMOVING COMPONENT
*
**********************************************************/
maskat.widget.MenuPopup.prototype.release = function()
{
	this.divExt.onmouseover	= null;
	this.divExt.onmouseout	= null;
}


/**********************************************
***********************************************
*
*			MENU ITEM
*
*
**********************************************/
maskat.widget.MenuItem = function (parentContainerObj, title, objPar)
{		
	if (!objPar)
	{
    	var objPar={};
    	objPar.name="maskat.widget.MenuItem";
	}   
	
	if (!objPar.type)
	{
		objPar.type	= "maskat.widget.MenuItem";
	}
	
	// base constructor
	this.base	= rialto.widget.AbstractComponent;	
	this.base(objPar);
	
	this.parentContainerObj		= null;
	this.childContainerObj		= null;
	this.overInnerElement		= false;
	
	this.childContainerHasFocus = false;
	
	// Values for server communication
	this.visible				= true;
	this.value					= null;
	
	if (objPar && objPar.name != null)
	{
		this.name = objPar.name;
	}	
	if (objPar && objPar.visible != null)
	{
		this.visible = objPar.visible;
	}	
	if (objPar && objPar.value != null)
	{
		this.value = objPar.value;
	}
	
	// Default values Rialto/Menu
	this.sIcon			= "";
	this.sIconAct		= "";
	this.sIconDis		= "";
	this.sIconDisAct	= "";
	
	this.title				= title;
	this.enable 			= true;
	
	// IE will increase height to 18 and FF/O will increase above -> must be set to 18
	this.height				= "18px";  
	this.widthMin			= "300px";
	this.width				= "100%";
	
	this.autoResizeParent 	= parent.autoResizeParent;   
    this.autoResizableH		= false;
    this.autoResizableW		= false; 
    
    if(rialto.lang.isBoolean(objPar.enable))
	{
		this.enable	= objPar.enable;
	}

	if(rialto.lang.isString(objPar.sIcon))
	{
		this.sIcon		= objPar.sIcon;		
	}
	if(rialto.lang.isString(objPar.sIconDisabled))
	{
		this.sIconDis		= objPar.sIconDisabled;

		if (this.sIcon == "")
		{
			this.sIcon 		= this.sIconDisabled;
		}
	}
	else 
	{
		this.sIconDis 		= this.sIcon
	}
	
	if (this.sIcon != "" && this.sIconDis != "")
	{
		this.sIconPassive		= maskat.menuUtilsObj.getPasFileName(this.sIcon);
		this.sIconDisPassive	= maskat.menuUtilsObj.getPasFileName(this.sIconDis);
	}
	
	objPar 		= null;
	this.base 	= null;
	
	// *******************************************
	// GENERATION OF DOM ELEMENTS
	// *******************************************
	this.baseCSSClassName	= "maskat_widget_menu_item_";
	
	this.divExt.style.top		= this.top;
    this.divExt.style.left		= this.left;
    this.divExt.style.height	= this.height;
    //this.width;
    this.divExt.style.width		= "auto";  
    
    this.divExt.title			= this.title;   
	
	
    if (this.sIcon == "" || this.sIconDisabled == "")	
    {
    	this.divLeftDummy			= document.createElement("DIV");
	    this.divLeftDummy.className	= this.baseCSSClassName + "left_div";
		this.divLeftDummy.innerHTML	= " ";		
		this.divExt.appendChild(this.divLeftDummy);
    }
    else
    {
    	this.divLeftActive				= document.createElement("IMG");
		this.divLeftActive.className	= this.baseCSSClassName + "left_img";
		this.divLeftActive.src			= this.sIconDis;
		this.divLeftActive.style.display = "none";
		
		this.divExt.appendChild(this.divLeftActive);
		
		this.divLeftPassive				= document.createElement("IMG");
		this.divLeftPassive.className	= this.baseCSSClassName + "left_img";
		this.divLeftPassive.src			= this.sIconPassive;
		this.divLeftPassive.style.display = "inline";

		this.divExt.appendChild(this.divLeftPassive);
    }

	
	this.divCenter				= document.createElement("DIV");
	this.divCenter.innerHTML	= " " + this.title + " ";
    this.divCenter.className	= this.baseCSSClassName + "center_div";
	this.divExt.appendChild(this.divCenter);
	
	this.divRight				= document.createElement("DIV");
    this.divRight.className		= this.baseCSSClassName + "right_div";
	this.divExt.appendChild(this.divRight);

	
	this.acceleratorDiv				= document.createElement("DIV");
	this.acceleratorDiv.innerHTML	= " ";
    this.acceleratorDiv.className	= this.baseCSSClassName + "accelerator_div";	
	this.divRight.appendChild(this.acceleratorDiv);
	
	this.dummyArrowDiv					= document.createElement("DIV");
	this.dummyArrowDiv.innerHTML			= " ";
    this.dummyArrowDiv.className			= "dummyDiv";	
    
    this.divRight.appendChild(this.dummyArrowDiv); 
    
	this.divArrowPassive			= null;	
	this.divArrowActive				= null;	

	var oThis = this;
	
	this.divExt.onmouseover	= this.makeMouseOverFunc(oThis);
	this.divExt.onmouseout	= this.makeMouseOutFunc(oThis);
	this.divExt.onclick		= this.makeOnClickFunc(oThis);
	
	if (parentContainerObj)
	{
		this.parentContainerObj = parentContainerObj
		this.placeIn(this.parentContainerObj);
	}
}

maskat.widget.MenuItem.prototype = new rialto.widget.AbstractContainer;

maskat.widget.MenuItem.prototype.add = function(containerObj, bValue)
{
	this.childContainerObj = containerObj;
	
	if (this.divArrowPassive == null)
	{
		this.divRight.removeChild(this.dummyArrowDiv);
		
		this.divArrowPassive			= document.createElement("IMG");
		this.divArrowPassive.src		= "images/arrowOff.PNG";
		this.divArrowPassive.className	= this.baseCSSClassName + "arrow_div";
		this.divArrowPassive.style.display = "inline";
		
		this.divArrowActive				= document.createElement("IMG");
		this.divArrowActive.src			= "images/arrowOn.PNG";
		this.divArrowActive.className	= this.baseCSSClassName + "arrow_div";
		this.divArrowActive.style.display = "none";
		
		this.divRight.appendChild(this.divArrowPassive);
		this.divRight.appendChild(this.divArrowActive);
	}
}

/*********************************************************
*
*		GETTER/SETTER
*
**********************************************************/
maskat.widget.MenuItem.prototype.name			= "";


maskat.widget.MenuItem.prototype.getParent = function()
{
	return this.parentContainerObj;
}

maskat.widget.MenuItem.prototype.getTitle = function()
{
	return this.title;
}

maskat.widget.MenuItem.prototype.setTitle = function(newTitle)
{
	this.title	= newTitle;
	this.divCenter.innerHTML	= this.title + " ";
}

maskat.widget.MenuItem.prototype.getPath = function()
{
	parentPath	= this.getParent().getPath();
	
	path		= parentPath + "/" + this.name;
	
	return path;
}

/*
maskat.widget.MenuItem.prototype.getEnable = function()
{
	
	return this.enable;
}
*/

maskat.widget.MenuItem.prototype.setEnable = function(bEnabled)
{
	if ((this instanceof maskat.widget.MenuItem)&& !(this instanceof maskat.widget.MenuCheckboxItem))
	{
		this.enable  = bEnabled;
		this.updateEnabledDiv();
	}
}

/*
// inhereted from Rialto
maskat.widget.MenuItem.prototype.isVisible = function()
{
	return this.visible;
}
*/

maskat.widget.MenuItem.prototype.setVisible = function(bVisible)
{
	this.visible = bVisible;
	this.updateVisibleDiv();
}


maskat.widget.MenuItem.prototype.getValue = function()
{
	return this.value;
}

maskat.widget.MenuItem.prototype.setValue = function(value)
{
	this.value = value;
}



/*********************************************************
*
*		MENU ANIMATION
*
**********************************************************/
maskat.widget.MenuItem.prototype.showItem = function()
{
	if (this.visible == true)
	{
		this.divExt.style.display = "block";
		this.updateEnabledDiv();
		
		if (!this.divLeftDummy)
		{
			this.divLeftActive.style.display 	= "none";
			this.divLeftPassive.style.display 	= "inline";
		}
	}
	else 
	{
		this.divExt.style.display = "none";
	}
}

/*
TODO: Rename function
*/
maskat.widget.MenuItem.prototype.setChildContainerCloses = function(e)
{
	this.childContainerHasFocus 	= false;

	this.divArrowPassive.style.display	= "inline";
	this.divArrowActive.style.display 	= "none";
	
	if (!this.divLeftDummy)
	{
		this.divLeftActive.style.display 	= "none";
		this.divLeftPassive.style.display 	= "inline";
	}
	
    this.divExt.className = this.baseCSSClassName + "passive" + " " + this.baseCSSClassName + "enabled";
	
	this.parentContainerObj.setChildMenuItemHasFocus(false);
	this.parentContainerObj.hideContainer(e);
}

maskat.widget.MenuItem.prototype.hideEntry = function()
{
   	this.divArrowPassive.style.display 	= "inline";
	this.divArrowActive.style.display 	= "none";	
	
	if (!this.divLeftDummy)
	{
		this.divLeftActive.style.display 	= "none";
		this.divLeftPassive.style.display 	= "inline";
	}
	
    this.divExt.className = this.baseCSSClassName + "passive" + " " + this.baseCSSClassName + "enabled";	
}

maskat.widget.MenuItem.prototype.forceCloseMenu = function()
{
	this.parentContainerObj.forceCloseMenu();
}

maskat.widget.MenuItem.prototype.setChildContainerHasFocus = function(hasFocus)
{
	this.childContainerHasFocus = hasFocus;
	this.parentContainerObj.setChildMenuItemHasFocus(true);
}

maskat.widget.MenuItem.prototype.getChildContainerHasFocus = function(hasFocus)
{
	return this.childContainerHasFocus;
}


maskat.widget.MenuItem.prototype.updateVisibleDiv = function()
{
	if (this.visible == false)
	{
		this.divExt.style.display = "none";
	}
}


maskat.widget.MenuItem.prototype.updateEnabledDiv = function()
{
	try
	{
		if (this.enable)
		{
	    	this.divExt.className = this.baseCSSClassName + "passive" + " " + this.baseCSSClassName + "enabled";		
			if (!this.divLeftDummy)
			{
				this.divLeftActive.src			= this.sIcon;
				this.divLeftPassive.src			= this.sIconPassive;
			}
		}
		else 
		{
	    	this.divExt.className		= this.baseCSSClassName + "passive" + " " + this.baseCSSClassName + "disabled";		
			if (!this.divLeftDummy)
			{
				this.divLeftActive.src			= this.sIconDis;
				this.divLeftPassive.src			= this.sIconDisPassive;
			}
		}
	}
	catch(err)
	{
		alert("Error in MenuItem.updateEnabledDiv " + err.description);
	}
}

maskat.widget.MenuItem.prototype.addAcceleratorStr = function(value)
{
	this.acceleratorDiv.innerHTML		= value;	
}



/**********************************************************
*
*		EVENT HANDLING
*
**********************************************************/
maskat.widget.MenuItem.prototype.makeMouseOverFunc = function (oThis)
{
	return function(e)
	{
		if (oThis.enable)
		{
			if (!oThis.divLeftDummy)
			{
				oThis.divLeftActive.style.display 	= "inline";
				oThis.divLeftPassive.style.display 	= "none";
			}
			
		    this.className = oThis.baseCSSClassName + "focus" + " " + oThis.baseCSSClassName + "enabled";
		    
			if (!e)
			{
				e = window.event;
			}
			
			if (oThis.childContainerObj != null)
			{	
			   	oThis.divArrowPassive.style.display = "none";
				oThis.divArrowActive.style.display 	= "inline";	
				
				offsetLeft	= this.offsetWidth - 5 + oThis.parentContainerObj.divExt.offsetLeft;				
				offsetTop	= this.offsetTop + oThis.parentContainerObj.divExt.offsetTop;
			
				oThis.childContainerObj.showContainer (offsetLeft, offsetTop);
			}
			
			oThis.onmouseover(e);
		}	
	}
}

maskat.widget.MenuItem.prototype.makeMouseOutFunc = function(oThis)
{
	return function(e)
	{
		if (oThis.enable)
		{
			if (maskat.menuUtilsObj.checkIfMouseIsOut(e, this, oThis) == true)
			{
							
				if (oThis.childContainerObj == null)
				{
					if (!oThis.divLeftDummy)
					{
						oThis.divLeftActive.style.display 	= "none";
						oThis.divLeftPassive.style.display 	= "inline";
					}
			    	this.className = oThis.baseCSSClassName + "passive" + " " + oThis.baseCSSClassName + "enabled";					
				}
				else
				{
					oThis.childContainerObj.hideContainer(e);
				}
			}
		}
	}
}

maskat.widget.MenuItem.prototype.makeOnClickFunc = function(oThis)
{
	return function(e)
	{
		if (oThis.childContainerObj == null)
		{
			if (oThis.enable)
			{
				oThis.forceCloseMenu();
				oThis.onclick(e);
				stopEvent(e);	    
			}
		}
		else
		{
			// Do nothing -> could show child popup box
		}
	}
}


/**********************************************************
*
*		REMOVING COMPONENT
*
**********************************************************/
maskat.widget.MenuItem.prototype.release = function()
{
	this.divExt.onmouseover	= null;
	this.divExt.onmouseout	= null;
	this.divExt.onclick		= null;	

	if (this.childContainerObj)
	{
		// true: container calls remove must not remove itself from DOM tree
		//       container will "cut line"
		this.childContainerObj.remove(true);
	}
}

maskat.widget.MenuItem.prototype.setMultiValue = function(mulVal) 
{
	path	= mulVal[0]["PATH"];
	title 	= mulVal[0]["TITLE"];
	enable	= mulVal[0]["ENABLE"];
	visible = mulVal[0]["VISIBLE"];
	checked = mulVal[0]["CHECKED"];
	value	= mulVal[0]["VALUE"];

	str = 	  "path:\t" 	+ path 		+ "\n" 
			+ "enable:\t" 	+ enable 	+ "\n"
			+ "title:\t" 	+ title 	+ "\n"
			+ "visible:\t" 	+ visible 	+ "\n"
			+ "checked:\t" 	+ checked	+ "\n"
			+ "value:\t"	+ value		+ "\n";
			
	if (enable == "true") 
	{	
		this.setEnable(true);
	}
	else if (enable == "false")
	{
		this.setEnable(false);
	}
	
	if (title != null)
	{
		this.setTitle(title);
	}
	
	if (visible == "true")
	{
		this.setVisible(true);
	}
	else if (visible == "false")
	{
		this.setVisible(false);
	}
	
	if (this instanceof maskat.widget.MenuCheckboxItem)
	{
		if (checked == "true")
		{
			this.setChecked(true);
		}
		else if (checked == "false")
		{
			this.setChecked(false)
		}
	}
	
	if (value != null)
	{
		this.setValue(value);
	}
};


MenuItemGetData = {};

MenuItemGetData.menuValue = {};

MenuItemGetData.menuValue.make = function(obj, validator, sourceNode)
{
	if ( (obj == null) || !(obj instanceof maskat.widget.MenuItem))
	{
		throw new MaskatError({name: "menuItemTeleMarker error",
                         message: "obj is not of type <MenuItemGetValue.menuData>",
                         fileName: "MenuItem.js",
                         functionName: "MenuItemGetValue.menuValue.make"});
	}
		
	var valueToSend = obj.getValue(); 
	
	var menuValueXML 	 = "<value>" + valueToSend + "</value>";
	
	var nodeName = maskat.xpath(sourceNode, "@node");
	
	if (nodeName != null)
	{
		return "<" + nodeName + ">" + valueToSend + "</" + nodeName + ">";
	}
	else
	{
		return menuValueXML;
	}
}

ObjWrapper.registerTeleMaker("menuItem.value", MenuItemGetData.menuValue);
ObjWrapper.registerTeleMaker("menuCheckboxItem.value", MenuItemGetData.menuValue);


MenuItemGetData.menuData = {};

MenuItemGetData.menuData.make = function (obj, validator, sourceNode)
{
	if ( (obj == null) || !(obj instanceof maskat.widget.MenuItem)  || !(obj instanceof maskat.widget.MenuItem))
	{
		throw new MaskatError({name: "menuDataTeleMarker error",
                        message: "obj is not of type <MenuItemGetData.menuData>",
                        fileName: "MenuItem.js",
                        functionName: "MenuItemGetData.menuData.make"});

	}

	var path 		= obj.getPath();
	var visible 	= obj.isVisible();
	var enable		= obj.isEnable();
	var title 		= obj.getTitle();
	var checked 	= "";
	
	if (obj instanceof maskat.widget.MenuCheckboxItem)
	{
	 	checked		= obj.getChecked();
	}
	
	var value		= obj.getValue();

	var menuDataXML	=	"<path>" 		+ path 		+ "</path>" 	+ 
						"<enable>"		+ enable   + "</enable>" 	+
						"<title>" 		+ title 	+ "</title>" 	+
						"<visible>" 	+ visible 	+ "</visible>"  +
						"<checked>"		+ checked	+ "</checked>"	+
						"<value>"		+ value		+ "</value>";

	var nodeName = maskat.xpath(sourceNode, "@node");
	
	if (nodeName != null)
	{
		return "<" + nodeName + ">" + menuDataXML + "</" + nodeName + ">";
	}
	else
	{	
		return menuDataXML;
	}
}

ObjWrapper.registerTeleMaker("menuItem.data", MenuItemGetData.menuData);
ObjWrapper.registerTeleMaker("menuCheckboxItem.data", MenuItemGetData.menuData);

/**********************************************
***********************************************
*
*			MENU CHECKBOX ITEM
*
*
**********************************************/
maskat.widget.MenuCheckboxItem = function (parentContainerObj, title, objPar)
{
	if (!objPar)
	{
    	var objPar={};
    	objPar.name="menuCheckBoxItem";
	}
	  
	objPar.type	= "maskat.widget.MenuCheckboxItem";
	
	this.base 	= maskat.widget.MenuItem;  
    this.base(parentContainerObj, title, objPar);
    
	this.checkFunc				= "";
   	this.checked				= true;
   	
   	if(rialto.lang.isBoolean(objPar.checked))
	{
		this.checked		= objPar.checked;
	}
	
	if(rialto.lang.isString(objPar.checkFunc))
	{
		this.checkFunc = objPar.checkFunc;
	}
	
	//release object	
	objPar=null;
	this.base=null;
	
/*	this.updateCheckedDiv();*/
}

maskat.widget.MenuCheckboxItem.prototype = new maskat.widget.MenuItem;

maskat.widget.MenuCheckboxItem.prototype.runCheckMethod = function(oThis)
{
	if (oThis.checkFunc != "")
	{
		returnValue = eval(oThis.checkFunc + "()");
		if (returnValue == true)
		{
			oThis.checked = !oThis.checked;
		}
		else
		{	
			// Do nothing
		}
	}
	else
	{
		oThis.checked = !oThis.checked;
	}
	oThis.updateCheckedDiv();
}

maskat.widget.MenuCheckboxItem.prototype.setChecked = function(checked)
{
	this.checked = checked;
	this.updateCheckedDiv();
}

maskat.widget.MenuCheckboxItem.prototype.getChecked = function()
{
	return this.checked;
}

maskat.widget.MenuCheckboxItem.prototype.isChecked = function()
{
	return this.checked;
}



maskat.widget.MenuCheckboxItem.prototype.showItem = function()
{
	if (this.visible == true)
	{
		this.divExt.style.display = "block";
		
		/* needed to set CSS class */
		this.updateEnabledDiv();
		this.updateCheckedDiv();
		
		if (!this.divLeftDummy)
		{
			this.divLeftActive.style.display 	= "none";
			this.divLeftPassive.style.display 	= "inline";
		}
	}
	else 
	{
		this.divExt.style.display = "none";
	}
}

maskat.widget.MenuCheckboxItem.prototype.updateCheckedDiv = function()
{
 	try
 	{
		if (this.checked == true)
		{
			this.divLeftActive.src	= this.sIcon;
			this.divLeftPassive.src	= this.sIconPassive;
		}
		else
		{
			this.divLeftActive.src	= this.sIconDis;
			this.divLeftPassive.src	= this.sIconDisPassive;			
		}
	}
	catch (err)
	{
		alert("Error in MenuCheckboxItem.updateCheckedDiv " + err.description);
	}
}


maskat.widget.MenuCheckboxItem.prototype.makeOnClickFunc = function(oThis)
{
	return function(e)
	{
		if (oThis.childContainerObj == null)
		{
			oThis.runCheckMethod(oThis);
			
			oThis.forceCloseMenu();
			oThis.onclick(e);
			stopEvent(e);	    
		}
		else
		{
			// Do nothing -> could show child popup box
		}
	}
}


/**********************************************
***********************************************
*
*			SEPERATOR
*
*
**********************************************/
maskat.widget.MenuSeparator = function()
{
	this.baseCSSClassName	= "maskat_widget_menu_seperator_"
	
	this.sizeSet = true;
	
	this.domNode = document.createElement("DIV");
	
	this.domNode.className = this.baseCSSClassName + "container";
	
	this.domNodeLeft 				= document.createElement("DIV");
	this.domNodeLeft.className 		= this.baseCSSClassName + "left";
	
	this.domNodeCenter 				= document.createElement("DIV");
	this.domNodeCenter.className 	= this.baseCSSClassName + "center";
	
	this.domNodeRight 				= document.createElement("DIV");
	this.domNodeRight.className 	= this.baseCSSClassName + "right";

	this.domNode.appendChild(this.domNodeLeft);	
	this.domNode.appendChild(this.domNodeCenter);
	this.domNode.appendChild(this.domNodeRight);

	this.adjustCenter = function()
	{
		leftWidth 	= this.domNodeLeft.offsetWidth;
		
		this.domNodeCenter.style.width = "100%";
		centerWidth = this.domNodeCenter.offsetWidth;
		
		rightWidth 	= this.domNodeRight.offsetWidth;

		this.domNodeCenter.style.width = centerWidth - (leftWidth + rightWidth);
	}
}



/**********************************************
***********************************************
*
*		    MASKAT EXTENSION: LAYOUT XML CODE 
*
*
**********************************************/
maskat.transMenuBarTag = function(pathObjArray, domElem)
{
	var output = "";
	var attr   = {};
	
	maskat.receiveAttributes(domElem, attr);
	
	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.MenuBar("
						+	maskat.composeSingleParam(domElem, attr, "parent")	+ ", "
						+ 	strObjPar + ");\n";
	
	output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
	
	if (domElem.hasChildNodes())
	{
	  var mainMenuObj = new maskat.MenuBarClass(attr.name, attr.parent);
	  pathObjArray.push(mainMenuObj);
	
	  output += maskat.transChildNodes(pathObjArray, domElem);
	}
		
	return output;
}

maskat.MenuBarClass = function (name, parentRefName)
{
	this.name 			= name;
	this.parentRefName	= parentRefName;
}

maskat.MenuBarClass.prototype.isContainer = false;

maskat.MenuBarClass.prototype.getRefObj = function()
{ 
	return this.name; 
}
maskat.MenuBarClass.prototype.getParentRefObj = function()
{
	return this.parentRefName;
}


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

	maskat.receiveAttributes(domElem, attr);
	
	var menuClassObj;
	
	for (var i = pathObjArray.length - 1; i >= 0; i--)
	{
	  if (pathObjArray[i] instanceof maskat.MenuBarClass)
	  {
	    menuClassObj = pathObjArray[i];
	    break;
	  }
	}	

	if (menuClassObj == undefined)
	{
    	throw new MaskatError({
    						name: "layoutXML Syntax Error",
                           message: "menuEntry(name:'" + attr.name +"')の親要素としてmenuEntry要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transMenuEntryTag"});
  	}
  	
  	var refObjName = menuClassObj.getRefObj();
  	
  	var strObjPar = maskat.composeParam(domElem, attr);
  	
  	attr["parent"] = refObjName;
  	
  	output += attr.name +	" = new maskat.widget.MenuEntry("
  						+	maskat.composeSingleParam(domElem, attr, "parent") + ", " 
  						+	maskat.composeSingleParam(domElem, attr, "caption")	+ ", "
  						+   strObjPar + ");\n";

	output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
	
	if (domElem.hasChildNodes())
	{
	   var menuEntryObj = new maskat.MenuEntryClass(attr.name);

	   pathObjArray.push(menuEntryObj);

	   output += maskat.transChildNodes(pathObjArray, domElem);
	}

	return output;
}

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


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

	maskat.receiveAttributes(domElem, attr);
	
	var menuEntryClassObj;
	
	var menuBarClassObj;
	
	for (var i = pathObjArray.length - 1; i >= 0; i--)
	{
	  if (pathObjArray[i] instanceof maskat.MenuBarClass)
	  {
	    menuBarClassObj = pathObjArray[i];
	    break;
	  }
	}	
	
	for (var i = pathObjArray.length - 1; i >= 0; i--)
	{
	  if (pathObjArray[i] instanceof maskat.MenuEntryClass || pathObjArray[i] instanceof maskat.MenuItemClass)
	  {
	    menuEntryClassObj = pathObjArray[i];
	    break;
	  } 
	}
		
	if (menuEntryClassObj == undefined || menuBarClassObj == undefined)
	{
    	throw new MaskatError({
    			           name: "layoutXML Syntax Error",
                           message: "menuPopup(name:'" + attr.name +"')の親要素としてmenuPopup要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transMenuPopupTag"});
  	}

  	var parentDivRefObjName		= menuBarClassObj.getParentRefObj(); 	
  	var parentEntryRefObjName	= menuEntryClassObj.getRefObj();
  	
    var strObjPar = maskat.composeParam(domElem, attr);
    
    attr["parent"] 			= parentDivRefObjName;
    attr["parentEntry"] 	= parentEntryRefObjName;

    output += attr.name +	" = new maskat.widget.MenuPopup("
  						+	maskat.composeSingleParam(domElem, attr, "parentEntry")	+ ", "
  						+	maskat.composeSingleParam(domElem, attr, "parent")	+ ", "  						
  						+   strObjPar + ");\n";
  						
	output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
		
  	if (domElem.hasChildNodes())
	{
	   var containerObj = new maskat.MenuPopupClass(attr.name);
	   pathObjArray.push(containerObj);
	   
	   output += maskat.transChildNodes(pathObjArray, domElem);
	}
	
	return output;
}

maskat.MenuPopupClass = function (name)
{
	this.name = name;
}

maskat.MenuPopupClass.prototype.isContainer = true;

maskat.MenuPopupClass.prototype.getRefObj = function()
{ 
	return this.name;
}


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

	maskat.receiveAttributes(domElem, attr);
	
	var containerClassObj;
	
	for (var i = pathObjArray.length - 1; i >= 0; i--)
	{
	  if (pathObjArray[i] instanceof maskat.MenuPopupClass)
	  {
	    containerClassObj = pathObjArray[i];
	    break;
	  }
	}	

	if (containerClassObj == undefined)
	{
    	throw new MaskatError({
    					   name: "layoutXML Syntax Error",
                           message: "menuItem(name:'" + attr.name +"')の親要素としてmenuItem要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transMenuItemTag"});
  	}
  	
  	var refObjName = containerClassObj.getRefObj();
  	
  	var strObjPar = maskat.composeParam(domElem, attr);
  	
  	attr["parent"] = refObjName;

  	output += attr.name +	" = new maskat.widget.MenuItem("
  						+	maskat.composeSingleParam(domElem, attr, "parent") + ", " 
  						+	maskat.composeSingleParam(domElem, attr, "caption")	+ ", "
  						+   strObjPar + ");\n";
  						
	output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
	
	if (domElem.hasChildNodes())
	{
	   var menuItemClassObj = new maskat.MenuItemClass(attr.name);
	   pathObjArray.push(menuItemClassObj);
	   
	   output += maskat.transChildNodes(pathObjArray, domElem);
	}
	
	return output;
}

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

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

	maskat.receiveAttributes(domElem, attr);
	
	var containerClassObj;
	
	for (var i = pathObjArray.length - 1; i >= 0; i--)
	{
	  if (pathObjArray[i] instanceof maskat.MenuPopupClass)
	  {
	    containerClassObj = pathObjArray[i];
	    break;
	  }
	}	

	if (containerClassObj == undefined)
	{
    	throw new MaskatError({
    					   name: "layoutXML Syntax Error",
                           message: "menuCheckboxItem(name:'" + attr.name +"')の親要素としてmenuCheckboxItem要素がありません。",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transMenuCheckboxItemTag"});
  	}
  	
  	var refObjName = containerClassObj.getRefObj();
  	
  	var strObjPar = maskat.composeParam(domElem, attr);
  	
  	attr["parent"] = refObjName;

  	output += attr.name +	" = new maskat.widget.MenuCheckboxItem("
  						+	maskat.composeSingleParam(domElem, attr, "parent") + ", " 
  						+	maskat.composeSingleParam(domElem, attr, "caption")	+ ", "
  						+   strObjPar + ");\n";
		
	output += "layoutObj.components[\""+attr.name + "\"]="+attr.name+";\n";
	
	return output;
}

maskat.MenuCheckboxItemClass = function (name)
{
	this.name = name;
}

maskat.MenuCheckboxItemClass.prototype.isContainer = false;
maskat.MenuCheckboxItemClass.prototype.getRefObj = function()
{ 
	return this.name;
}

maskat.transMenuSeparatorTag = function(pathObjArray, domElem)
{
	var output = "";
	var attr = {};
	
	maskat.receiveAttributes(domElem, attr);
	
	var conObj;
	
	for (var i = pathObjArray.length - 1; i >= 0; i--)
	{
		conObj = pathObjArray[i];
		if (conObj instanceof maskat.MenuPopupClass)
		{
			break;
		}
	}
	
	if (conObj == undefined)
	{
    	throw new MaskatError({
    						name: "layoutXML Syntax Error",
                           message: "menuSeperator(name:'" + attr.name +"')a?Re|ae|?c´?a?¨a??a?|seperatore|?c´?a??a??a??a??a??a??a?",
                           fileName: "layoutXMLInterpreter.js",
                           functionName: "maskat.transSeperatorTag"});
	}
	
	var refObjName	= conObj.getRefObj();
	
	var strObjPar 	= maskat.composeParam(domElem, attr);
	
	attr["parent"]	= refObjName;
	
	output += attr.name + " = " + attr["parent"] + ".addSeperator();\n"
	
    output += "layoutObj.components[\"" + attr.name + "\"]=" + attr.name + ";\n";
	
	return output;
}

maskat.syntax.menuBar = 
{
  	name:	{type: "string", req: true},
  	parent: {type: "object"}
};
  
maskat.syntax.menuEntry =
{
	name:		{type: "string", req: true},
	caption: 	{type: "string", req: true},
	parent:		{type: "object"},
    enable:		{type: "boolean"},    
    visible:  	{type: "boolean"},
	value:		{type: "string"}
};
  
maskat.syntax.menuPopup =
{
	name:			{type: "string", req: true},
	parent: 		{type: "object"},
	parentEntry:	{type: "object"},
	width: 			{type: "string"}
};
  
maskat.syntax.menuItem =
{
	name:    		{type: "string", req: true},
	caption:		{type: "string", req: true},
	parent:  		{type: "object"},
    enable:			{type: "boolean"},
    visible:  		{type: "boolean"},
	value:			{type: "string"},
	sIcon:			{type: "string"},
	sIconDisabled:	{type: "string"}
};

maskat.syntax.menuCheckboxItem =
{
	name:    		{type: "string", req: true},
	caption:		{type: "string", req: true},
	parent:  		{type: "object"},
    visible:  		{type: "boolean"},
	value:			{type: "string"},
	checked:		{type: "boolean"},
	checkFunc:		{type: "string"},
	sIcon:			{type: "string"},
	sIconDisabled:	{type: "string"}
};

maskat.syntax.menuSeparator = 
{
	name: {type: "string", req: true}
};

/**********************************************
***********************************************
*
*			KEY VECTOR
*
*
**********************************************/
maskat.widget.KeyVector	= function ()
{
	this.keys	= new Array();
	this.size	= 0;
}

maskat.widget.KeyVector.prototype.getSize = function()
{
	return this.size;
}

maskat.widget.KeyVector.prototype.addKey = function (newKey)
{
	var index = -1;
	if (this.indexOf(newKey) == -1)
	{
		this.keys.push(newKey);
		
		this.size 	= this.keys.length;
		index 		= this.keys.length;
	}

	return index;
}

maskat.widget.KeyVector.prototype.empty = function()
{
	while (this.keys.pop() != null)
	{
		// Do Nothing
	}
	
	this.size = this.keys.length;
}

maskat.widget.KeyVector.prototype.removeKey = function (key)
{
	var tmp = new Array();
	var e	= null;
	
	for (var i = 0; i < this.keys.length; i++)
	{
		if (this.keys[i] != key)
		{
			tmp.push(this.keys[i]);
		}
		else
		{
			e = key;
		}
	}
	
	this.keys = tmp;
	this.size = this.keys.length;
	
	return e;
}

maskat.widget.KeyVector.prototype.indexOf = function(key)
{
	for (var i = 0; i < this.keys.length; i++)
	{
		if (this.keys[i] == key)
		{
			return i;
		}
	}
	
	return -1;
}

maskat.widget.KeyVector.prototype.contains = function(key)
{
	for (var i = 0; i < this.keys.length; i++)
	{
		if (this.keys[i] == key)
		{
			return true;
		}
	}

	return false;
}

/**********************************************
***********************************************
*
*			KEY LOGGER
*
*
**********************************************/
maskat.widget.KeyLogger = function()
{
	this.type 		= "maskat.widget.KeyLogger";
	
	this.hasRunInit = false;
	
	this.keyObjMap 			= new Array();
	this.pressedKeysVector 	= new maskat.widget.KeyVector();
	
	this.oldOnKeyDown 	= function () {};
	this.oldOnKeyUp	 	= function () {};
	
	oThis = this;
}

maskat.keyLoggerObj = new maskat.widget.KeyLogger();


maskat.widget.KeyLogger.prototype.getHasRunInit = function()
{
	return this.hasRunInit;
}


maskat.widget.KeyLogger.prototype.upDateMenu = function(eventName, keyObj)
{
	var compStr 	= keyObj.getComponentAsStr();
	
	var accStr 		= keyObj.getAcceleratorAsString();
	
	eval
	(
		"if (" + compStr + ".type == \"maskat.widget.MenuItem\")" +
		"{" +
			compStr + ".addAcceleratorStr(\"" + accStr + "\");" +
		"}" +
		"else" +
		"{" +
			compStr + ".divExt.title += \" (\" + \"" + accStr + "\" + \")\";" +
		"}"
	);
}

maskat.widget.KeyLogger.prototype.KeyCode2Key = function (keyCode)
{
	key = "";
	keyLetter = "";
	
	/* [a..z], [A..Z]   upper/lower case will not be distinguished */
	if (keyCode > 64 && keyCode < 91)
   	{
		keyLetter = String.fromCharCode(keyCode);
   	}
	// [0, 1..9]
   	else if (keyCode > 47 && keyCode < 58)
   	{
		keyLetter = String.fromCharCode(keyCode);
   	}
   	else
   	{
   		mapCode = "kc_" + keyCode;

   		if (maskat.widget.KeyLogger.Code2KeyMap[mapCode] != undefined)
   		{
   			keyLetter = maskat.widget.KeyLogger.Code2KeyMap[mapCode];
   		}
   	}
   	
   	return keyLetter;
}

maskat.widget.KeyLogger.prototype.makeOnKeyDownFunc = function (oThis)
{	
	return function (e)
	{
      	oThis.oldOnKeyDown(e);

    	var event		= window.event ? window.event : e;
    	var keyCode 	= event.keyCode;
    	
    	var keyLetter	= "";
    	 	
    	keyLetter = oThis.KeyCode2Key(keyCode);
    	
    	if (keyLetter != "")
    	{
	 	  	if (oThis.pressedKeysVector.indexOf(keyLetter) == -1)
	    	{
	    		oThis.pressedKeysVector.addKey(keyLetter);
	    	}
	    	else 
	    	{
	    		// Do nothing: key already stored
	    	}

	    	for (var i = 0; i < oThis.keyObjMap.length; i++)
	    	{
	    		var tmpKeyObj = oThis.keyObjMap[i];
	    		
	    		if (tmpKeyObj.checkIfComponentIsDeleted())
	    		{
	    			tmpKeyObj.removeFromKeyLogger();
	    		}
	    		else
	    		{
		    		if(tmpKeyObj.checkKeysPressed(event, oThis.pressedKeysVector))
					{
										
						oThis.pressedKeysVector.empty();
						tmpKeyObj.callEvent();
					}
				}
				
	    		/*
	    		var tmpStr = "";
	    		
	    		for (var j = 0; j < tmpKeyObj.metaKeysArray.length; j++)
	    		{
					tmpStr += tmpKeyObj.metaKeysArray[j] + " + ";
	    		}
	    		
	    		tmpStr += tmpKeyObj.key;
	    		*/
	    		
	    	}
	    	
		}
	}
}

maskat.widget.KeyLogger.prototype.makeOnKeyUpFunc = function (oThis)
{
	return function(e)
	{
      	oThis.oldOnKeyUp(e);
      	
      	var keyLetter = "";
      	
    	var event = window.event ? window.event : e;
    
    	keyLetter = oThis.KeyCode2Key(event.keyCode);
    	
    	oThis.pressedKeysVector.removeKey(keyLetter);
	}
}

maskat.widget.KeyLogger.prototype.initKeyLogging = function()
{
	if (document.onkeydown)
    {
    	this.oldOnKeyDown = document.onkeydown;
    }       
    document.onkeydown = this.makeOnKeyDownFunc(this);
    
    if (document.onkeyup)
    {
    	this.oldOnKeyUp = document.onkeyup;
    }
    document.onkeyup = this.makeOnKeyUpFunc(this);
    
   	this.hasRunInit = true;
}

maskat.widget.KeyLogger.Code2KeyMap = 
{
	kc_16: "SHIFT",
	kc_17: "CTRL",
	kc_18: "ALT"
/*	kc_112: "F1"....*/
};

maskat.widget.KeyLogger.prototype.connectEventKeyFunc = function(IDs, key, metaKey)
{
	var keyObj = new maskat.widget.KeyLogger.KeyObject(	key, 
														metaKey, 
														IDs.component, 
														IDs.event);
	
	this.keyObjMap.push(keyObj);
	
	this.upDateMenu(IDs.event, keyObj);
}

maskat.widget.KeyLogger.prototype.keyToString = function(event, eventName)
{
	var str =	eventName + ": ######################### \n" +
				"Key:\t\t"			+ String.fromCharCode(event.keyCode) + "\n" + 
				"Keycode:\t"		+ event.keyCode 	+ "\n" +
			  	"Charcode:\t" 		+ event.charCode	+ "\n" +
    		  	"Which:\t\t"		+ event.which		+ "\n" +
    		  	"event.altKey:\t"	+ event.altKey		+ "\n" +
    		  	"event.ctrlKey:\t"	+ event.ctrlKey		+ "\n" +
    		  	"event.shiftKey:\t"	+ event.shiftKey    + "\n" +
    		  	"Alt: " 			+ event.altKey 		+ " / "  + 
    		  	"Ctrl: " 			+ event.ctrlKey 	+ " / " + 
    		  	"Shift: " 			+ event.shiftKey;
    		  	
   return str;
}

maskat.widget.KeyLogger.prototype.removeZombies = function()
{
	var tmpArray = new Array();
	
	for (var i = this.keyObjMap.length - 1; i >= 0; i--)
   	{
   		var tmpKeyObj = this.keyObjMap.pop();
   		
   		if (tmpKeyObj.checkIfComponentIsDeleted())
   		{
   			tmpKeyObj.removeFromKeyLogger();
   		}
   		else
   		{
   			tmpArray.push(tmpKeyObj)
   		}
   	}
   	
   	this.keyObjMap = tmpArray;
}

maskat.widget.KeyLogger.prototype.removeKeyObj = function(keyObj)
{
	for (prop in keyObj)
	{
     	prop = null;
    }	
        
    delete keyObj
}

maskat.widget.KeyLogger.KeyObject = function (key, metaKeys, componentStr, eventStr)
{
	this.key			= null;
	
	this.checkAlt		= false;
	this.checkCtrl		= false;
	this.checkShift		= false;
	
	/* needed to update menu caption */
	this.metaKeysArray	= new Array();
	
	this.component  	= componentStr;
	this.method			= eventStr;
		
	if (key)
	{
		this.key 		= key.toUpperCase();
	}

	if (metaKeys)
	{
		var tmpArray	= new Array();
		var tempStr 	= "";
		
		// deleted spaces
		tempStr = metaKeys.replace(/\ /g, "");		
		
		// split string 		
		tmpArray = tempStr.split("|");
	
		for (var i = 0; i < tmpArray.length; i++)
		{
			tmpArray[i]	= tmpArray[i].toUpperCase();
			if (tmpArray[i] == "SHIFT")
			{
				this.checkShift = true;
			}
			else if (tmpArray[i] == "CTRL")
			{
				this.checkCtrl = true;
			}
			else if (tmpArray[i] == "ALT")
			{
				this.checkAlt = true;
			}
		}
		
		this.metaKeysArray = this.metaKeysArray.concat(tmpArray);
	}	
}

maskat.widget.KeyLogger.KeyObject.prototype.getAcceleratorAsString = function ()
{
	var tmpStr = "";
	    		
	for (var j = 0; j < this.metaKeysArray.length; j++)
	{
		tmpStr += this.metaKeysArray[j].substring(0, 1) + this.metaKeysArray[j].substring(1).toLowerCase() + "+";
	}
  		
	tmpStr += this.key;
		
	return tmpStr;
} 


maskat.widget.KeyLogger.KeyObject.prototype.checkKeysPressed = function(event, pressedKeysVector)
{
	keyPressed 		= false;
	modKeysPressed	= true; 
	
	keyPressed = pressedKeysVector.contains(this.key)
		
	if (this.checkShift == true && event.shiftKey == false)
	{
		modKeysPressed = false;
	}
		if (this.checkCtrl == true && event.ctrlKey == false)
	{
		modKeysPressed = false;
	}
	if (this.checkAlt == true && event.altKey == false)
	{
		modKeysPressed = false;
	}

	return (keyPressed == true && modKeysPressed == true);
}


maskat.widget.KeyLogger.KeyObject.prototype.callEvent = function()
{
	eval
	(
		"if (" + this.component + ".isVisible() && " + 
			     this.component + ".isEnable())" +
		"{" +
			this.component + "." + this.method + "();" + 
		"}"
	);
}

maskat.widget.KeyLogger.KeyObject.prototype.checkIfComponentIsDeleted = function()
{
	var tempComponent = eval(this.component);

	if (tempComponent.name == null) 
	{
		return true;
	}
	else
	{
		return false;
	}
}

maskat.widget.KeyLogger.KeyObject.prototype.removeFromKeyLogger = function ()
{
	return maskat.keyLoggerObj.removeKeyObj(this);
} 

maskat.widget.KeyLogger.KeyObject.prototype.getComponentAsStr = function ()
{
	return this.component;
} 

/**********************************************
***********************************************
*
*			MENU UTILS
*
*
**********************************************/
maskat.widget.MenuUtils = function(){};

maskat.menuUtilsObj = new maskat.widget.MenuUtils();

maskat.widget.MenuUtils.prototype.getMouseCoordinates = function(e, node, oThis)
{
	var offsetIE = 0;
	var	offsetO  = 0;
	var	offsetFF = 0;
		
	if (oThis.type == "maskat.widget.MenuPopup")
	{
		offsetIE = -2;
		// O reoprts correct values. To test against >=top the mouse pointer needs to be moved 1 down!		
		offsetO  = 1;
		offsetFF = 0;
	} 
	else if (oThis.type == "maskat.widget.MenuItem")
	{
		offsetIE = -3;
		offsetO  = 1;
		offsetFF = -1;		
	}
	// O
	if (window.opera)  
	{						
		mouseX 	= e.clientX + offsetO;
		mouseY 	= e.clientY + offsetO;
	}
	// IE	
	else if (window.event) 
	{
		mouseX 	= window.event.clientX + offsetIE;
		mouseY 	= window.event.clientY + offsetIE;				
	}
	// FF
	else 
	{
		mouseX 	= e.clientX + offsetFF;
		mouseY 	= e.clientY + offsetFF;
	}
	
	return [mouseX, mouseY];
}

// TODO: Refactor!
maskat.widget.MenuUtils.prototype.checkIfMouseIsOut = function(e, node, oThis)
{
	mouseCoords = maskat.menuUtilsObj.getMouseCoordinates(e, node, oThis);
	
	mouseX = mouseCoords[0];
	mouseY = mouseCoords[1];


	nodePosition 	= this.getNodePosition(node);	

	leftXPos 		= nodePosition[0];
	topYPos  		= nodePosition[1];
	rightXPos		= leftXPos	+ node.offsetWidth;
	bottomYPos  	= topYPos 	+ node.offsetHeight;

/*			
 debug("MO(CO): " + oThis.name + " \n\t" + 
 	leftXPos 	+ " >= " + mouseX + " >= " + rightXPos + " / \n\t" + 
 	bottomYPos 	+ " <= " + mouseY + " <= " + topYPos);
*/
 /* In theory, the popup closes 1 pixel bevore mouse pointer is out
 		 <=top
 		-------
 		|     |
 <=left	|     | >=right
 		|     | 	
 		-------
 	    >=bottom
 */	    				
	if(mouseX <= leftXPos || mouseX >= rightXPos || mouseY <= topYPos || mouseY >= bottomYPos)
	{
		return true;
	}
	else
	{
		return false;
	}
}

/**
*	From www.quirksmode.org
*/
maskat.widget.MenuUtils.prototype.getNodePosition = function(node)
{
	var curleft = curtop = borderWidth = 0;
	
	curleft	= node.offsetLeft
	curtop	= node.offsetTop
	
	if (node.offsetParent) 
	{
		while (node = node.offsetParent) 
		{
			curleft += node.offsetLeft
			curtop	+= node.offsetTop
		}
	}
	return [curleft, curtop, borderWidth];
}

maskat.widget.MenuUtils.prototype.getPasFileName = function(fileName)
{
	var sLenght 	= fileName.length;
	var fileBegin	= fileName.substr(0, sLenght - 4);
	var fileEnd		= fileName.substring(sLenght - 4);
	
	return fileBegin + "Passive" + fileEnd;
}


line = 0; 
function debug(text)
{
	debugText.setValue(line++ + ": " + text + "\n" + debugText.getValue().substr(0, 7000));
}




/**
 * スクリーン
 */
if (typeof maskat == "undefined"){
	maskat={};
}
if (typeof maskat.widget == "undefined"){
    maskat.widget={};
}
if (typeof maskat.syntax == "undefined"){
	maskat.syntax={};
}

maskat.widget.Window = function(objPar){
    objPar.boolMaxi = false;
    this.canMin = false;
    if (rialto.lang.isBoolean(objPar.canMin)){
        this.canMin = objPar.canMin;
    }
    this.title="screen";
    if (rialto.lang.isString(objPar.title)){
        this.title = objPar.title;
    }
    objPar.dynamic = true;
    objPar.open = true;
    this.frame = new rialto.widget.Frame(objPar);
    if (this.frame.bMAX) {
        this.frame.bMAX.setVisible(false);
	}    
    if (this.canMin == false){
        this.frame.BTN.setVisible(false);
    }

    this.statusDiv = document.createElement("div");
    this.statusDiv.style.position="absolute";
    this.statusDiv.style.left=0;
    this.statusDiv.style.width="100%";
    this.statusDiv.style.height=23;
    this.frame.divExt.appendChild(this.statusDiv);
    if (rialto.lang.isString(objPar.statusClassName) && rialto.string.trim(objPar.statusClassName) != ""){
        this.statusClassName = objPar.statusClassName;
        this.statusDiv.className=this.statusClassName;
    }else{
        this.statusDiv.className="window_message";
    }

    var oThis = this;
    this.frame.toolBar.ondbleclick=function(){
        if (oThis.canMin){
            oThis.frame.setDisplay(!oThis.frame.open);
            if (oThis.frame.open) {
                oThis.statusDiv.style.display = "block";
            } else {
                oThis.statusDiv.style.display = "none";
			}
	    }
    }
    if (this.frame.BTN!=null){
        this.frame.BTN.onclick=function(){
            oThis.frame.setDisplay(!oThis.frame.open);
            if (oThis.frame.open) {
	            oThis.statusDiv.style.display = "block";
	        } else {
	            oThis.statusDiv.style.display = "none";
	        }
        }
    }
    if (this.frame.labelTitle!=null){
        this.frame.labelTitle.divExt.style.display="none";
    }
    this.titleDiv = document.createElement("div");
    this.titleDiv.className = "window_title";
    this.titleDiv.innerHTML=this.title;
    this.frame.toolBar.divExt.appendChild(this.titleDiv);

    this.msgs = new Array();
    this.msgIdx = 0;
    this.statusDiv.onclick = function(e){
        oThis.msgIdx++;
        oThis.showCurrentMsg();
    }
}

maskat.widget.Window.prototype = new rialto.widget.AbstractContainer;

maskat.widget.Window.prototype.getHtmlCont=function(){
    return this.frame.getHtmlCont();
}

maskat.widget.Window.prototype.placeIn=function(par){
    this.frame.placeIn(par);
}

maskat.widget.Window.prototype.setMsg=function(msg){
    if (typeof msg == "string") {
        this.msgs = new Array(msg);
        this.msgIdx = 0;
    }
    if (msg instanceof Array) {
        this.msgs = msg;
        this.msgIdx = 0;
    }
    this.showCurrentMsg();
}

maskat.widget.Window.prototype.showCurrentMsg = function(){
    var msgToShow = "";
    if (this.msgs.length != 0){
		if (this.msgIdx > this.msgs.length - 1 || this.msgIdx < 0){
		    this.msgIdx = 0;
		}
		msgToShow = this.msgs[this.msgIdx];
    }
    this.statusDiv.innerHTML=msgToShow;
}

maskat.widget.Window.prototype.setTitle=function(msg){
    this.titleDiv.innerHTML=msg;
}

maskat.widget.Window.prototype.remove=function(){
    this.frame.remove();
    this.titleDiv.onclick=null;
}

maskat.syntax["screen"]= {
    name: {type: "string"},
    top: {type: "number"},
    left: {type: "number"},
    width: {type: "number"},
    height: {type: "number"},
    title: {type: "string"},
    draggable: {type:"boolean"},
    canMin: {type:"boolean"},
    statusClassName: {type: "string"},
    parent: {type: "object"}
  };

maskat.transScreenTag = function(pathObjArray, domElem){
  var attr = {};

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

  //// 前変換

  // pathObjArrayの要素を降順に走査し、isContainerプロパティがtrue
  // のオブジェクトのgetRefObjメソッドの戻り値を取得する
  var refObjName=null;
  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);

  var output = attr.name + " = new maskat.widget.Window(" + strObjPar + ");\n";
  output += "layoutObj.components[\"" + attr.name + "\"]="+attr.name+";\n";
  
  //// 子供の処理
  if (domElem.hasChildNodes()){
    // 自タグのオブジェクトを作成
    var popupObj = new maskat.ScreenClass(attr.name);
    pathObjArray.push(popupObj);

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

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

maskat.validationErrorHandler=function(errors){
    var windows = new Array();
    var messagesOfWindows = new Array();
	for (var i=0;i<errors.length;i++){
		var error = errors[i];
		var obj = maskat.getObjByName(error.vTarget.objName);
		var windowParent = maskat.findParentWindow(obj);
		if (windowParent!=null){
			var idx;
			var messages;
			for (idx=0;idx<windows.length;idx++){
				if (windows[idx]==windowParent){
				    messages = messagesOfWindows[idx];
				    break;
				}
			}
			if (idx==windows.length){
			    windows[idx] = windowParent;
			    messages = messagesOfWindows[idx] = new Array();
			}
			//臨時保存
			messages[messages.length] = "<span style='color:red'>" + error.vTarget.desc+ ":" + error.message + "</span>";
		}else{
		    //ウィンドウの子部品ではない場合は、alertでエラーメッセージ表示
            alert(error.vTarget.desc+ ":" + error.message);
        }
	}
	for (var i=0;i<windows.length;i++){
		//windowParentにエラー表示
	    windows[i].setMsg(messagesOfWindows[i]);
	}
}

/**
 * maskatObjの親コンポーネントから一階層ずつ上に行って、maskat.widget.Windowの親コンポーネントを探し
 * 見つからなければ、nullを返す
 */
maskat.findParentWindow = function(maskatObj, limit){
    if (typeof limit != "number") {
		//デフォルトは最大10回
        limit = 10; 
	}
    if (limit == 0) {
        return null;
	}
    if (maskatObj != null){
        if (!maskatObj.inParent){
            if (maskatObj.oRia != null){
                return maskat.findParentWindow(maskatObj.oRia, limit - 1);
            } else
                return null;
        }
        if (maskatObj.inParent instanceof maskat.widget.Window){
            return maskatObj.inParent;
        }
        return maskat.findParentWindow(maskatObj.inParent, limit - 1);
    }
    return null;
}



