
// array of elements in selected dom
var Track_DomElementsArr = new Array();
// array of elements in selected dom tag names
var Track_DomElements_TAGNAME_Arr = new Array();
// array of elements in selected dom id's
var Track_DomElements_ID_Arr = new Array();
// array of elements in selected dom class names
var Track_DomElements_CLASS_Arr = new Array();
// array of rules matches found for selected dom
var Track_DomElements_MATCH_Arr = new Array();
// array of layers that used to display the elements location and dimensions
var Track_DimensionsLayersArr = new Array();

//------------------------------------

// the object hold the entire data of the element
function Track_DomElementData(HtmlElement)
{
	// the reference to the element
	this.HtmlElement = HtmlElement;
	// the rules collection match to the element
	this.RulesMatch = new Array();
	// the events collection match to the element
	this.EventsMatch = new Array();
	// the attributes collection match to the element
	this.AttributesMatch = new Array();
}

// the function get the srcElement and start bubbling up collecting the relevant data from the
// dom and insert it to the relevant arrays
function Track_AddElementsDataToArray(StartElement)
{
	try
	{
		Track_DomElementsArr.length = 0;
		Track_DomElements_TAGNAME_Arr.length = 0;
		Track_DomElements_ID_Arr.length = 0;
		Track_DomElements_CLASS_Arr.length = 0;
		Track_DomElements_MATCH_Arr.length = 0;
	
		var Track_DomElement = StartElement;
		var Track_Counter = 0;
	
		while (Track_DomElement.tagName.toLowerCase() != "html")
		{
			Track_DomElementsArr[Track_Counter] = new Track_DomElementData(Track_DomElement);
			Track_DomElements_TAGNAME_Arr[Track_Counter] = Track_DomElement.tagName.toLowerCase();
			Track_DomElements_ID_Arr[Track_Counter] = Track_DomElement.id.toLowerCase();
			Track_DomElements_CLASS_Arr[Track_Counter] = Track_DomElement.className.toLowerCase();
			Track_Counter ++;
			Track_DomElement = Track_DomElement.parentNode;
		}
		Track_DomElementsArr[Track_DomElementsArr.length] = new Track_DomElementData(document.getElementsByTagName("html").item(0));
	}
	catch(e){}
}

//-------------------------------

function Track_DisplayElementsWithLayers()
{
	var NewDimensionsLayer;
	for (var i = 1;i < Track_DomElementsArr.length;i ++)
	{
		if (! Track_DimensionsLayersArr[i])
		{
			NewDimensionsLayer = document.createElement("samp");
			document.body.appendChild(NewDimensionsLayer);
			NewDimensionsLayer.style.cssText = Track_DimensionsLayer_Css;
			Track_DimensionsLayersArr[i] = NewDimensionsLayer;
		}
		var DimensionsLayer = Track_DimensionsLayersArr[i];
		
		with (new Track_Obj_rectangle(Track_DomElementsArr[i].HtmlElement))
		{
			DimensionsLayer.style.display = "block";
			DimensionsLayer.style.zIndex = (100+i);
			DimensionsLayer.style.left = ObjLeft+"px";
			DimensionsLayer.style.top = ObjTop+"px";
			DimensionsLayer.style.width = ObjWidth+"px";
			DimensionsLayer.style.height = ObjHeight+"px";
		}
	}
}

//-------------------------------

function Track_UnDisplayElementsWithLayers()
{
	for(var i = 0;i < Track_DimensionsLayersArr.length;i ++)
	{
		if (! Track_DimensionsLayersArr[i]){return;}
		Track_DimensionsLayersArr[i].style.display = "none";
	}
}

//-------------------------------

// the function pass over the roles in the style sheets and compare them with the
// selected dom for find all the possible matches. then the matches inserted into
// the Track_DomElements_MATCH_Arr array
function Track_Parse_StyleSheets()
{
	// remove the #.* character from the rule string
	var Track_RulesReg = /[#.*]/g;
	// remove the white spaces from the rule sides
	var Track_Trim = /^\s+|\s+$/g;
	
	// the collection of the style sheets
	var Track_StyleSheetsColl = document.styleSheets;
	
	var Track_RulesColl;
	var h, i;
	var Track_SelectorTextStr;
	// the original rule name string
	var Track_OrgSelectorText;
	// the rule css string;
	var Track_CssText;
	// the rule name string after removing the #.* character
	var Track_SelectorText;
	for (i = 0;i < Track_StyleSheetsColl.length;i ++)
	{
		// the collection of the rules
		Track_RulesColl = document.styleSheets[i].rules;
		for (h = 0;h < Track_RulesColl.length;h ++)
		{
			Track_OrgSelectorText = Track_RulesColl(h).selectorText.toLowerCase();
			Track_CssText = Track_RulesColl(h).style.cssText.toLowerCase();
			Track_SelectorText = Track_OrgSelectorText.replace(Track_RulesReg, "");
			Track_SelectorText = Track_SelectorText.replace(Track_Trim,"");
			// get a string of the rule part could be match to the selected dom 
			Track_SelectorTextStr = Track_MatchRulesToHtmlDom(Track_SelectorText, -1);		
			// if the string returned from the function Track_MatchRulesToHtmlDom
			// equal to the rule string, the rule string will added to the
			// Track_DomElements_MATCH_Arr array
			if (Track_SelectorText == Track_SelectorTextStr)
			{
				Track_DomElements_MATCH_Arr[Track_DomElements_MATCH_Arr.length] = new Track_MatchRuleData(Track_OrgSelectorText, Track_SelectorText, Track_CssText);
			}
		}
	}
	Track_MatchRulesToElement();
}

//------------------------------

// the function get the string SelectorText which represent the rule string
// and a counter that represent the index of the data in the different data
// arrays that represent the elements and their relevant data
function Track_MatchRulesToHtmlDom(SelectorText, Track_DomElementsCounter)
{
	// create an array that hold the parts of the rule string. for example
	// the rule "#element_id li .element_class" means: element with the class 'element_class'
	// that found under the tag 'li' that located under the element with the id 'element_id'.
	// this array hold the different parts of it
	var Track_SelectorTextSplit = SelectorText.split(" ");
	var Track_DomElementsCounter = Track_DomElementsCounter;
	// the rule parts that found matches to the different elements in the selected dom
	// will be collected into this variable
	var Track_SelectorTextStr = "";
	
	// loop on the rule parts
	Track_SelectorTextSplitLabel:
	for (var i = Track_SelectorTextSplit.length - 1;i >= 0;i --)
	{
		Track_DomElementsCounter ++;
		// loop on the elements stored in the Track_DomElementsArr array starting
		// from the Track_DomElementsCounter index
		for (var g = Track_DomElementsCounter;g < Track_DomElementsArr.length;g ++)
		{
			Track_DomElementsCounter = g;
			// if rule part match to the elements tag name, the tag name will be the match
			if (Track_DomElements_TAGNAME_Arr[g] == Track_SelectorTextSplit[i])
			{
				Track_SelectorTextStr = Track_DomElements_TAGNAME_Arr[g] + " " + Track_SelectorTextStr;
				continue Track_SelectorTextSplitLabel;
			}
			// if rule part match to the elements id, the id name will be the match
			else if (Track_DomElements_ID_Arr[g] == Track_SelectorTextSplit[i])
			{
				Track_SelectorTextStr = Track_DomElements_ID_Arr[g] + " " + Track_SelectorTextStr;
				continue Track_SelectorTextSplitLabel;
			}
			// if rule part match to the elements class name, the class name name will be the match
			else if (Track_DomElements_CLASS_Arr[g] == Track_SelectorTextSplit[i])
			{
				Track_SelectorTextStr = Track_DomElements_CLASS_Arr[g] + " " + Track_SelectorTextStr;
				continue Track_SelectorTextSplitLabel;
			}
		}
	}
	// white spaces from the string sides removed and the string returned
	Track_SelectorTextStr = Track_SelectorTextStr.replace(/^\s+|\s+$/g,"");
	return Track_SelectorTextStr;
}

//------------------------------

// the function compare each element in the selected elements dom to the rules found
// and if the rules match to the element, it will added to the data displayed
// the rules are those who fined matched in general to one or more of the selected
// dom elements and now be pointed to the exact elements that they match to
function Track_MatchRulesToElement()
{
	var Track_IdiocraticArr;
	var Track_LastIdiocratic;
	var Track_SelectorText;
	var Track_SelectorTextStr;
	var e, g;
	
	for (e = 0;e < Track_DomElementsArr.length;e ++)
	{
		for (g = 0;g < Track_DomElements_MATCH_Arr.length;g ++)
		{
			// the rule
			Track_SelectorText = Track_DomElements_MATCH_Arr[g].ProcessedRuleText;
			// get a string of the rule part could be match to the selected dom starting
			// from the index of the loop
			Track_SelectorTextStr = Track_MatchRulesToHtmlDom(Track_SelectorText, e-1);
			
			// no match found, no need to check forward
			if (Track_SelectorTextStr == ""){continue;}
			
			// create an array that hold the parts of the rule string. for example
			// the rule "#element_id li .element_class" means: element with the class 'element_class'
			// that found under the tag 'li' that located under the element with the id 'element_id'.
			// this array hold the different parts of it
			Track_IdiocraticArr = Track_SelectorTextStr.split(" ");
			// the last part of the rules string
			Track_LastIdiocratic = Track_IdiocraticArr[Track_IdiocraticArr.length - 1];
			
			// if the last part of the rules string is equal to the 'tag name' of the element
			// or to the 'id name' of the element or to the 'class name' of the element,
			// the rule belong to this element
			if ((Track_LastIdiocratic == Track_DomElements_TAGNAME_Arr[e])||
			(Track_LastIdiocratic == Track_DomElements_ID_Arr[e])||
			(Track_LastIdiocratic == Track_DomElements_CLASS_Arr[e]))
			{
				Track_DomElementsArr[e].RulesMatch[Track_DomElementsArr[e].RulesMatch.length] = g;
			}
		}
	}
}

//------------------------------

// the object got the data of the rule match to the element
function Track_MatchRuleData(OrgSelectorText, ProcessedRuleText, CssText)
{
	// the rule selectorText (name) with original characters
	this.OrgSelectorText = OrgSelectorText;
	// the rule selectorText (name) after been Processed for comparing purposes
	this.ProcessedRuleText = ProcessedRuleText;
	// the css from the rule
	this.CssText = CssText;
}

//------------------------------

// the function loop on the attributes of the elements and collect them into the 
// relevants data arrays
function Track_Parse_Attributes()
{
	// loop on the selected elements dom
	for (var i = 0;i < Track_DomElementsArr.length;i ++)
	{
		// attributes collection
		var AttColl = Track_DomElementsArr[i].HtmlElement.attributes;
		var AttLength = AttColl.length;
		var AttNode, AttName, AttValue;
		
		// loop on the att collection
		for (var g = 0;g < AttLength;g ++)
		{
			AttNode = AttColl.item(g);
			bSpecified = AttNode.specified;
			// if attribute exist
			if (bSpecified)
			{
				AttName = AttNode.nodeName.toLowerCase();
				AttValue = AttNode.nodeValue;
				// if the attribute is event
				if (AttName.substring(0, 2) == "on")
				{
					// adding the att node to the EventsMatch array of the element
					Track_DomElementsArr[i].EventsMatch[Track_DomElementsArr[i].EventsMatch.length] = AttNode;
					continue;
				}
				// adding the att node to the AttributesMatch array of the element
				Track_DomElementsArr[i].AttributesMatch[Track_DomElementsArr[i].AttributesMatch.length] = AttNode;
			}
		}
	}
}

//------------------------------

function MarkDimensionLayer(LayerID)
{
	var ID = LayerID.split("TrackID_")[1];
	if (! Track_DimensionsLayersArr[ID]){return;}
	Track_DimensionsLayersArr[ID].style.backgroundColor = "blue";
}

function UnMarkDimensionLayer(LayerID)
{
	var ID = LayerID.split("TrackID_")[1];
	if (! Track_DimensionsLayersArr[ID]){return;}
	Track_DimensionsLayersArr[ID].style.backgroundColor = "";
}



// the function start the process of displaying the elements dom start from one element.
// the element to start from is the srcElement
function Track_DisplayElementsLayer()
{
	// clear the old data from the layer displayed it
	DataLayer.innerHTML = "";
	
	// call to function that loop on the elements from the srcElement bubbling up to the
	// top element of 'html' and add them to array
	Track_AddElementsDataToArray(Track_SrcElement);
	// call to function that loop on the rules and add the match ones to array
	Track_Parse_StyleSheets();
	// call to function that loop on the attributes and add the match ones to array
	Track_Parse_Attributes();
	
	Track_DisplayElementsWithLayers();
	
	var DomElement;
	var DomElementTagName;
	var DomElementsDiv;
	var DomCounter = 0;
	var EventsExist;
	var StylesExist;
	var AttributesExist;
	var RulesExist;
	
	// loop on the selected dom and build the html display of the elements
	for (var i = Track_DomElementsArr.length - 1;i >= 0;i --)
	{
		DomElement = Track_DomElementsArr[i].HtmlElement;
		DomElementTagName = DomElement.tagName;
		
		// display the elements tag name
		DomElementsDiv = document.createElement("samp");
		DomElementsDiv.id = "TrackID_"+i;
		DomElementsDiv.style.cssText = Track_Div_Css;
		DomElementsDiv.style.paddingLeft = (DomCounter * 20)+"px";
		DomElementsDiv.setAttribute("onmouseover", function(){MarkDimensionLayer(this.id);});
		DomElementsDiv.setAttribute("onmouseout", function(){UnMarkDimensionLayer(this.id);});
		
		DomElementsDiv.innerHTML = "&lt;"+DomElementTagName;
		
		// loop on the elements attributes
		var AttributesMatch = Track_DomElementsArr[i].AttributesMatch;
		var AttName, AttValue;
		for (var g = 0;g < AttributesMatch.length;g ++)
		{
			AttName = AttributesMatch[g].nodeName.toLowerCase();
			AttValue = AttributesMatch[g].nodeValue;
			// display only parts of the att with the tag name
			if ((AttName == "id") || (AttName == "class"))
			{
				DomElementsDiv.innerHTML = DomElementsDiv.innerHTML+" "+AttName+"='<samp style='"+Track_Att_Css+"'>"+AttValue+"</samp>'";
			}
		}
		// closing the tag display
		DomElementsDiv.innerHTML = DomElementsDiv.innerHTML+"&gt;";
		
		// find out which tabs to display near the tag name according
		// to the data been collected for the element
		RulesExist = Number(Track_DomElementsArr[i].RulesMatch.length);
		EventsExist = Number(Track_DomElementsArr[i].EventsMatch.length);
		AttributesExist = Number(Track_DomElementsArr[i].AttributesMatch.length);
		StylesExist = Number(Track_DomElementsArr[i].HtmlElement.style.cssText.length);
		
		// display the 'events' tab
		if (EventsExist)
		{
			DomElementsDiv.innerHTML = DomElementsDiv.innerHTML 
			+ " <samp style='"+Track_EventsExist_Css+"'"
			+ " onmousemove=\"Track_DisplayExpandedData('Events', '"+i+"')\""
			+ " onmouseover=\"Track_DisplayLayer('OpenDataLayer');\""
			+ " onmouseout=\"Track_HideLayer('OpenDataLayer');\""
			+ ">[events]</samp> ";
		}
		// display the 'style' tab
		if (StylesExist)
		{
			DomElementsDiv.innerHTML = DomElementsDiv.innerHTML 
			+ " <samp style='"+Track_StylesExist_Css+"'"
			+ " onmousemove=\"Track_DisplayExpandedData('Styles', '"+i+"')\""
			+ " onmouseover=\"Track_DisplayLayer('OpenDataLayer');\""
			+ " onmouseout=\"Track_HideLayer('OpenDataLayer');\""
			+ ">[styles]</samp> ";
		}
		// display the 'attributes' tab
		if (AttributesExist)
		{
			DomElementsDiv.innerHTML = DomElementsDiv.innerHTML 
			+ " <samp style='"+Track_AttributesExist_Css+"'"
			+ " onmousemove=\"Track_DisplayExpandedData('Attributes', '"+i+"')\""
			+ " onmouseover=\"Track_DisplayLayer('OpenDataLayer');\""
			+ " onmouseout=\"Track_HideLayer('OpenDataLayer');\""
			+ ">[attributes]</samp> ";
		}
		// display the 'rules' tab
		if (RulesExist)
		{
			DomElementsDiv.innerHTML = DomElementsDiv.innerHTML 
			+ " <samp style='"+Track_RulesExist_Css+"'"
			+ " onmousemove=\"Track_DisplayExpandedData('Class', '"+i+"')\""
			+ " onmouseover=\"Track_DisplayLayer('OpenDataLayer');\""
			+ " onmouseout=\"Track_HideLayer('OpenDataLayer');\""
			+ ">[rules]</samp> ";
		}
		// display the 'All' tab
		if ((EventsExist) || (StylesExist) || (AttributesExist) || (RulesExist))
		{
			DomElementsDiv.innerHTML = DomElementsDiv.innerHTML 
			+ " <samp style='"+Track_DataExist_Css+"'"
			+ " onmousemove=\"Track_DisplayExpandedData('All', '"+i+"')\""
			+ " onmouseover=\"Track_DisplayLayer('OpenDataLayer');\""
			+ " onmouseout=\"Track_HideLayer('OpenDataLayer');\""
			+ ">[all]</samp> ";
		}
		
		// adding the elements display to the document
		DataLayer.appendChild(DomElementsDiv);
		DomCounter ++;
	}
	Track_OnScroll();
}

//------------------------------------

// the fuction display the Expande data for the elements. it gets the data type
// request and the index of the element from the elements array and display its
// relevant data
function Track_DisplayExpandedData(DataType, DomElementIndex)
{
	var CssTextReg1 = /;/g;
	var CssTextReg2 = /:/g;
	// clear the old data
	OpenDataLayer.innerHTML = "";
	
	// if the request is for displaying the inline css of the element
	if ((DataType === "Styles") || (DataType === "All"))
	{
		// the css string
		var CssText = Track_DomElementsArr[DomElementIndex].HtmlElement.style.cssText.toLowerCase();
		if (CssText != "")
		{
			// specify parts of the string in a special style
			CssText = CssText.replace(CssTextReg1, "</samp>;<br />");
			CssText = CssText.replace(CssTextReg2, ":<samp style='"+Track_StylesExist_Css+"'>");
		
			OpenDataLayer.innerHTML = OpenDataLayer.innerHTML 
			+ "<samp style='"+Track_OpenDataLayer_MainTitle_Css+"'>"
			+ "Style belong to this element</samp>"
			+ "<samp style='"+Track_OpenDataLayer_SubTitle_Css+"'>Inline style:</samp>"
			+ "<samp style='"+Track_CssTextDiv_Css+"'>"+CssText+";</samp>";
		}
	}
	// if the request is for displaying the css rules of the element
	if ((DataType === "Class") || (DataType === "All"))
	{
		if (Track_DomElementsArr[DomElementIndex].RulesMatch.length)
		{
			var CssText, OrgSelectorText;
			OpenDataLayer.innerHTML = OpenDataLayer.innerHTML 
			+ "<samp style='"+Track_OpenDataLayer_MainTitle_Css+"'>"
			+ "Rules may belong to this element</samp>";
			
			// loop on the rules of the element
			for(var i = 0;i < Track_DomElementsArr[DomElementIndex].RulesMatch.length;i ++)
			{
				with (Track_DomElements_MATCH_Arr[Track_DomElementsArr[DomElementIndex].RulesMatch[i]])
				{
					// the css string
					ProcessedCssText = CssText+";";
					// specify parts of the string in a special style
					ProcessedCssText = ProcessedCssText.replace(CssTextReg1, "</samp>;<br />");
					ProcessedCssText = ProcessedCssText.replace(CssTextReg2, ":<samp style='"+Track_RulesExist_Css+"'>");
					
					OpenDataLayer.innerHTML = OpenDataLayer.innerHTML 
					+ "<samp style='"+Track_OpenDataLayer_SubTitle_Css+"'>Rule:</samp> "+OrgSelectorText
					+"<br />{<br /><samp style='"+Track_CssTextDiv_Css+"'>"+ProcessedCssText+"</samp>}<br />";
				}
			}
		}
	}
	// if the request is for displaying the Attributes of the element
	if ((DataType === "Attributes") || (DataType === "All"))
	{
		if (Track_DomElementsArr[DomElementIndex].AttributesMatch.length)
		{
			var AttName, AttValue;
			OpenDataLayer.innerHTML = OpenDataLayer.innerHTML 
			+ "<samp style='"+Track_OpenDataLayer_MainTitle_Css+"'>"
			+ "Attributes belong to this element</samp>";
			
			// loop on the attributes of the element
			for(var i = 0;i < Track_DomElementsArr[DomElementIndex].AttributesMatch.length;i ++)
			{
				with (Track_DomElementsArr[DomElementIndex].AttributesMatch[i])
				{
					AttName = nodeName;
					AttValue = nodeValue;
					if (AttName.toLowerCase() == "style"){AttValue = "[See style tab]";}
					OpenDataLayer.innerHTML = OpenDataLayer.innerHTML 
					+ "<samp style='"+Track_OpenDataLayer_SubTitle_Css+"'>Att:</samp> "+AttName+" = "
					+"&quot;<samp style='"+Track_AttributesExist_Css+"'>"+AttValue+"</samp>&quot;<br />";
				}
			}
		}
	}
	// if the request is for displaying the events of the element
	if ((DataType === "Events") || (DataType === "All"))
	{
		if (Track_DomElementsArr[DomElementIndex].EventsMatch.length)
		{
			var AttName, AttValue;
			OpenDataLayer.innerHTML = OpenDataLayer.innerHTML 
			+ "<samp style='"+Track_OpenDataLayer_MainTitle_Css+"'>"
			+ "Events belong to this element</samp>";
			
			// loop on the attributes of the element
			for(var i = 0;i < Track_DomElementsArr[DomElementIndex].EventsMatch.length;i ++)
			{
				with (Track_DomElementsArr[DomElementIndex].EventsMatch[i])
				{
					AttName = nodeName;
					AttValue = nodeValue;
					OpenDataLayer.innerHTML = OpenDataLayer.innerHTML 
					+ "<samp style='"+Track_OpenDataLayer_SubTitle_Css+"'>Event:</samp> "+AttName+" = "
					+"&quot;<samp style='"+Track_EventsExist_Css+"'>"+AttValue+"</samp>&quot;<br />";
				}
			}
		}
	}
	
	// placing the layer near the mouse
	//OpenDataLayer.style.left = (Track_ClientX + 10) +"px";
	//OpenDataLayer.style.top = (Track_FindScrollTop()+Track_ClientY + 10) +"px";
	OpenDataLayer.style.left = (event.clientX + 10) +"px";
	OpenDataLayer.style.top = (Track_FindScrollTop()+event.clientY + 10) +"px";
}


function Track_DisplayLayer(LayerID)
{
	var Layer = document.getElementById(LayerID);
	Layer.style.display = "block";
}

function Track_HideLayer(LayerID)
{
	var Layer = document.getElementById(LayerID);
	Layer.style.display = "none";
}

var Track_ClientX, Track_ClientY, Track_SrcElement;
function Track_onmousemove(e)
{
	//if (isMIE){e = event;}
	e = event;
	Track_ClientX = e.clientX;
	Track_ClientY = e.clientY;
	if (Track_Start_Tracking)
	{
		Track_SrcElement = e.srcElement;
	}
}

var Track_ApplyDataAction, Track_Start_Tracking;
function Track_OnKeyDown(e)
{
	Track_UnDisplayElementsWithLayers();
	//if (isMIE){e = event;}
	e = event;
	// F8
	if (e.keyCode == 119)
	{
		if (! Track_Start_Tracking)
		{
			Track_Start_Tracking = true;
			Track_SrcElement = e.srcElement;
		}
		else 
		{
			Track_Start_Tracking = false;
			Track_ApplyDataAction = false;
			Track_HideLayer('DataLayer');
			Track_HideLayer('OpenDataLayer');
		}
	}
	// F7
	if ((e.keyCode == 118) && (Track_Start_Tracking))
	{
		Track_DisplayLayer('DataLayer');
		Track_DisplayElementsLayer();
	}
	// F9
	if ((e.keyCode == 120) && (Track_Start_Tracking))
	{
		Track_ApplyDataAction = true;
		if (DataLayer.style.display == "block")
		{
			Track_HideLayer('DataLayer');
			Track_HideLayer('OpenDataLayer');
		}
		else
		{
			Track_DisplayLayer('DataLayer');
			Track_SrcElement = e.srcElement;
		}
		
		return;
		
	}
	Track_ApplyDataAction = false;
}

//-----------------------------------

// styles
var Track_DataLayer_Css = "width: 100px; "
+ "height: 50px; "
+ "background-color: white; "
+ "position: absolute; "
+ "left: 0px;"
+ "top: 0px;"
+ "z-index: 200; "
+ "border: 1px solid black; "
+ "display: none; "
+ "direction: ltr;"
+ "padding: 4px; "
+ "font-size: 12px;";

var Track_OpenDataLayer_Css = "background-color: white; "
+ "position: absolute; "
+ "top: 100px; "
+ "z-index: 200; "
+ "border: 1px solid black; "
+ "display: none; "
+ "direction: ltr;"
+ "text-align: left; "
+ "padding: 4px; "
+ "font-size: 12px;";

var Track_Div_Css = "direction: ltr;"
+ "font-size: 12px; "
+ "display: block; "
+ "white-space: nowrap";

var Track_OpenDataLayer_MainTitle_Css = "direction: ltr;"
+ "font-size: 14px; "
+ "font-weight: bold; "
+ "text-decoration: underline; "
+ "color: Teal; "
+ "display: block; "
+ "text-align: left";

var Track_OpenDataLayer_SubTitle_Css = "direction: ltr;"
+ "font-size: 13px; "
+ "font-weight: bold; "
+ "color: Purple; "
+ "text-align: left";

var Track_CssTextDiv_Css = "direction: ltr;"
+ "padding-left: 30px; "
+ "display: block; "
+ "text-align: left";


var Track_Att_Css = "color: red; "
+ " font-style: italic";

var Track_EventsExist_Css = "color: red; "
+ "font-weight: bold; "
+ " font-size: 11px";

var Track_StylesExist_Css = "color: blue; "
+ "font-weight: bold; "
+ " font-size: 11px";

var Track_RulesExist_Css = "color: green; "
+ "font-weight: bold; "
+ " font-size: 11px";

var Track_AttributesExist_Css = "color: brown; "
+ "font-weight: bold; "
+ " font-size: 11px";

var Track_DataExist_Css = "color: Lightseagreen; "
+ " font-size: 11px; "
+ " font-weight: bold; "
+ " text-decoration: underline;";

var Track_DimensionsLayer_Css = "display: none; "
+ " position: absolute; "
+ " filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=30); ";
//-------------------------------------


var DataLayer = document.createElement("samp");
DataLayer.id = "DataLayer";
DataLayer.style.cssText = Track_DataLayer_Css;
DataLayer.onkeydown = function(){event.cancelBubble = true; return false;}
DataLayer.onmousemove = function(){event.cancelBubble = true; return false;}

var OpenDataLayer = document.createElement("samp");
OpenDataLayer.id = "OpenDataLayer";
OpenDataLayer.style.cssText = Track_OpenDataLayer_Css;
OpenDataLayer.onkeydown = function(){event.cancelBubble = true; return false;}
OpenDataLayer.onmousemove = function(){event.cancelBubble = true; return false;}

document.body.appendChild(DataLayer);
document.body.appendChild(OpenDataLayer);

document.attachEvent('onmousemove',Track_onmousemove);
document.attachEvent('onkeydown',Track_OnKeyDown);
window.attachEvent('onscroll',Track_OnScroll);

function Track_FindScrollTop()
{
	if (document.documentElement && document.documentElement.scrollTop)
	{
		return document.documentElement.scrollTop;
	}
	return document.body.scrollTop;
}

function Track_OnScroll()
{
	DataLayer.style.top = Track_FindScrollTop()+"px";
}

function Track_Obj_rectangle(Obj)
{
	this.ObjLeft = findOffset(Obj, "offsetLeft");
	this.ObjWidth = Obj.offsetWidth;
	this.ObjRight = this.ObjLeft + this.ObjWidth;
	this.ObjTop = findOffset(Obj, "offsetTop");
	this.ObjHeight = Obj.offsetHeight;
	this.ObjBottom = this.ObjTop + this.ObjHeight;
	
	function findOffset(Obj, offset)
	{
		var NumValue = 0;
		
		var startOffsetDom = Obj;

		while (startOffsetDom.offsetParent)
		{
			NumValue = NumValue + startOffsetDom[offset];
			startOffsetDom = startOffsetDom.offsetParent;
		}
		return NumValue;
	}
}
