function BibleReader(doc, bookskel, versinfo) {

	// Initial Configuration
	
	var conf = new Object();
	conf.showbiblefile = "showbible.xml.php";
	conf.bookinfo = bookskel;
	conf.verinfo = versinfo;
	
	// Content Binding
	
	var pDoc = doc;

	var view = new Object();

	view.bibleframes = new Array(new Object(), new Object(), new Object());
	view.bibleframes[0].node = pDoc.getElementById('ContentFrame0');
	view.bibleframes[1].node = pDoc.getElementById('ContentFrame1');
	view.bibleframes[2].node = pDoc.getElementById('ContentFrame2');
	view.bibleframes[0].node.style.display = 'block';
	view.bibleframes[1].node.style.display = 'none';
	view.bibleframes[2].node.style.display = 'none';
	view.bibleframes[0].contentid = 0;
	view.bibleframes[1].contentid = 0;
	view.bibleframes[2].contentid = 0;

	view.browseframe = new Object();
	view.browseframe.node = pDoc.getElementById('BrowsingFrame');

	view.chapnav = new Object();
	view.chapnav.booktitle = new Object();
	view.chapnav.booktitle.node = pDoc.getElementById('BookTitle');
	view.chapnav.chapinput = new Object();
	view.chapnav.chapinput.node = pDoc.getElementById('ChapterInput');
	view.chapnav.chapcount = new Object();
	view.chapnav.chapcount.node = pDoc.getElementById('ChapterCount');

	view.sidebar = new Object();

	view.sidebar.tab = new Object();
	view.sidebar.tab.node = pDoc.getElementById('SideBarTab');
	view.sidebar.tab.search = new Object();
	view.sidebar.tab.search.node = pDoc.getElementById('SideBarSearchTab');
	view.sidebar.tab.bookmark = new Object();
	view.sidebar.tab.bookmark.node = pDoc.getElementById('SideBarBookmarkTab');

	view.sidebar.search = new Object();
	view.sidebar.search.node = pDoc.getElementById('SideBarSearch');
	view.sidebar.search.input = new Object();
	view.sidebar.search.input.node = pDoc.getElementById('SearchInput');
	view.sidebar.search.from = new Object();
	view.sidebar.search.from.node = pDoc.getElementById('SearchFrom');
	view.sidebar.search.from.bookid = null;
	view.sidebar.search.to = new Object();
	view.sidebar.search.to.node = pDoc.getElementById('SearchTo');
	view.sidebar.search.to.bookid = null;
	view.sidebar.search.versiondisplay = new Object();
	view.sidebar.search.versiondisplay.node = pDoc.getElementById('SearchVersionDisplay');
	view.sidebar.search.searchbtn = new Object();
	view.sidebar.search.searchbtn.node = pDoc.getElementById('SearchNow');
	view.sidebar.search.resultframe = new Object();
	view.sidebar.search.resultframe.node = pDoc.getElementById('SearchResultFrame');
	
	view.sidebar.bookmark = new Object();
	view.sidebar.bookmark.node = pDoc.getElementById('SideBarBookmark');
	view.sidebar.bookmark.pribtn = new Object();
	view.sidebar.bookmark.pribtn.node = pDoc.getElementById('BookmarkPriBtn');
	view.sidebar.bookmark.secselection = new Object();
	view.sidebar.bookmark.secselection.node = pDoc.getElementById('BookmarkSecSelection');
	
	// States Initialization
	
	var state = new Object();
	state.layout = 'combine_line';
	state.contentid = -1 << 8;
	state.enterSearch = false;
	state.enterSearchFrom = true;

	// Private Functions	
	
	var UpdateLayout = function(index) {
		frame = view.bibleframes[index].node;
		if (frame.contentDocument) { // Mozilla
			combine_line_div = frame.contentDocument.getElementById("combine_line");
			split_line_div = frame.contentDocument.getElementById("split_line");
			paragraph_div = frame.contentDocument.getElementById("paragraph");
		} else if (frame.contentWindow) { // IE 5.5, IE 6
			combine_line_div = frame.contentWindow.document.getElementById("combine_line");
			split_line_div = frame.contentWindow.document.getElementById("split_line");
			paragraph_div = frame.contentWindow.document.getElementById("paragraph");
		} else { // IE 5
			combine_line_div = frame.document.getElementById("combine_line");
			split_line_div = frame.document.getElementById("split_line");
			paragraph_div = frame.document.getElementById("paragraph");
		}
		switch (state.layout) {
		case "combine_line":
			if (combine_line_div) combine_line_div.style.display = "block";
			if (split_line_div) split_line_div.style.display = "none";
			if (paragraph_div) paragraph_div.style.display = "none";
			break;
		case "split_line":
			if (combine_line_div) combine_line_div.style.display = "none";
			if (split_line_div) split_line_div.style.display = "block";
			if (paragraph_div) paragraph_div.style.display = "none";
			break;
		case "paragraph":
			if (combine_line_div) combine_line_div.style.display = "none";
			if (split_line_div) split_line_div.style.display = "none";
			if (paragraph_div) paragraph_div.style.display = "block";
			break;
		default:
			break;
		}
		return false;
	}
	
	// Public Functions
	
	this.SetBrowseBible = function(bool) {
		if (bool) {
			view.browseframe.node.style.display = "none";		
		} else {
			view.browseframe.node.style.display = "inline";
			view.chapnav.booktitle.node.innerHTML = "";
			view.chapnav.chapcount.node.innerHTML = "/ -";
			view.chapnav.chapinput.node.value = "-";
		}
		return false;
	}
	
	this.BrowsePage = function(src) {
		view.browseframe.node.src = src;
		this.SetBrowseBible(false);
		return false;
	}

	this.DisplayBibleText = function(bookid, chapter) {
		if (state.contentid >> 8 != bookid) {
			view.chapnav.booktitle.node.innerHTML = conf.bookinfo[bookid].name_clong;
			view.chapnav.chapcount.node.innerHTML = "/ " + conf.bookinfo[bookid].chap_cnt;
			state.contentid = bookid << 8;
		}
		state.contentid = (state.contentid & 0xFF00) | chapter;
		versions = "";
		for (i=0; i<conf.verinfo.length; i++) {
			if (conf.verinfo[i].show) {
				versions = versions + conf.verinfo[i].versionid + "+";
			}
		}
		srcPrefix = conf.showbiblefile + "?version=" + versions + "&book=" + bookid + "&chapter=";
		state.contentid = (bookid << 8) + chapter;
		if (view.bibleframes[1].contentid == state.contentid) {
			var temp = view.bibleframes[0];
			view.bibleframes[0] = view.bibleframes[1];
			view.bibleframes[1] = temp;
			view.bibleframes[0].node.style.display = "block";
			view.bibleframes[1].node.style.display = "none";
		} else if (view.bibleframes[2].contentid == state.contentid) {
			temp = view.bibleframes[0];
			view.bibleframes[0] = view.bibleframes[2];
			view.bibleframes[2] = temp;
			view.bibleframes[0].node.style.display = "block";
			view.bibleframes[2].node.style.display = "none";
		} else {
			view.bibleframes[0].node.src = srcPrefix + chapter;
		}
		view.bibleframes[0].contentid = state.contentid;
		diff1 = view.bibleframes[1].contentid - state.contentid;
		diff2 = view.bibleframes[2].contentid - state.contentid;
		if (diff1 == 1 || diff1 == -1) {
			view.bibleframes[2].node.src = srcPrefix + (chapter - diff1);
			view.bibleframes[2].contentid = state.contentid - diff1;
		} else if (diff2 == 1 || diff2 == -1) {
			view.bibleframes[1].node.src = srcPrefix + (chapter - diff2);
			view.bibleframes[1].contentid = state.contentid - diff2;
		} else {
			view.bibleframes[1].node.src = srcPrefix + (chapter - 1);
			view.bibleframes[2].node.src = srcPrefix + (chapter + 1);
			view.bibleframes[1].contentid = state.contentid - 1;
			view.bibleframes[2].contentid = state.contentid + 1;
		}
		this.SetBrowseBible(true);
		view.chapnav.chapinput.node.value = chapter;
		SetCookie("lastcontentid", state.contentid);
		return false;
 	}

	this.ContentFrameLoaded = function(book, chapter) {
		if (view.bibleframes[0].contentid == ((book << 8) + chapter)) {
			UpdateLayout(0);
		} else if (view.bibleframes[1].contentid == ((book << 8) + chapter)) {
			UpdateLayout(1);
		} else {
			UpdateLayout(2);
		}
		return false;
	}
	
	this.BookButtonClicked = function(id) {
		id = id * 1;
		if (state.enterSearch) {
			if (state.enterSearchFrom)
				this.SetSearchFrom(id);
			else
				this.SetSearchTo(id);
			this.CheckSearchOrder();
			state.enterSearch = false;
		} else {
			this.DisplayBibleText(id, 1);
		}
		return false;
	}

	this.LayoutButtonClicked = function(layout) {
		switch (layout) {
		case "combine_line":
			state.layout = "combine_line";
			break;
		case "split_line":
			state.layout = "split_line";
			break;
		case "paragraph":
			state.layout = "paragraph";
			break;
		default:
			break;
		}
		UpdateLayout(0);
		UpdateLayout(1);
		UpdateLayout(2);
		return false;
	}
	
	this.ToggleVersion = function(checkbox) {
		if (checkbox.checked == false) {
			count = 0;
			for (i=0; i<conf.verinfo.length; i++) {
				if (conf.verinfo[i].show) count++;
			}
			if (count == 1) {
				checkbox.checked = true;
				return false;
			}
		}
		versions = "";
		for (i=0; i<conf.verinfo.length; i++) {
			if (conf.verinfo[i].versionid == checkbox.value) conf.verinfo[i].show = checkbox.checked;
			if (conf.verinfo[i].show) versions = versions + conf.verinfo[i].versionid + "+";
		}
		srcPrefix = conf.showbiblefile + "?version=" + versions + "&book=" + (view.bibleframes[0].contentid >> 8) + "&chapter=";
		view.bibleframes[0].node.src = srcPrefix + (view.bibleframes[0].contentid & 0xFF);
		view.bibleframes[1].node.src = srcPrefix + (view.bibleframes[1].contentid & 0xFF);
		view.bibleframes[2].node.src = srcPrefix + (view.bibleframes[2].contentid & 0xFF);
		this.UpdateSearchVersionDisplay();
		return false;
	}
	
	this.UpdateSearchVersionDisplay = function() {
		searchdisplay = "";
		for (i=0; i<conf.verinfo.length; i++) {
			if (conf.verinfo[i].show) {
				searchdisplay = searchdisplay + conf.verinfo[i].name_cshort + ", ";
			}
		}
		searchdisplay = searchdisplay.substring(0,searchdisplay.length-2);
		view.sidebar.search.versiondisplay.node.innerHTML = searchdisplay;
		return false;
	}
	
	this.ChapterInputChanged = function(chapter) {
		this.DisplayBibleText(state.contentid >> 8, Math.min(Math.max(1, chapter), conf.bookinfo[state.contentid >> 8].chap_cnt));
		return false;
	}
	
	this.ChapterBeginClicked = function() {
		if ((state.contentid & 0xFF) == 1 && (state.contentid >> 8) > 0) {
			this.DisplayBibleText((state.contentid >> 8)-1, 1);
		} else {
			this.DisplayBibleText((state.contentid >> 8), 1);
		}
		return false;
	}
	
	this.ChapterEndClicked = function() {
		if ((state.contentid & 0xFF) == conf.bookinfo[state.contentid >> 8].chap_cnt && (state.contentid >> 8) < 65) {
			this.DisplayBibleText((state.contentid >> 8)+1, 1);
		} else {
			this.DisplayBibleText(state.contentid >> 8, conf.bookinfo[state.contentid >> 8].chap_cnt);
		}
		return false;
	}
	
	this.ChapterPrevClicked = function() {
		if ((state.contentid & 0xFF) == 1 && (state.contentid >> 8) > 0) {
			this.DisplayBibleText((state.contentid >> 8)-1, conf.bookinfo[(state.contentid >> 8)-1].chap_cnt);
		} else {
			this.DisplayBibleText((state.contentid >> 8), Math.max(1, (state.contentid & 0xFF)-1));
		}
		return false;
	}
	
	this.ChapterNextClicked = function() {
		if ((state.contentid & 0xFF) == conf.bookinfo[state.contentid >> 8].chap_cnt && (state.contentid >> 8) < 65) {
			this.DisplayBibleText((state.contentid >> 8)+1, 1);
		} else {
			this.DisplayBibleText(state.contentid >> 8, Math.min(conf.bookinfo[state.contentid >> 8].chap_cnt, (state.contentid & 0xFF)+1));
		}
		return false;
	}
	
	this.ChapterFastPrevClicked = function() {
		if ((state.contentid & 0xFF) == 1 && (state.contentid >> 8) > 0) {
			this.DisplayBibleText((state.contentid >> 8)-1, conf.bookinfo[(state.contentid >> 8)-1].chap_cnt);
		} else {
			this.DisplayBibleText(state.contentid >> 8, Math.max(1, (state.contentid & 0xFF)-5));
		}
		return false;
	}
	
	this.ChapterFastNextClicked = function() {
		if ((state.contentid & 0xFF) == conf.bookinfo[state.contentid >> 8].chap_cnt && (state.contentid >> 8) < 65) {
			this.DisplayBibleText((state.contentid >> 8)+1, 1);
		} else {
			this.DisplayBibleText(state.contentid >> 8, Math.min(conf.bookinfo[state.contentid >> 8].chap_cnt, (state.contentid & 0xFF)+5));
		}
		return false;
	}
	
	this.SetSearchFrom = function(id) {
		view.sidebar.search.from.node.innerHTML = conf.bookinfo[id].name_clong;
		view.sidebar.search.from.bookid = id;
		return false;
	}
	
	this.SetSearchTo = function(id) {
		view.sidebar.search.to.node.innerHTML = conf.bookinfo[id].name_clong;
		view.sidebar.search.to.bookid = id;
		return false;
	}
	
	this.CheckSearchOrder = function() {
		if (view.sidebar.search.from.bookid == null || view.sidebar.search.to.bookid == null) return false;
		if (view.sidebar.search.from.bookid > view.sidebar.search.to.bookid) {
			var tempHTML = view.sidebar.search.from.node.innerHTML;
			view.sidebar.search.from.node.innerHTML = view.sidebar.search.to.node.innerHTML;
			view.sidebar.search.to.node.innerHTML = tempHTML;
			var tempid = view.sidebar.search.from.bookid;
			view.sidebar.search.from.bookid = view.sidebar.search.to.bookid;
			view.sidebar.search.to.bookid = bookid;
		}
		return false;
	}
	
	this.SearchFromToClicked = function(isFrom) {
		state.enterSearch = true;
		state.enterSearchFrom = isFrom;
		if (isFrom) 
			view.sidebar.search.from.node.innerHTML = view.sidebar.search.from.node.actionHTML;
		else
			view.sidebar.search.to.node.innerHTML = view.sidebar.search.to.node.actionHTML;		
		return false;
	}
	
	this.SearchRangeClicked = function(rangeid) {
		var from;
		var to;
		switch (rangeid) {
		case 1:
			from = 0;
			to = 38;
			break;
		case 2:
			from = 39;
			to = 65;
			break;
		case 0:
		default:
			from = 0;
			to = 65;
			break;
		}
		this.SetSearchFrom(from);
		this.SetSearchTo(to);
		this.CheckSearchOrder();
		return false;
	}
	
	this.SearchReset = function() {
		var obj = view.sidebar.search;
		obj.from.node.innerHTML = obj.from.node.defaultHTML || obj.from.node.innerHTML;
		obj.from.bookid = null;
		obj.to.node.innerHTML = obj.to.node.defaultHTML || obj.to.node.innerHTML;
		obj.to.bookid = null;
		obj.input.node.value = "";
		obj.resultframe.node.src = "about:blank";
		return false;
	}
	
	this.SearchNow = function() {
		var verStr = "";
		for (i=0; i<conf.verinfo.length; i++) {
			if (conf.verinfo[i].show) verStr = verStr + conf.verinfo[i].versionid + "+";
		}
		view.sidebar.search.resultframe.node.src = "searchresult.php?searchstr="+view.sidebar.search.input.node.value+"&bookidfrom="+(view.sidebar.search.from.bookid+1)+"&bookidto="+(view.sidebar.search.to.bookid+1)+"&versions="+verStr;
		view.sidebar.search.searchbtn.node.innerHTML = view.sidebar.search.searchbtn.node.actionHTML;
		return false;
	}
	
	this.SetPriBookmark = function() {
		SetCookie('pri_bookmark', state.contentid);
		this.UpdatePriBookmark();
		return false;
	}
	
	this.UpdatePriBookmark = function() {
		var contentid = parseInt(GetCookie('pri_bookmark'));
		if (contentid > 0) {
			var bookid = contentid >> 8;
			var chapid = contentid & 0xFF;
			view.sidebar.bookmark.pribtn.node.innerHTML = conf.bookinfo[bookid].name_clong + " " + chapid;
		} else {
			view.sidebar.bookmark.pribtn.node.innerHTML = view.sidebar.bookmark.pribtn.node.defaultHTML;
		}
		return false;
	}
	
	this.DisplayPriBookmark = function() {
		var contentid = parseInt(GetCookie('pri_bookmark'));
		if (contentid > 0) {
			var bookid = contentid >> 8;
			var chapid = contentid & 0xFF;
			this.DisplayBibleText(bookid, chapid);
		}
		return false;
	}
	
	this.SetSecBookmark = function() {
		var contentidstr = GetCookie('sec_bookmark');
		if (contentidstr != null) {
			var contentids = contentidstr.split('.');
			for (var i=0; i<contentids.length; i++) {
				if (parseInt(contentids[i]) == state.contentid) {
					alert(view.sidebar.bookmark.secselection.node.insertfail);
					return false;
				}
			}
		} else contentidstr = '';
		if (contentidstr != '') contentidstr = contentidstr + '.';
		contentidstr = contentidstr + state.contentid;
		SetCookie('sec_bookmark', contentidstr);
		this.UpdateSecBookmark();
		return false;
	}
	
	this.UpdateSecBookmark = function() {
		view.sidebar.bookmark.secselection.node.innerHTML = '';
		contentidstr = GetCookie('sec_bookmark');
		if (contentidstr != null) {
			var contentids = contentidstr.split('.');
			for (var i=0; i<contentids.length; i++) {
				newcontentid = parseInt(contentids[i]);
				if (newcontentid > 0) {
					var bookid = newcontentid >> 8;
					var chapid = newcontentid & 0xFF;
					var newoption = pDoc.createElement("option");
					view.sidebar.bookmark.secselection.node.options[view.sidebar.bookmark.secselection.node.options.length] = newoption;
					newoption.value = newcontentid;
					newoption.innerHTML = conf.bookinfo[bookid].name_clong + ' ' + chapid;
				}
			}
		}
		return false;
	}
	
	this.DisplaySecBookmark = function() {
		if (view.sidebar.bookmark.secselection.node.selectedIndex < 0) alert(view.sidebar.bookmark.secselection.node.openfail);
		else {
			var opencontentid = view.sidebar.bookmark.secselection.node.options[view.sidebar.bookmark.secselection.node.selectedIndex].value;
			this.DisplayBibleText(opencontentid >> 8, opencontentid & 0xFF);
		}
		return false;
	}
	
	this.RemoveSecBookmark = function() {
		if (view.sidebar.bookmark.secselection.node.selectedIndex < 0) alert(view.sidebar.bookmark.secselection.node.deletefail);
		else {
			var selected = view.sidebar.bookmark.secselection.node.options[view.sidebar.bookmark.secselection.node.selectedIndex];
			var contentidstr = GetCookie('sec_bookmark');
			var newcontentidstr = '';
			var contentids = contentidstr.split('.');
			for (var i=0; i<contentids.length; i++) {
				if (parseInt(contentids[i]) != selected.value) {
					if (newcontentidstr != '') newcontentidstr = newcontentidstr + '.';
					newcontentidstr = newcontentidstr + contentids[i];
				}
			}
			SetCookie('sec_bookmark', newcontentidstr);
			this.UpdateSecBookmark();
		}
		return false;
	}
	
	this.GetSideBarExpanded = function() {
		return view.sidebar.expanded;
	}
	
	this.SetSideBarExpanded = function(bool) {
		view.sidebar.expanded = bool;
		if (view.sidebar.expanded) {
			view.sidebar.tab.node.style.display = "block";
			if (view.sidebar.search.show) view.sidebar.search.node.style.display = "block";
			if (view.sidebar.bookmark.show) view.sidebar.bookmark.node.style.display = "block";
		} else {
			view.sidebar.tab.node.style.display = "none";
			view.sidebar.search.node.style.display = "none";
			view.sidebar.bookmark.node.style.display = "none";
		}
		return state.sideBarExpanded;
	}
	
	this.SetSideBarShow = function(textid) {
		state.sideBarShow = textid;
		if (state.sideBarShow == "search") {
			view.sidebar.tab.search.node.style.background = "#DDDDDD";
			view.sidebar.tab.bookmark.node.style.background = "#FFFFFF";
			view.sidebar.search.show = true;
			view.sidebar.search.node.style.display = "block";
			view.sidebar.bookmark.show = false;
			view.sidebar.bookmark.node.style.display = "none";
			SetCookie('isSideBarShowedSearch', '1')
		} else if (state.sideBarShow == "bookmark") {
			view.sidebar.tab.search.node.style.background = "#FFFFFF";
			view.sidebar.tab.bookmark.node.style.background = "#DDDDDD";
			view.sidebar.search.show = false;
			view.sidebar.search.node.style.display = "none";
			view.sidebar.bookmark.show = true;
			view.sidebar.bookmark.node.style.display = "block";
			SetCookie('isSideBarShowedSearch', '0')
		}		
		return false;
	}
	
	this.ClearRecord = function() {
		ClearCookie();
		this.UpdatePriBookmark();
		this.UpdateSecBookmark();
	}
	
}
