/******************************************************************************
* pgCssInspector.js
*******************************************************************************

*******************************************************************************
*                                                                             *
* Copyright 2006									                          *
*                                                                             *
******************************************************************************/

function PgCssSelector(elementName, id, className, qualifier)
{
	var isXhtml = pgCssInspector.isXhtml();
	if(elementName != "") this.elementName = isXhtml ? elementName : elementName.toLowerCase();
	if(id != "") this.id = id.substr(1);
	if(className != "") this.className = isXhtml ? className.substr(1): className.substr(1).toLowerCase();
	if(qualifier != "") this.qualifier = qualifier.substr(1).toLowerCase();
}

PgCssSelector.prototype.match = function(element)
{
	var isXhtml = pgCssInspector.isXhtml();
	if(this.elementName != null) {
		var elementName = isXhtml ? element.tagName: element.tagName.toLowerCase();
		if(elementName != this.elementName) return false;
	}
	if(this.id != null) {
		if(element.id != this.id) return false;
	}
	if(this.className != null) {
		var className = isXhtml ? element.className: element.className.toLowerCase();
		if(className != this.className) return false;
	}
	return true;
}
function PgElementStyle(element)
{
	this.element = element;
}

PgElementStyle.prototype.getValue = function(name)
{
	return this.element.style[name];
}
PgElementStyle.prototype.select = function()
{
	var doc = pgCssInspector.window.document;
	var ruleDescription = doc.getElementById("ruleDescription");
	var ruleDescriptionTitle = doc.getElementById("ruleDescriptionTitle");
	var ruleDescriptionBody = doc.getElementById("ruleDescriptionBody");
	var ruleDescriptionPath = doc.getElementById("ruleDescriptionPath");
	ruleDescription.style.display = "block";
	var styleAttribute = this.element.getAttribute("style");
	debugger;
	ruleDescriptionTitle.innerHTML = styleAttribute + "";
	ruleDescriptionPath.innerHTML = "Elément " + pgCssInspector.getElementLabel(this.element);
	ruleDescriptionBody.innerHTML = this.element.style.cssText.replace(/;/g, ";<br/>");
}

function PgRuleStyle(stylesheet, rule)
{
	this.stylesheet = stylesheet;
	this.rule = rule;
}

PgRuleStyle.prototype.getValue = function(name)
{
	return this.rule.style[name];
}

PgRuleStyle.prototype.select = function()
{
	var doc = pgCssInspector.window.document;
	var ruleDescription = doc.getElementById("ruleDescription");
	var ruleDescriptionTitle = doc.getElementById("ruleDescriptionTitle");
	var ruleDescriptionBody = doc.getElementById("ruleDescriptionBody");
	var ruleDescriptionPath = doc.getElementById("ruleDescriptionPath");
	ruleDescription.style.display = "block";
	ruleDescriptionTitle.innerHTML = this.rule.selectorText;
	ruleDescriptionPath.innerHTML = this.stylesheet.href;
	ruleDescriptionBody.innerHTML = this.rule.style.cssText.replace(/;/g, ";<br/>");
	if(pgCssInspector.selectedRule != null) {
		pgCssInspector.selectedRule.li.className = "";
		pgCssInspector.selectedRule = null;
	}
	if(this.li != null) {
		this.li.className = "selected";
		pgCssInspector.selectedRule = this;
	}
}

function PgCssInspector()
{
	this.active = false;
	this.keyCounter = 0;
	this.objects = new Object();
}
PgCssInspector.prototype.ignoredProperties = {
cssText:1, accelerator:1
}
PgCssInspector.prototype.propertyType = {
"fontFamily":1,
"fontSize":1,
"textAlign":1,
"color":1,
"backgroundColor":1
}
PgCssInspector.prototype.selectElement = function(evt)
{
	if(this != pgCssInspector) return pgCssInspector.selectElement(evt);
	evt || (evt = window.event);
	var element;
	if (document.all != null) {
		element = evt.srcElement;
	} else {
		element = evt.currentTarget;
	}
	this.pivotElement = element;
	this.select(element);
}

PgCssInspector.prototype.getElementLabel = function(element)
{
	var name = element.tagName;
	var id = element.id;
	if(id != "") {
		name += "#" + id;
	}
	var className = element.className;
	if(className != "") name += "." + className;
	return name;
}

PgCssInspector.prototype.addAncestor = function(ancestorBar, ancestor, depth)
{
	if(ancestor == null || ancestor.nodeType != 1) return;
	this.addAncestor(ancestorBar, ancestor.parentElement, depth+1);
	var doc = this.window.document;
	var li = doc.createElement("li");
	ancestorBar.appendChild(li);
	var name = this.getElementLabel(ancestor);
	var html = "<a href='#' onclick='pgCssInspector.selectAncestor(" + depth + ");return false;'>" + name + "</a>";
	if(depth != 0) html += " &gt; ";
	li.innerHTML = html;
}

PgCssInspector.prototype.matchSelectors = function(element, selectors, index)
{
	if(element == null || element.nodeType != 1) return false;
	var selector = selectors[index];
	if(selector.match(element)) {
		if(selectors.length == index + 1) return true;
		if(this.matchSelectors(element.parentNode, selectors, index +1)) return true;
	}
	return this.matchSelectors(element.parentNode, selectors, index);
}

PgCssInspector.prototype.matchSelector = function(element, selector)
{
	var pos = selector.indexOf(",");
	if(pos > 0) {
		var selectors = selector.split(",");
		for(var i=0;i<selectors.length;i++) {
			if(this.matchSelector(element, selectors[i])) return true;
		}
		return false;
	}
	var ancestorMatches = selector.split(" ");
	var regExp = /^\s*([a-z0-9]+)?(\#[-_a-z0-9]+)?(\.[-_a-z0-9]+)?(\:[-_a-z0-9]+)?\s*$/i;
	var selectors = new Array();
	for(var i=ancestorMatches.length-1;i>=0;i--) {
		var ancestorMatch = ancestorMatches[i];
		var match = regExp.exec(ancestorMatch);
		if(match == null) {
			consoleDump("#### '" + ancestorMatch +"'");
			continue;
		}
		if(match[1] == "" && match[2] == "" && match[3] == "" && match[4] == "") continue;
		selectors[selectors.length] = new PgCssSelector(match[1], match[2], match[3], match[4]);
	}
	if(selectors.length == 0) return false;
	var firstSelector = selectors[0];
	if(!firstSelector.match(element)) return false;
	if(selectors.length > 1) {
		if(!this.matchSelectors(element.parentElement, selectors, 1)) return false;
	}
	return true;
}

PgCssInspector.prototype.getStylesheetRules = function(element, stylesheet, rules)
{
	if(rules == null) rules = new Array();
	for(var i=0;i<stylesheet.rules.length;i++) {
		var rule = stylesheet.rules[i];
		if(this.matchSelector(element, rule.selectorText)) {
			rules[rules.length] = new PgRuleStyle(stylesheet, rule);
		}
	}
	return rules;
}

PgCssInspector.prototype.getRules = function(element, rules)
{
	if(rules == null) rules = new Array();
	for(var i=0;i<document.styleSheets.length;i++) {
		var stylesheet = document.styleSheets[i];
		this.getStylesheetRules(element, stylesheet, rules);
	}
	return rules;
}

PgCssInspector.prototype.studyElement = function(element, map, depth)
{
	var elementStyle = new PgElementStyle(element); 
	for(var key in element.style) {
		if(map[key] != null) continue;
		if(this.ignoredProperties[key]) continue;
		if(depth > 0 && !(this.propertyType[key] & 1)) continue;
		var value = element.style[key];
		if(typeof(value) != "string") continue;
		if(value == "") continue;
		map[key] = elementStyle;
	}
	var doc = this.window.document;
	var ruleList = doc.getElementById("ruleList");
	var rules = this.getRules(element);
	for(var i=rules.length-1;i>=0;i--) {
		var rule = rules[i];
		var li = rule.li = doc.createElement("li");
		var key = this.registerObject(rule);
		li.innerHTML = "<a href='#' onclick='pgCssInspector.selectObject(\"" + key + "\");return false;'>" + rule.rule.selectorText + "</a>";
		ruleList.appendChild(li);
		for(var key in rule.rule.style) {
			if(map[key] != null) continue;
			if(this.ignoredProperties[key]) continue;
			if(depth > 0 && !(this.propertyType[key] & 1)) continue;
			var value = rule.rule.style[key];
			if(typeof(value) != "string") continue;
			if(value == "") continue;
			map[key] = rule;
		}
	}
	var parent = element.parentNode;
	if(parent == null || parent.nodeType != 1) return;
	this.studyElement(parent, map, depth + 1);
}

PgCssInspector.prototype.select = function(element)
{
	if(this.window == null) return;
	this.selectedElement = element;
	var doc = this.window.document;
	var startMessage = doc.getElementById("startMessage");
	startMessage.style.display = "none";	
	var resultPanel = doc.getElementById("resultPanel");
	resultPanel.style.display = "block";
	var elementTitle = doc.getElementById("elementTitle");
	elementTitle.innerHTML = "Elément " + this.getElementLabel(element);
	var ancestorBar = doc.getElementById("ancestorBar");
	var propertyList = doc.getElementById("propertyList");
	while(ancestorBar.firstChild) ancestorBar.removeChild(ancestorBar.firstChild);
	this.addAncestor(ancestorBar, this.pivotElement, 0);
	var ruleList = doc.getElementById("ruleList");
	while(ruleList.firstChild) ruleList.removeChild(ruleList.firstChild);
	this.selectedPropertyLine = null;
	this.selectedRule = null;
	var map = this.propertyMap = new Object();
	this.propertyLines = new Object();
	this.studyElement(element, map, 0);
	var list = new Array();
	for(var k in map) list[list.length] = k;
	list = list.sort();
	while(propertyList.firstChild) propertyList.removeChild(propertyList.firstChild);
	for(var i=0;i<list.length;i++) {
		var k = list[i];
		var styleProvider = map[k];
		var value = styleProvider.getValue(k);
		var li = doc.createElement("li");
		if(styleProvider.li == null) styleProvider.li = li;
		this.propertyLines[k] = li;
		li.innerHTML = "<a href='#' onclick='pgCssInspector.selectProperty(\"" + k + "\");return false;'>" + k + "=" + value + "</a>";
		propertyList.appendChild(li);
	}
	this.window.focus();
}
PgCssInspector.prototype.selectAncestor = function(depth)
{
	var ancestor = this.pivotElement;
	while(ancestor && ancestor.nodeType == 1) {
		if(depth-- == 0) return this.select(ancestor);
		ancestor = ancestor.parentElement;
	}
}
PgCssInspector.prototype.start = function()
{
	this.active = true;
	if(this.window == null) {
		this.getWindow();
	}
	document.focus();
	this.addEvent(document, "dblclick", this.selectElement)
}

PgCssInspector.prototype.stop = function()
{
	this.active = false;
	if(this.window != null) {
		this.window.close();
		this.window = null;
	}

}

PgCssInspector.prototype.toggle = function()
{
	if(this.active) this.stop();
	else this.start();
}

PgCssInspector.prototype.getWindow = function()
{
	var width = "800";
	var height = "400";
	var leftPos = (screen.availWidth - width) / 2;
	var topPos = (screen.availHeight - height) / 2;
	var options = 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos;
	var w = this.window = window.open("./iso_scripts/pgCssInspectorPage.html", "cssWindow", options)
	return w;
}

PgCssInspector.prototype.addEvent = function(element, evname, func)
{
	if (element.attachEvent) { // IE
		element.attachEvent("on" + evname, func);
	} else if (element.addEventListener) { // Gecko / W3C
		element.addEventListener(evname, func, true);
	} else {
		element["on" + evname] = func;
	}
}

PgCssInspector.prototype.removeEvent = function(element, evname, func)
{
	if (element.detachEvent) { // IE
		element.detachEvent("on" + evname, func);
	} else if (element.removeEventListener) { // Gecko / W3C
		element.removeEventListener(evname, func, true);
	} else {
		element["on" + evname] = null;
	}
}
PgCssInspector.prototype.getKey = function()
{
	return "k" + this.keyCounter++;
}



PgCssInspector.prototype.selectProperty = function(key)
{
	var object = this.propertyMap[key];
	var li = this.propertyLines[key];
	if(this.selectedPropertyLine != null) {
		this.selectedPropertyLine.className = "";
		this.selectedPropertyLine = null;
	}
	if(li != null) {
		li.className = "selected";
		pgCssInspector.selectedPropertyLine = li;
	}
	if(object == null) return;
	object.select();
}

PgCssInspector.prototype.selectObject = function(key)
{
	var object = this.objects[key];
	if(object == null) return;
	object.select();
}

PgCssInspector.prototype.registerObject = function(object)
{
	if(object.key == null) object.key = this.getKey();
	this.objects[object.key] = object;
	return object.key;
}
PgCssInspector.prototype.isXhtml = function()
{
	if(this.xhtml != null) return this.xhtml;
	this.xhtml = document.body.parentNode.getAttribute("xmlns") != null;
	return this.xhtml;
}
PgCssInspector.prototype.dropWindow = function()
{
	this.window = null;
	if(this.button) {
		this.button.setState(false);
	}
	this.active = false;
}
PgCssInspector.prototype.setButton = function(button)
{
	this.button = button;
}
var pgCssInspector = new PgCssInspector()

