
includeJS("common", "UTF-8"); // using common.js
includeJS("alertitems", "UTF-8"); // using alertitems.js

function xmlhttpParse(xmlhttp)
{
  if(xmlhttp.responseXML
  && xmlhttp.responseXML.documentElement)
    return xmlhttp.responseXML;
  return xmldomParseString(xmlhttp.responseText, true);
}

function xmlhttpReplaceElement(dst, src)
{
  if(dst.outerHTML && src.xml)
    dst.outerHTML = src.xml; // IE Only.
  else
  {
    if(navigator.userAgent.indexOf("AppleWebKit/") >= 0) // Safari, ...
      dst.outerHTML = src.outerHTML;
    else
      dst.parentNode.replaceChild(src, dst);
  }
  domutil.replaceStatus = "normal";
}

function xmldomParseString(str)
{
  var type = { "function":true, "object":true };
  if(type[ typeof DOMParser ])
  {
    if(!domutil.parser)
      domutil.parser = new DOMParser();
    return domutil.parser.parseFromString(str, "text/xml");
  }
  
  // Remove DOCTYPE
  var reg = /^([\S\s]*)<!DOCTYPE\s+\S+\s+(\[[\S\s]*\]\s*|[^>]+)>([\S\s]*)$/;
  if(str.match(reg))
    str = RegExp.$1 + RegExp.$3;
  
  if(domutil.msxml)
    return domutil.msxml.createDocument(str);
  
  var pids = 
  {
    "Msxml2.DOMDocument.2.5" : false,
    "Msxml2.DOMDocument.2.0" : false,
    "Msxml2.DOMDocument" : true
    // "Microsoft.XMLDOM" : false
  };
  var xmldom, isXPath;
  
  for(var i in pids)
  {
    try
    {
      xmldom = new ActiveXObject(i);
      isXPath = pids[i];
      break;
    }catch(e){ xmldom = undefined; }
  }
  if(!xmldom)
    return;
  
  if(isXPath)
    xmldom.setProperty("SelectionLanguage", "XPath");
  xmldom.async = false;
  domutil.msxml = 
  {
    domDocument : xmldom,
    isXPath : isXPath,
    createDocument : function(str)
    {
      this.domDocument.loadXML(str);
      function msdomObject(msxml)
      {
        this.msxmldom = msxml.domDocument;
        this.getElementById = function(id){ return this.msxmldom.selectSingleNode("//*[@id='" + id + "']"); };
        if(msxml.isXPath)
        { // XPath
          this.getElementsByTagName   = function(    tagName){ return this.msxmldom.selectNodes("//*[local-name()='" + tagName + "' and namespace-uri()='']"); };
          this.getElementsByTagNameNS = function(ns, tagName){ return this.msxmldom.selectNodes("//*[local-name()='" + tagName + "' and namespace-uri()='" + ns + "']"); };
        }
        else
        { // XSLPattern
          this.getElementsByTagName   = function(    tagName){ return this.msxmldom.selectNodes("*[not @xmlns]//" + tagName); };
          this.getElementsByTagNameNS = function(ns, tagName){ return this.msxmldom.selectNodes("*[@xmlns='" + ns + "']//" + tagName); };
        }
      }
      return new msdomObject(domutil.msxml);
    }
  };
  return domutil.msxml.createDocument(str);
}

function replaceHTTPErrorMessage(dst, status, statusText)
{
  if(!dst)
    return;
  
  var statusTable = 
  {
    unknown : { ja:"不明なエラーが発生しました", en:"Unknown" },
    "401" : { ja:"認証に失敗しました", en:"Unauthorized" },
    "403" : { ja:"アクセスが拒否されました", en:"Forbidden" },
    "404" : { ja:"ファイルが見つかりません", en:"Not Found" },
    "500" : { ja:"サーバの内部エラーです", en:"Internal Server Error" },
    "503" : { ja:"サーバが利用できない状態です", en:"Service Unavailable" }
  };
  var lng = getSystemLanguageJorE();
  var str = statusTable[ status ][ lng ];
  if(!str)
    str = (typeof statusText == "string" && !statusText.match(/unknown/i))
      ? statusText : statusTable.unknown[ lng ]
      ;
  
  var src = createHTMLElement(dst.tagName);
  src.id = dst.id;
  
  var p = createHTMLElement("p");
  p.id = "errormessage";
  
  var text = document.createTextNode("ERROR " + status + " : " + str);
  
  p.appendChild(text);
  src.appendChild(p);
  dst.parentNode.replaceChild(src, dst);
  
  domutil.replaceStatus = "error";
}

function updatePageInfo(iserror)
{
  var pageID, bodyID;
  if(iserror)
    pageID = bodyID = "";
  else
  {
    pageID = FilenameToFragment(domutil.loadingFlagment).substr(1);
    bodyID = FragmentToFilename(domutil.loadingFlagment, "#");
  }
  var body = getHTMLElementsByTagName(document, "body")[0];
  var page = getHTMLElementsByTagAndClass(document, "*", domutil.pageClassName)[0];
  page.id = pageID;
  body.id = bodyID;
  body.className = domutil.replaceStatus;
  return pageID;
}

function tryCallDOMUtilEventById(id, evtname, arg)
{
  var evt = domutil.events[id];
  evtname = "on" + evtname;
  if(evt && (typeof evt[evtname] == "function"))
    evt[evtname](arg);
}

function asyncUpdateMainarea()
{
  var xmlhttp = domutil.xmlhttp;
  if(!xmlhttp || xmlhttp.readyState != 4)
    return;
  
  var id  = domutil.mainareaID;
  var dst = document.getElementById(id);
  var page = getHTMLElementsByTagAndClass(document, "*", domutil.pageClassName)[0];
  tryCallDOMUtilEventById(page.id, "unload", dst);
  
  if((xmlhttp.status | 200) != 200)
  {
    replaceHTTPErrorMessage(dst, xmlhttp.status, xmlhttp.statusText);
    updatePageInfo(true);
    return;
  }
  
  // Get Reference-Nodes
  var next = dst.nextSibling;
  var prev = dst.previousSibling;
  var parent = dst.parentNode;
  
  // Replace Document
  var xmldoc = xmlhttpParse(xmlhttp);
  var src = xmldoc.getElementById(id);
  xmlhttpReplaceElement(dst, src);
  // Replace Title
  var tsrc = getHTMLElementsByTagName(xmldoc, "title")[0];
  var tdst = getHTMLElementsByTagName(document, "title")[0];
  document.title = tdst.text = tsrc.firstChild.nodeValue;
  
  // Update Destination-Node (used Reference-Nodes)
  if(next)dst = next.previousSibling;
  else if(prev)dst = prev.nextSibling;
  else dst = parent.firstChild;
  
  anchorsHRefFilenameToFragmentByClassName(dst, domutil.fragmentClassName);
  tryCallDOMUtilEventById(updatePageInfo(), "load", dst);
  
  // Fragment Scroll Emulation
  var hash = getLocationHash();
  var elem = tryFixElementIDByFragment(hash);
  if(!elem)elem = document.getElementById( hash.substr(1) );
  if(elem)
  {
    var pos = getElementPosition(elem);
    window.scroll(pos.x, pos.y);
  }
}

function getPathByLocation()
{
  var href = location.href;
  var qi = href.lastIndexOf("?");
  var si = href.lastIndexOf("#");
  var sep = href.indexOf("\\") < 0 ? "/" : "\\";
  var i = href.length;
  if(     qi >= 0)i = qi;
  else if(si >= 0)i = si;
  
  return href.substring(0, href.lastIndexOf(sep, i) + 1 );
}

function getCurrentByHRef(href)
{
  var path = getPathByLocation();
  
  var i = href.indexOf(path);
  if(i >= 0)
    return href.substr(i + path.length);
  
  return href;
}

function FilenameToFragment(filename, separator, isext)
{
  var table = 
  {
    "/" : { chr:"-", regexp:/\//g },
    "\\": { chr:"-", regexp:/\\/g },
    "#" : { chr:"--", regexp:/#/g }
  };
  var regexp;
  if(!isext)
  {
    regexp = /[\.\/\\#]/g;
    table["."] = { chr:"_", regexp:/\./g };
  }
  else
  {
    regexp = /[\/\\#]/g;
  }
  
  var seps = 
  {
    "#" : "#",
    "?" : "?"
  };
  separator = seps[ separator ];
  if(!separator)
    separator = "#";
  
  if(isIEVersion(4, 5.01))
  {
    for(var i in table)
      filename = filename.replace(table[i].regexp, table[i].chr);
    return separator + filename;
  }
  
  return separator + filename.replace(regexp, function($0){ return table[$0].chr; });
}

function FragmentToFilename(fragment, separator)
{
  var table = 
  {
    "#" : { chr:"" , regexp:/#/g },
    "?" : { chr:"" , regexp:/\?/g },
    "--": { chr:"#", regexp:/:/g },
    "-" : { chr:"/", regexp:/-/g },
    "_" : { chr:".", regexp:/_/g }
  };
  if(location.href.indexOf("\\") >= 0)
    table["-"].chr = "\\";
  
  if(isIEVersion(4, 5.01))
  {
    for(var i in table)
      fragment = fragment.replace(table[i].regexp, table[i].chr);
    return;
  }
  
  var regexp;
  var regexps = 
  {
    "#" : /--|[-_#]/g,
    "?" : /--|[-_\?]/g
  };
  regexp = regexps[ separator ];
  if(!regexp)
    return "";
  
  return fragment.replace(regexp, function($0){ return table[$0].chr; });
}

function HRefFilenameToFragment(href, separator, isext)
{
  var path = getCurrentByHRef(href);
  if(path == href)
    return href;
  
  return FilenameToFragment(path, separator, isext);
}

function HRefFragmentToFilename(href)
{
  var separator, index;
  if((index = href.lastIndexOf("#")) >= 0)
    separator = "#";
  else if((index = href.lastIndexOf("?")) >= 0)
    separator = "?";
  else
    index = href.length;
  
  return getPathByLocation() + FragmentToFilename(href.substr(index), separator);
}

function getPrimaryFragmentByURL(url)
{
  var fragment = url.substr(url.lastIndexOf("#") + 1);
  var subIndex = fragment.lastIndexOf("--");
  return (subIndex < 0) ? fragment : fragment.substring(0, subIndex);
}

function getPrimaryPathByURL(url)
{
  var hashIndex = url.lastIndexOf("#");
  return (hashIndex < 0) ? url : url.substr(0, hashIndex);
}

function xmlhttpGetFile(url, asyncFlag, userName, password)
{
  var xmlhttp = xmlhttpInit(domutil);
  if(!xmlhttp)
    return;
  
  url = getPrimaryPathByURL(url);
  xmlhttp.onreadystatechange = asyncUpdateMainarea;
  
  try
  {
    xmlhttp.open("GET", url, asyncFlag, userName, password);
    xmlhttp.send(null);
  }catch(e)
  {
    var mainarea = document.getElementById(domutil.mainareaID);
    replaceHTTPErrorMessage(mainarea, 404);
    updatePageInfo(true);
  }
}

function xmlhttpGetFragment(url, asyncFlag, userName, password)
{
  domutil.loadingFlagment = getPrimaryFragmentByURL(url);
  xmlhttpGetFile( HRefFragmentToFilename(url), asyncFlag, userName, password);
}

function setLocationHash(hash)
{
  if(!isIEVersion(4))
  {
    location.hash = hash;
    return;
  }
  
  var iframe, ifloc = document.getElementById("IEHiddenLocator");
  if(ifloc)
  {
    iframe = ifloc.contentWindow
      ? ifloc.contentWindow.document
      : ifloc.document
      ;
  }
  else
  {
    ifloc = document.createElement("iframe");
    ifloc.id = "IEHiddenLocator";
    ifloc.style.display = "none";
    getHTMLElementsByTagName(document, "body")[0].appendChild(ifloc);
    iframe = ifloc.contentWindow
      ? ifloc.contentWindow.document
      : ifloc.document
      ;
    iframe.open();
    iframe.close();
    if(isIEVersion(4,7))
      iframe.location.hash = location.hash;
  }
  if(isIEVersion(4,7))
  {
    iframe.open();
    iframe.close();
  }
  iframe.location.hash = hash;
  location.hash = hash;
  domutil.newLocationHash = hash;
}

function getLocationHash()
{
  var hash = location.hash;
  if(isIEVersion(4,7))
  {
    var ifloc = document.getElementById("IEHiddenLocator");
    if(ifloc)
    {
      var iframe = ifloc.contentWindow
        ? ifloc.contentWindow.document
        : ifloc.document
        ;
      var hash = iframe.location.hash;
      if(hash != domutil.newLocationHash)
      {
        if(location.hash != hash)
          location.hash = hash;
        domutil.newLocationHash = hash;
      }
    }
  }
  return (hash.length <= 1) ? domutil.mainloadHRefHash : hash;
}

function reloadMainareaByFragment()
{
  var hash = getLocationHash();
  
  if(hash == domutil.prevLocationHash         // Not Changed
  || document.getElementById(hash.substr(1))) // Document Found
    return;
  
  domutil.prevLocationHash = hash;
  
  xmlhttpGetFragment(hash, true);
}

function tryFixElementIDByFragment(fragment)
{
  var index = fragment.lastIndexOf("--");
  if(index >= 0)
  {
    // var mainFragment = fragment.substring(0, index);
    var  subFragment = fragment.substring(index + 2);
    var e = document.getElementById(subFragment);
    if(e && e.className == domutil.fixIDClassName)
    {
      e.id = fragment.substr(1);
      return e;
    }
  }
}

function anchorsHRefFilenameToFragmentByClassName(obj, className, separator)
{
  // Change location hash handler /////////////////////////////////////////////
  function changeLocationHashByEventHRef(e)
  {
    if(!e)e = window.event;
    var a = e.srcElement ? e.srcElement : e.currentTarget;
    for(;;)
    {
      switch( a.nodeName.toLowerCase() )
      {
        case "a":
          break;
        case "body":
          return;
        default:
          a = a.parentNode;
          continue;
      }
      break;
    }
    var href = a.href;
    var hash = href.substr( href.lastIndexOf("#") );
    
    a.blur();
    
    if(document.getElementById( hash.substr(1) ))
      return;
    
    if(href.indexOf("javascript:") == 0)
    {
      if(isIEVersion(7) || window.opera)
      {
        window.setTimeout(reloadMainareaByFragment, 0);
        return;
      }
      eval( href.substring(11) );
      reloadMainareaByFragment();
    }
    else
    {
      domutil.prevLocationHash = hash;
      setLocationHash(hash);
      xmlhttpGetFragment(href, true);
    }
    
    if(e.preventDefault)
      e.preventDefault();
    else
      e.returnValue = false;
    return false;
  }
  
  var isext = (location.hash.lastIndexOf(".") >= 0);
  var objs = getHTMLElementsByTagAndClass(obj, "a", className);
  for(var i = 0, len = objs.length; i < len; i++)
  {
    var a = objs[i];
    var fragment = HRefFilenameToFragment(a.href, separator, isext);
    a.href = fragment;
    tryFixElementIDByFragment(fragment);
    AddEventListener(a, "click", changeLocationHashByEventHRef, false);
  }
}

function isFragmentNGIDs()
{
  var str;
  if(location.hash.length   > 1)str = location.hash.substr(1);
  if(location.search.length > 1)str = location.search.substr(1);
  if(!str)
    return true;
  
  if(!domutil.fragmentNGIDs)
    return false;
  for(var i = 0, len = domutil.fragmentNGIDs.length; i < len; i++)
    if(domutil.fragmentNGIDs[i] == str)
      return true;
  return false;
}

function dommain()
{
  var mainload_href = document.getElementById(domutil.mainloadID).href;
  var current_href  = mainload_href;
  if(!isFragmentNGIDs())
  {
    current_href = HRefFragmentToFilename(location.href);
    if(current_href.length == 0
    || current_href.lastIndexOf("/") == current_href.length - 1)
      current_href = mainload_href;
  }
  
  domutil.mainloadHRefHash = HRefFilenameToFragment(mainload_href);
  domutil.prevLocationHash = HRefFilenameToFragment(current_href);
  domutil.loadingFlagment = getPrimaryFragmentByURL( domutil.prevLocationHash );
  
  /****
  alert("document.getElementById(domutil.mainloadID).href:" + document.getElementById(domutil.mainloadID).href
    + "\nmainload_href:" + mainload_href
    + "\nlocation.href:" + location.href
    + "\ncurrent_href:" + current_href
    + "\ndomutil.mainloadHRefHash:" + domutil.mainloadHRefHash
    + "\ndomutil.prevLocationHash:" + domutil.prevLocationHash
    );
  ****/
  
  anchorsHRefFilenameToFragmentByClassName(
    document, domutil.fragmentClassName
    );
  
  addStyleSheetRule("." + domutil.fragmentClassName, "visibility:visible");
  xmlhttpGetFile(current_href, true);
  
  // UA fragment update detection handler ///////////////////////////////////
  function mainareaIntervalRefresh()
  {
    reloadMainareaByFragment();
    window.setTimeout(mainareaIntervalRefresh, domutil.mainareaRefreshMSec);
  }
  window.setTimeout(mainareaIntervalRefresh, domutil.mainareaRefreshMSec);
}

(function()
{
  // Regist listener
  AddContentLoadedListener(dommain);
  
  // None-Display element
  addStyleSheetRule("." + domutil.altareaClassName, "display:none");
  
  // Hidden element fragments
  addStyleSheetRule("." + domutil.fragmentClassName, "visibility:hidden");
})();

/* End of mainarea.js */

