/**********************************
          Global Variables
***********************************/
// precache art files and sizes for widget styles and spacers
// (all images must have same height/width)
// this section move to outline-edit (book.kahua)

var isIE = window.navigator.appName.indexOf("Microsoft") != -1;

// miscellaneous globals
var widgetWidth = "20";
var widgetHeight = "16";
var currState = new Object();
var nodeList = new Array();
var displayTarget = "contentFrame";
var xDoc;
  
var ELEMENT_EDIT_FORM_ID = 'elementEditForm';
var ELEMENT_EDIT_INPUT_ID = 'elementEditInput';
var sourceElem = null; // element now editing.

function  getNodeId(id) {
    return id.match(/^[A-Za-z]*_(.*)$/)[1];
}

/**********************************
  Toggle Display and Icons
***********************************/
// invert item state (expanded to/from collapsed)
function swapState(currState, currVal, n) {
    currState[n] = currVal ^ 1;
}
  
// retrieve matching version of 'minus' images
function getExpandedWidgetState(imgURL) {
    if (imgURL.indexOf("Start") != -1) {
        return expandedWidgetStart.src;
    }
    if (imgURL.indexOf("End") != -1) {
        return expandedWidgetEnd.src;
    }
    return expandedWidget.src;
}
  
// retrieve matching version of 'plus' images
function getCollapsedWidgetState(imgURL) {
    if (imgURL.indexOf("Start") != -1) {
        return collapsedWidgetStart.src;
    }
    if (imgURL.indexOf("End") != -1) {
        return collapsedWidgetEnd.src;
    }
    return collapsedWidget.src;
}
  
// toggle an outline mother entry, storing new state value;
// invoked by onclick event handlers of widget image elements
function toggleImg(img, blockNum) {
    var newString = "";
    var expanded, n;
    // modify state string based on parameters from IMG
    expanded = currState[blockNum];
    swapState(currState, expanded, blockNum);
    // dynamically change display style
    var bicon = document.getElementById('bookIcon_'+blockNum);
    var sty = document.getElementById("OLBlock_" + blockNum).style;
    if (expanded == "0") {
	sty.display = "block";
	img.src = getExpandedWidgetState(img.src);
	bicon.src = openBookIcon.src;
    } else {
	sty.display = "none";
	img.src = getCollapsedWidgetState(img.src);
	bicon.src = bookIcon.src;
    }
    if (sourceElem && document.getElementById(ELEMENT_EDIT_INPUT_ID)) {
	overElement(sourceElem, document.getElementById(ELEMENT_EDIT_INPUT_ID));
    }
}

function expandAll( ) {
    for (var state in currState) {
	currState[state] = "1";
	var img = document.getElementById('widget_'+state);
	if (img) {
	    img.src = getExpandedWidgetState(img.src);
	}
	var bimg = document.getElementById('bookIcon'+state);
	if (bimg) {
	    bimg.src = openBookIcon.src;
	}
    }
    initExpand( );
}
  
function collapseAll( ) {
    for (var state in currState) {
	currState[state] = "0";
	var img = document.getElementById('widget'+state);
	if (img) {
	    img.src = getCollapsedWidgetState(img.src);
	}
	var bimg = document.getElementById('bookIcon'+state);
	if (bimg) {
	    bimg.src = bookIcon.src;
	}
    }
    initExpand( );
}

// window function

function getPageEventCoords(evt) {
    var coords = {left:0, top:0};
    if (evt.screenX) {
	coords.left = evt.screenX;
	coords.top  = evt.screenY;
    }
    return coords;
}

function nodeWindow(url, evt) {
    evt = evt ? evt : (window.event) ? event : null;
    var coord = getPageEventCoords(evt);
    var nodeWindow =
	window.open(url, 'bookNode',
		    'location=yes,left=' + coord.left + ',top=' + coord.top +
		    ',width=350,height=200');
    nodeWindow.focus();
}

// style

function hilight(source) {
    source.style.backgroundColor = 'lightblue';
    source.style.fontWeight = 'bold';
}

function normal(source) {
    source.style.backgroundColor = 'white';
    source.style.fontWeight = 'normal';
}

/*********************************
   Outline HTML Generation
**********************************/
// apply default expansion state from outline's header
// info to the expanded state for one element to help 
// initialize currState variable
function calcBlockState(n) {
    var ol = xDoc.getElementsByTagName("body")[0];
    var outlineLen = ol.getElementsByTagName("outline").length;
    // get OPML expansionState data
    var expandElem = xDoc.getElementsByTagName("expansionState")[0];
    var expandedData = (expandElem.childNodes.length) ? 
        expandElem.firstChild.nodeValue.split(",") : null;
    if (expandedData) {
        for (var j = 0; j < expandedData.length; j++) {
            if (n == expandedData[j] - 1) {
                return "1";
            }
        }
    }
    return "0";
}

// &state=1,4,7,...
function getExpansionState() {
    var result = "";
    for (var i=0; i<nodeList.length; i++) {
	if (nodeList[i] != undefined && currState[nodeList[i]] == "1") {
	    result += (i+1).toString() + ',';
	}
    }
    return result;
}

// make DOM elements

function makeImage(doc, src) {
    var elem = doc.createElement('img');
    elem.src = src;
    elem.height = widgetHeight;
    elem.width = widgetWidth;
    return elem;
}

function makeEmptyImage(doc) {
    return makeImage(emptySpace.src);
}

function makeChainImage(doc) {
    return makeImage(chainSpace.src);
}

function makeClickImageString(src, id) {
    return "<img src=\""+src+"\" onClick=\"toggleImg(this, '"+id+"');\" id=\"widget_"+id+"\" />";
}

function makeRow(doc, id) {
    var elem = doc.createElement('div');
    elem.setAttribute('class', 'OLRow');
    elem.id = 'OLRow_'+id;
    var sty = elem.style;
    sty.display = 'block';
    sty.whiteSpace = 'nowrap';
    return elem;
}

var hTim = 0;
function startEdit(node, parent) {
    var id = 'nodeTitle_'+node;
    var el = document.getElementById(id);
    if (el != null) {
	clearInterval(hTim);
	var state = currState[parent];
	if (state == '0') {
	    var img = document.getElementById('widget_'+parent);
	    toggleImg(img, parent);
	}
	var evt = {target:el};
	editElement(evt);
	sourceElem.style.cursor = 'auto';
    }
}
function addElement(e) {
    function handler(req) {
	var result = req.responseXML;
	var error = result.getElementsByTagName('Error')[0].getAttribute('code');
	var message = result.getElementsByTagName('Message')[0].firstChild.nodeValue;
	var node = result.getElementsByTagName('Node')[0].getAttribute('id');
	var parent = result.getElementsByTagName('Parent')[0].getAttribute('id');
	if (error != "0") {
	    alert('見出し追加に失敗しました。\nMessage='+message);
	}
	var rel = document.getElementById('reloadButton');
	rel.click();
	hTim = setInterval('startEdit("'+node+'","'+parent+'")', 100);
    }
    var evt = e ? e : (window.event) ? event : null;
    sourceElem = evt.target ? evt.target : evt.srcElement;
    sourceElem.style.cursor = 'wait';
    var id = sourceElem.id.match(/^[A-Za-z0-9]+_(.*)$/)[1];
    var book = sourceElem.getAttribute('book');
    var prefix = sourceElem.getAttribute('prefix');
    var url = nodeAdd + book + '/' + id;
    new Ajax.Request(url, {method:'post',
		requestHeaders:['Accept-Charset', 'euc-jp'],
		parameters:'name='+EscapeEUCJP('無題'), onComplete:handler});
}


function overElement(baseElem, overElem) {
    var offsetTmp = baseElem;
    var offsetLeft = 0;
    var offsetTop = 0;
    while (offsetTmp) {
	offsetLeft += offsetTmp.offsetLeft;
	offsetTop += offsetTmp.offsetTop;
	offsetTmp = offsetTmp.offsetParent;
    }
    
    overElem.style.left = offsetLeft;
    overElem.style.top = offsetTop;
}

function replaceText() {
    function handler(req) {
	var result = req.responseXML;
	var error = result.getElementsByTagName('Error')[0].getAttribute('code');
	var message = result.getElementsByTagName('Message')[0].firstChild.nodeValue;
	if (error != "0") {
	    alert('見出し編集に失敗しました。\nMessage='+message);
	}
	var rel = document.getElementById('reloadButton');
	rel.click();
	sourceElem.style.cursor = 'auto';
    }
    var form = document.getElementById(ELEMENT_EDIT_FORM_ID);
    var input = document.getElementById(ELEMENT_EDIT_INPUT_ID);
    if (sourceElem != null && input.value.length > 0) {
	sourceElem.innerHTML = input.value;
	if (nodeEdit && nodeEdit.length > 0) {
	    var url = nodeEdit + getNodeId(sourceElem.id);
	    document.charset = 'euc-jp';
	    new Ajax.Request(url, {method:'post',
			requestHeaders:['Accept-Charset', 'euc-jp'],
			parameters:'name='+EscapeEUCJP(input.value), onComplete:handler});
	}
    }
    form.removeChild(input);
    document.body.removeChild(form);
}

function getMBLength(str) {
    var rep = encodeURI(str.replace(/[\x20\x22\x25\x3c\x3e\x5b\x5c\x5d\x5e\x60\x7b\x7c\x7d]/g, '.'));
    return decodeURI(rep.replace(/%(\d|[A-Z0-9]){2}%(\d|[A-Z0-9]){2}%(\d|[A-Z0-9]){2}/g, "..")).length;
}
function editElement(e){
    if (document.getElementById(ELEMENT_EDIT_INPUT_ID)) return;
    var evt = e ? e : (window.event) ? event : null;
    sourceElem = evt.target ? evt.target : evt.srcElement;
    sourceElem.style.cursor = 'wait';
    
    var form = document.createElement('form');
    form.id = ELEMENT_EDIT_FORM_ID;
    form.action = "javascript:replaceText();";
    form.setAttribute('Accept-Charset', 'euc-jp');
    document.body.appendChild(form);
    
    var input = document.createElement('input');
    input.name = 'name';
    input.id =  ELEMENT_EDIT_INPUT_ID;
    input.size = 20;
    input.style.position = 'absolute';
    input.value = sourceElem.innerHTML;
    var len = getMBLength(input.value);
    if (input.size < len) {
	input.size = len;
    }
    form.appendChild(input);
    
    overElement(sourceElem, input);
    input.select();
}

function upElement(e) {
    function handler(req) {
	var result = req.responseXML;
	var error = result.getElementsByTagName('Error')[0].getAttribute('code');
	var message = result.getElementsByTagName('Message')[0].firstChild.nodeValue;
	//alert(req.responseText);
	if (error != "0") {
	    alert('見出しレベルの変更に失敗しました。\nMessage='+message);
	}
  	var rel = document.getElementById('reloadButton');
	rel.click();
	sourceElem.style.cursor = 'auto';
    }
    var evt = e ? e : (window.event) ? event : null;
    sourceElem = evt.target ? evt.target : evt.srcElement;
    sourceElem.style.cursor = 'wait';
    var id = sourceElem.id.match(/^[A-Za-z0-9]+_(.*)$/)[1];
    var url = nodeUp + id;
    //prompt('url', url);
    new Ajax.Request(url, {onComplete:handler});
}
function downElement(e) {
    function handler(req) {
	var result = req.responseXML;
	var error = result.getElementsByTagName('Error')[0].getAttribute('code');
	var message = result.getElementsByTagName('Message')[0].firstChild.nodeValue;
	//alert(req.responseText);
	if (error != "0") {
	    alert('見出しレベルの変更に失敗しました。\nMessage='+message);
	}
  	var rel = document.getElementById('reloadButton');
	rel.click();
	sourceElem.style.cursor = 'auto';
    }
    var evt = e ? e : (window.event) ? event : null;
    sourceElem = evt.target ? evt.target : evt.srcElement;
    sourceElem.style.cursor = 'wait';
    var id = sourceElem.id.match(/^[A-Za-z0-9]+_(.*)$/)[1];
    var url = nodeDown + id;
    //prompt('url', url);
    new Ajax.Request(url, {onComplete:handler});
}

function deleteElement(e) {
    function handler(req) {
	var result = req.responseXML;
	var error = result.getElementsByTagName('Error')[0].getAttribute('code');
	var message = result.getElementsByTagName('Message')[0].firstChild.nodeValue;
	if (error != "0") {
	    alert('削除できませんでした。\n'+message);
	}
	var rel = document.getElementById('reloadButton');
	rel.click();
	sourceElem.style.cursor = 'auto';
    }
    if (!confirm('本当に削除しますか?\nこの操作は取り消しできません。')) return;
    var evt = e ? e : (window.event) ? event : null;
    sourceElem = evt.target ? evt.target : evt.srcElement;
    sourceElem.style.cursor = 'wait';
    var id = sourceElem.id.match(/^[A-Za-z0-9]+_(.*)$/)[1];
    var url = nodeDelete + id;
    new Ajax.Request(url, {onComplete:handler});
}

function makeNodeAnchor(doc, link, target, nodeEdit, id, type) {
    var elem = doc.createElement('a');
    elem.setAttribute('class','itemTitle');
    elem.id = 'itemTitle_'+id;
    if (type == "book") {
	elem.style.fontWeight = "bold";
    } else if (type == "node") {
	elem.setAttribute('onMouseOver', 'hilight(this);');
	elem.setAttribute('onMouseOut', 'normal(this);');
	if (link) {
	    elem.title = link;
	    elem.href = link;
	    elem.target = target;
	    elem.style.cursor = 'pointer'; //IE
	}
	if (nodeEdit && id) {
	    elem.setAttribute('onDblClick', 'editElement(event);');
	}
    } else if (type == "article") {
    }
    return elem;
}

function makePostLinkString(src, editable, articleEdit, book, id) {
    var postLink;
    var url;
    if (editable == "1") {
	url = decodeURI(articleEdit+'book/'+id+'/new/outline-edit/'+book);
	if (isIE) {
	    postLink = "<a href=\""+url+"\">"+
		"<span title='新しい記事を投稿'>"+
		"<img src='"+src+"' alt='新しい記事を投稿' border='0'></span></a>";
	} else {
	    postLink = "<a href=\"javascript:void(0);\" onClick=\"locationChange('"+url+"');\">"+
		"<span title='新しい記事を投稿'>"+
		"<img src='"+src+"' alt='新しい記事を投稿' border='0'></span></a>";
	}
    } else {
	url = decodeURI(articleEdit+'book/'+id+'/new/book-node/'+book+'/'+id);
	postLink = "<a href=\""+url+"\" target='contentFrame'>"+
	    "<span title='新しい記事を投稿'>"+
	    "<img src='"+src+"' alt='新しい記事を投稿' border='0'></span></a>";
    }
    return postLink;
}


function makeArticleAnchorString(title, articleEdit, book, bookNode, id) {
    var articleAnchor;
    if (isIE) {
	articleAnchor = "&nbsp;<a href=\""+
	    decodeURI(articleEdit+"book/"+bookNode+"/"+id+"/outline-edit/"+book)+
	    "\" target=\"_blank\"><span style=\"position:relatve; top:-3px; height:11px\" "+
	    "title=\"クリックで記事編集\">"+title+"</span></a>";
    } else {
	articleAnchor = "&nbsp;<a href=\"javascript:void(0);\" onClick=\"locationChange('"+
	    decodeURI(articleEdit+"book/"+bookNode+"/"+id+"/outline-edit/"+book)+
	    "');\" ><span style=\"top:-3px; height:11px\" "+
	    "title=\"クリックで記事編集\">"+title+"</span></a>";
    }
    return articleAnchor;
}

function setElemStyle(elem) {
    elem.style.top = '-3px';
    elem.style.height = '11px';
    return elem;
}

function makeNodeTitle(doc, id, title, type, nodeEdit) {
    var elem = doc.createElement('span');
    elem.id = 'nodeTitle_'+id;
    if (type == "node") {
	if (nodeEdit.length > 0) {
	    elem.title = 'ダブルクリックで見出し編集';
	} else {
	    elem.title = title;
	}
    }
    elem = setElemStyle(elem);
    elem.innerHTML = title;
    return elem;
}

function setElemClick(elem, url) {
    elem.onClick = 'nodeWindow(\"'+url+"\", event);";
    return elem;
}

function makeLinkStyle(doc) {
    var elem = doc.createElement('span');
    return setElemStyle(elem);
}

function makeButtonLinkString(url, src, label) {
    return "<a href= \"javascript:void(0);\" onClick=\"nodeWindow('"+url+"', event);\" >"+
    	"<span style='top:-3px; height:11px' title='"+label+"'>"+
    	"<img src='"+src+"' alt='"+label+"' border='0'></span></a>";
}

function makeBlock(doc, id) {
    var elem = doc.createElement('span');
    elem.setAttribute('class','OLBlock');
    elem.blockNum = id;
    elem.id = 'OLBlock_'+id;
    return elem;
}

// navigation
function locationChange(url) {
    var expansionState = getExpansionState();
    if (expansionState != '') {
	location.href = url+'?state='+getExpansionState();  // mozilla
    } else {
	location.href = url;
    }
}

// escapeHTML like prototype.js
function escapeHTML(str) {
    var div = document.createElement('div');
    var text = document.createTextNode(str);
    div.appendChild(text);
    return div.innerHTML;
}

// function setButtonIcon(doc, book, type, id, prefix, icon, onclick) {
//     var elem = doc.createElement('a');
//     elem.setAttribute('onClick', onclick);
//     var img = doc.createElement('img');
//     img.id = type + '_' + id;
//     img.setAttribute('prefix', prefix);
//     img.setAttribute('book', book);
//     img.src = icon.src;
//     img.style.border = '0';
//     elem.appendChild(img);
//     return elem;
// }

function makeButtonIconString(book, type, id, prefix, icon, onclick, label) {
    return "<a onClick='"+onclick+"' ><span title='"+label+"'><img src='"+
	icon.src+"' id='"+type+"_"+id+"' prefix='"+prefix+"' book='"+book+"' style='border: 0px'/></span></a>";
}

// counters for reflexive calls to drawOutline
var currID = 0;
var blockID = 0;
var bookId = '';

function drawNode(node, parent, prefix, currID, blockID) {
    var nestCount = node.childNodes.length;
    var id =
	(node.getAttribute("id")) ? node.getAttribute("id") : "";
    
    // div OLRow
    var row = makeRow(document, id);
    
    currID++;
    
    // prefix
    
    row.setAttribute('prefix', prefix);
    if (prefix) {
	for (var n=0; n<prefix.length; n++) {
	    var c = prefix.charAt(n);
	    if (c == "0") {
		var pimg = makeImage(document, chainSpace.src);
		row.appendChild(pimg);
	    } else if (c == "1") {
		var pimg = makeImage(document, emptySpace.src);
		row.appendChild(pimg);
	    }
	}
    }
    
    // img
    var type =
	(node.getAttribute("type")) ?
	node.getAttribute("type") : "";
    if (type == "book") {
	bookId = node.getAttribute("id");
	var img = makeImage(document, bookIcon.src);
	row.appendChild(img);
	row.innerHTML += '&nbsp;';
    } else if (type == "article") {
	var articlePrefix = 
	    (node.getAttribute("prefix")) ? node.getAttribute("prefix") : "";
	var src;
	if (articlePrefix == "1") {
	    src = chainSpace.src;
	} else {
	    src = emptySpace.src;
	}
	var img = makeImage(document, src);
	row.appendChild(img);
	// article icon
	var isPrivate =
	    (node.getAttribute("private")) ? node.getAttribute("private") : "";
	var aimg;
	if (isPrivate == '1') {
	    aimg = makeImage(document, privateIcon.src);
	} else {
	    aimg = makeImage(document, articleIcon.src);
	}
	row.appendChild(aimg);
    } else if (type == "node") {
	if (nestCount > 0) {
	    var src =
		(node == parent.lastChild) ? collapsedWidgetEnd.src :
		(blockID == 0 && currID == 1) ?
		collapsedWidgetStart.src : collapsedWidget.src;
	    //var img = makeClickImage(document, src, id);
	    //row.appendChild(img);
	    row.innerHTML += makeClickImageString(src, id);
	    // book-node icon
	    var bsrc = 
		(node == parent.lastChild) ? bookIcon.src : openBookIcon.src;
	    var bimg = makeImage(document, bsrc);
	    bimg.id = 'bookIcon_'+id;
	    row.appendChild(bimg);
	    row.innerHTML += '&nbsp;';
	} else {
	    var src =
		(node == parent.lastChild) ? nodeWidgetEnd.src : nodeWidget.src;
	    var img = makeImage(document, src);
	    row.appendChild(img);
	    // book-node icon
	    var bimg = makeImage(document, openBookIcon.src);
	    bimg.id = 'bookIcon'+id;
	    row.appendChild(bimg);
	    row.innerHTML += '&nbsp;';
	}
    }
    
    // a
    var title = node.getAttribute("text");
    title = escapeHTML(title);
    var link = (node.getAttribute("uri")) ?
	node.getAttribute("uri") : "";
    // article or others
    if (type == "article") {
	var book =
	    (node.getAttribute("book")) ? node.getAttribute("book") : "";
	var bookNode =
	    (node.getAttribute("bookNode")) ? node.getAttribute("bookNode") : "";
	row.innerHTML += makeArticleAnchorString(title, articleEdit, book, bookNode, id);
    } else {
	var anchor =  makeNodeAnchor(document, link, displayTarget, nodeEdit, id, type);
	row.appendChild(anchor);
	// span
	var style = makeNodeTitle(document, id, title, type, nodeEdit);
	anchor.appendChild(style);
    }
    
    // post article
    var book =
	(node.getAttribute("book")) ? node.getAttribute("book") : "";
    if (type == "node" && articleEdit && id) {
	var editable =
	    (node.getAttribute("editable")) ? node.getAttribute("editable") : "";
	row.innerHTML += makePostLinkString(postIcon.src, editable, articleEdit, book, id);
    }
    
    // article delete
    if (type == "article") {
	row.innerHTML += makeButtonLinkString(articleDelete+"book/"+bookNode+"/"+id, deleteIcon.src, '記事削除');
    }
    
    // add button
    if (nodeAdd && book && id) {
	row.innerHTML += makeButtonIconString(book, 'addNode', id, prefix, addChildIcon, 'addElement(event);', '見出し追加');
    }

    // up button
    if ((type == 'node') && (parent.getAttribute('type') != 'book') && nodeUp && book && id) {
	row.innerHTML += makeButtonIconString(book, 'upNode', id, prefix, upIcon, 'upElement(event);', '見出しレベルを上げる');
    }
    
    // down button
    if ((type == 'node') && (node != parent.firstChild) && nodeDown && book && id) {
	row.innerHTML += makeButtonIconString(book, 'downNode', id, prefix, downIcon, 'downElement(event);', '見出しレベルを下げる');
    }
    
    if (type == "node" && nodeDelete && id) {
 	row.innerHTML += makeButtonIconString(book, 'deleteNode', id, prefix, deleteIcon, 'deleteElement(event);', '見出し削除');
   }
    return row;
}

function drawOutlineDOM(ol, parent, prefix) {
    var nestConut;
    ol = (ol) ? ol : xDoc.getElementsByTagName("body")[0];
    prefix = (prefix) ? prefix : "";
    if (ol.childNodes[ol.childNodes.length - 1].nodeType == 3) {
        ol.removeChild(ol.childNodes[ol.childNodes.length - 1]);
    }
    for (var i = 0; i < ol.childNodes.length ; i++) {
        if (ol.childNodes[i].nodeType == 3) {
            continue;
        }
	if (ol.childNodes[i].childNodes.length > 0 && 
	    ol.childNodes[i].childNodes[ol.childNodes[i].childNodes.length - 1].nodeType == 3) {
	    ol.childNodes[i].removeChild(ol.childNodes[i].childNodes[ol.childNodes[i].childNodes.length - 1]);
        }

	nestCount = ol.childNodes[i].childNodes.length;
 	var id =
 	    (ol.childNodes[i].getAttribute("id")) ? ol.childNodes[i].getAttribute("id") : "";

 	var type =
 	    (ol.childNodes[i].getAttribute("type")) ?
 	    ol.childNodes[i].getAttribute("type") : "";

	var row = drawNode(ol.childNodes[i], ol, prefix, currID, blockID);

 	parent.appendChild(row);

	// child-nodes
	if (nestCount > 0) {
	    var block = makeBlock(document, id);
	    blockID++;
	    row.appendChild(block);
	    if (type == "node" && currState[id] == null) {
		currState[id] = calcBlockState(currID-1);
		nodeList[currID-1] = id;
	    }
	    var nestPrefix = prefix;
	    nestPrefix += (i == ol.childNodes.length - 1) ? "1" : "0";
	    drawOutlineDOM(ol.childNodes[i], block, nestPrefix);
	}
    } // end for
}
  
/*********************************
     Outline Initializations
**********************************/
// expand items set in expansionState OPML tag, if any
function initExpand( ) {
    for (var state in currState) {
	var img = document.getElementById('widget_'+state);
	var bimg = document.getElementById('bookIcon_'+state);
	var block = document.getElementById("OLBlock_" + state);
	if (currState[state] == 1) {
	    if (block) {
		block.style.display = "block";
	    }
	    if (img) {
		img.src = getExpandedWidgetState(img.src);
	    }
	    if (bimg) {
		bimg.src = openBookIcon.src;
	    }
        } else {
	    if (block) {
		block.style.display = "none";
	    }
	    if (img) {
		img.src = getCollapsedWidgetState(img.src);
	    }
	    if (bimg) {
		bimg.src = bookIcon.src;
	    }
        }
	if (sourceElem && document.getElementById(ELEMENT_EDIT_INPUT_ID)) {
	    overElement(sourceElem, document.getElementById(ELEMENT_EDIT_INPUT_ID));
	}
    }
}

function replaceNode(s) {
    function handler(req) {
	var result = req.responseXML;
	var error = result.getElementsByTagName('Error')[0].getAttribute('code');
	var message = result.getElementsByTagName('Message')[0].firstChild.nodeValue;
	if (error != "0") {
	    alert('見出し移動に失敗しました。更新ボタンを押して元に戻してください。\nMessage='+message);
	}
    }
    var path = getNodeId(s.id);
    for (var n=0; n<s.childNodes.length; n++) {
	path = path + "/" + getNodeId(s.childNodes[n].id);
    }
    new Ajax.Request(nodeReplace+path, {onComplete:handler});
}

function createSortables() {
    for (var state in currState) {
	Sortable.create('OLBlock_'+state,{tag:'div',ghosting:false,
						  onUpdate:replaceNode});
    }
    Sortable.create('OLBlock_'+bookId,{tag:'div',ghosting:false,
    					  onUpdate:replaceNode});
}
  
function deleteSortables() {
    Sortable.destroy('OLBlock_'+bookId);
    for (var state in currState) {
	Sortable.destroy('OLBlock_'+state);
    }
}
  
function finishInit( ) {
        var ol = xDoc.getElementsByTagName("body")[0];
	// DOM
	var content = document.getElementById("content");
	if (content.firstChild) {
	    content.removeChild(content.firstChild);
	}
	var olHTML = document.createElement('span');
	olHTML.setAttribute('class','renderedOL');
	currID = 0;
	blockID = 0;
	drawOutlineDOM(ol, olHTML);
	content.appendChild(olHTML);

	initExpand();

	//createSortables();
}

var req;
var last_modified = null;
var cached_content = '';

function loadXMLDoc(url) {
    req = false;
    if (window.XMLHttpRequest) {
	try {
	    req = new XMLHttpRequest();
	} catch (e) {
	    req = false;
	}
    } else if (window.ActiveXObject) {
	try {
	    req = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
	    try {
		req = new ActiveXObject("Microsoft.XMLHTTP");
	    } catch (e) {
		req = false;
	    }
	}
    }
    if (req) {
	req.onreadystatechange = processReqChange;
	req.open("GET", url, true);
	if (last_modified) {
	    req.setRequestHeader("If-Modified-Since", last_modified);
	}
	req.send("");
    }
}

function processReqChange() {
    if (req.readyState == 4) {
	if (req.status == 200) {
	    if (req.getAllResponseHeaders().match("Date")) {
		last_modified = req.getResponseHeader("Date");
	    }
	    xDoc = req.responseXML;
	    setTimeout("finishInit( )", 300);
//         } else {
//             alert("There was a problem retrieving the XML data:\n" +
// 		  req.statusText);
	}
    }
}
  
// initialize first time -- invoked onload
function initXMLOutline(url) {
    loadXMLDoc(url);
}
