function isMSIE() {
	return navigator.userAgent.indexOf("MSIE") >= -1;
}

function ImageLoader() {
	this.imagesToLoad = 0;
	this.imagesLoaded = 0;
	this.complete = false;
}

ImageLoader.prototype.addImage = function(imgSrc) {
	var img = new Image();
	var self = this;
	img.onload = function() { self.imageLoaded() };
	img.src = imgSrc;
	this.imagesToLoad++;
	return img;
}

ImageLoader.prototype.imageLoaded = function() {
	this.imagesLoaded++;
	if (this.imagesLoaded >= this.imagesToLoad) {
		this.complete = true;
	}
}

function GlyphChart2(containerId, bgImgSrc, glyphImgSrc, glyphWidth, glyphHeight, glyphCoords, glyphCount) {
	this.containerId = containerId;
	this.imageLoader = new ImageLoader();
	this.bgImg = this.imageLoader.addImage(bgImgSrc);
	this.glyphImg = this.imageLoader.addImage(glyphImgSrc);
	this.glyphWidth = glyphWidth;
	this.glyphHeight = glyphHeight;
	this.glyphCoords = glyphCoords;
	this.glyphDivs = new Array();
	this.glyphCount = glyphCount;
	this.index = 0;
	this.loaded = false;
	this.checkRender();
}

GlyphChart2.prototype.getGlyphCount = function() {
	return this.glyphCount;
}

GlyphChart2.prototype.checkRender = function() {
	if (this.imageLoader.complete && document.getElementById(this.containerId)) {
		this.render();
	} else {
		var self = this;
		setTimeout(function() { self.checkRender(); }, 100);
	}
}

GlyphChart2.prototype.render = function() {

	// create main div
	var rootDiv = document.getElementById(this.containerId);
	rootDiv.style.position = "relative";
	rootDiv.style.zIndex = 10;
	
	// create the "background" image
	var bgDiv = document.createElement("DIV");
	bgDiv.style.position = "absolute";
	bgDiv.style.zIndex = 10;
	var bgImg = document.createElement("IMG");
	bgImg.src = this.bgImg.src;
	bgImg.style.zIndex = 11;
	bgDiv.appendChild(bgImg);
	rootDiv.appendChild(bgDiv);
	
	// add one cell per glyph
	for(var i = 0; i < this.glyphCoords.length; i++) {
		var glyphDiv = document.createElement("DIV");
		glyphDiv.id = "gc2_" + i;
		glyphDiv.style.position = "absolute";
		glyphDiv.style.left = this.glyphCoords[i][0] - i * this.glyphWidth;
		glyphDiv.style.top = this.glyphCoords[i][1];
		glyphDiv.style.width = this.glyphWidth;
		glyphDiv.style.clip = this.getClipString(i);
		glyphDiv.style.zIndex = 10 + i;
		var glyphImg = document.createElement("IMG");
		glyphImg.src = this.glyphImg.src;
		glyphDiv.appendChild(glyphImg);
		rootDiv.appendChild(glyphDiv);
		this.glyphDivs[i] = glyphDiv;
	}
}

GlyphChart2.prototype.getClipString = function(group) {
	var top = this.index * this.glyphHeight;
	var bottom = top + this.glyphHeight - 1;
	var left = group * this.glyphWidth;
	var right = left + this.glyphWidth - 1;
	return "rect(" + top + "px," + right + "px," + bottom + "px," + left + "px)";
}

GlyphChart2.prototype.setGlyph = function(index) {
	if (index < 0 || index >= this.glyphCount) { 
		return;
	}
	this.index = index;
	for(var i = 0; i < this.glyphDivs.length; i++) {
		this.glyphDivs[i].style.left = this.glyphCoords[i][0] - i * this.glyphWidth;
		this.glyphDivs[i].style.top = this.glyphCoords[i][1] - this.index * this.glyphHeight;
		this.glyphDivs[i].style.clip = this.getClipString(i);
	}
}

GlyphChart2.prototype.goGlyph = function(offset) {
	this.setGlyph(this.index + offset);
}

function GlyphSelector(containerId, glyphChart, nameImgSrc, prevImgSrc, nextImgSrc, nameWidth, nameHeight, nameIndices) {
	var self = this;
	this.containerId = containerId;
	this.glyphChart = glyphChart;
	this.imageLoader = new ImageLoader();
	this.nameImg = this.imageLoader.addImage(nameImgSrc);
	this.prevImg = this.imageLoader.addImage(prevImgSrc);
	this.nextImg = this.imageLoader.addImage(nextImgSrc);
	this.index = 0;
	this.nameWidth = nameWidth;
	this.nameHeight = nameHeight;
	this.nameIndices = nameIndices;
	this.checkRender();
}

GlyphSelector.prototype.checkRender = function() {
	if (this.imageLoader.complete && document.getElementById(this.containerId)) {
		this.render();
	} else {
		var self = this;
		setTimeout(function() { self.checkRender(); }, 100);
	}
}

GlyphSelector.prototype.render = function() {

	// create main div
	var rootDiv = document.getElementById(this.containerId);
	rootDiv.style.position = "relative";
	rootDiv.style.zIndex = 100;
	
	var left = 0;
	var self = this;
	
	// create the "background" image
	var prevDiv = document.createElement("DIV");
	prevDiv.style.position = "absolute";
	prevDiv.style.left = left;
	prevDiv.style.cursor = "pointer";
	prevDiv.style.zIndex = 100;
	prevDiv.onclick = function() { self.scroll(-1); };
	var prevImg = document.createElement("IMG");
	prevImg.src = this.prevImg.src;
	prevDiv.appendChild(prevImg);
	rootDiv.appendChild(prevDiv);
	left += prevImg.width;

	// create the "background" image
	var nameDiv = document.createElement("DIV");
	this.nameDiv = nameDiv;
	nameDiv.style.position = "absolute";
	nameDiv.style.left = left;
	nameDiv.style.top = 0;
	nameDiv.style.clip = this.getClipString(this.index);
	nameDiv.style.cursor = "pointer";
	nameDiv.style.zIndex = 900;
	nameDiv.onclick = function() { self.toggleNames(); }
	var nameImg = document.createElement("IMG");
	nameImg.src = this.nameImg.src;
	nameDiv.appendChild(nameImg);
	rootDiv.appendChild(nameDiv);
	
	var nameSelectorDiv = document.createElement("DIV");
	this.nameSelectorDiv = nameSelectorDiv;
	nameSelectorDiv.style.position = "absolute";
	nameSelectorDiv.style.left = left;
	nameSelectorDiv.style.top = this.nameHeight;
	nameSelectorDiv.style.display = "none";
	nameSelectorDiv.style.zIndex = 800;
	nameSelectorDiv.style.border = "1px solid #000000";
	var maxCols = 0;
	var nameIndex = 0;
	for(var row = 0; row < this.nameIndices.length; row++) {
		for(var col = 0; col < this.nameIndices[row].length; col++) {
			var nameSelCellDiv = document.createElement("DIV");
			nameSelCellDiv.style.position = "absolute";
			nameSelCellDiv.style.left = col * this.nameWidth;
			nameSelCellDiv.style.top = (row - nameIndex) * this.nameHeight;
			nameSelCellDiv.style.cursor = "pointer";
			nameSelCellDiv.style.clip = this.getClipString(nameIndex);
			nameSelCellDiv.style.zIndex = 600;
			nameSelCellDiv.onclick = clickGoMacro(self, nameIndex);
			var nameSelCellImg = document.createElement("IMG");
			nameSelCellImg.src = this.nameImg.src;
			nameSelCellDiv.appendChild(nameSelCellImg);
			nameSelectorDiv.appendChild(nameSelCellDiv);
			nameIndex++;
		}
		if (this.nameIndices[row].length > maxCols) {
			maxCols = this.nameIndices[row].length;
		}
	}
	nameSelectorDiv.style.width = maxCols * this.nameWidth + (isMSIE() ? 2 : 0);
	nameSelectorDiv.style.height = this.nameIndices.length * this.nameHeight + (isMSIE() ? 2 : 0);
	nameSelectorDiv.style.backgroundColor = "#ddccbb";
	rootDiv.appendChild(nameSelectorDiv);

	left += nameImg.width;

	// create the "background" image
	var nextDiv = document.createElement("DIV");
	nextDiv.style.position = "absolute";
	nextDiv.style.left = left;
	nextDiv.style.cursor = "pointer";
	nextDiv.style.zIndex = 700;
	nextDiv.onclick = function() { self.scroll(1); };
	var nextImg = document.createElement("IMG");
	nextImg.src = this.nextImg.src;
	nextDiv.appendChild(nextImg);
	rootDiv.appendChild(nextDiv);
}

function clickGoMacro(self, idx) {
	return function() { self.go(idx); self.hideNames() }
}

GlyphSelector.prototype.getClipString = function(index) {
	var top = index * this.nameHeight;
	var bottom = top + this.nameHeight - 1;
	var left = 0;
	var right = left + this.nameWidth - 1;
	return "rect(" + top + "px," + right + "px," + bottom + "px," + left + "px)";
}

GlyphSelector.prototype.scroll = function(offset) {
	var index = this.index + offset;
	this.go(index);
}

GlyphSelector.prototype.go = function(index) {
	if (index < 0 || index >= this.glyphChart.getGlyphCount()) {
		return;
	}
	this.index = index;
	this.glyphChart.setGlyph(index);
	this.nameDiv.style.top = -this.index * this.nameHeight;
	this.nameDiv.style.clip = this.getClipString(this.index);
}

GlyphSelector.prototype.showNames = function() {
	this.nameSelectorDiv.style.display = "block";
}

GlyphSelector.prototype.hideNames = function() {
	this.nameSelectorDiv.style.display = "none";
}

GlyphSelector.prototype.toggleNames = function() {
	if (this.nameSelectorDiv.style.display == "none") {
		this.nameSelectorDiv.style.display = "block";
	} else {
		this.nameSelectorDiv.style.display = "none";
	}
}


