function addEvent(elm, evType, fn, useCapture) {
  // cross-browser event handling for IE5+, NS6 and Mozilla 
  // By Scott Andrew 
  if (elm.addEventListener) { 
    elm.addEventListener(evType, fn, useCapture); 
    return true; 
  } else if (elm.attachEvent) { 
    var r = elm.attachEvent('on' + evType, fn); 
    return r; 
  } else {
    elm['on' + evType] = fn;
	return null
  }
}

function removeEvent(elm, evType, fn) {
  if (elm.removeEventListener) { 
    elm.removeEventListener(evType, fn, false); 
    return true; 
  } else if (elm.attachEvent) { 
    var r = elm.detachEvent('on' + evType, fn); 
    return r; 
  } else {
    elm['on' + evType] = null;
	return null
  }
}


// climb up the tree to the supplied tag 
function ascendDOM(e, tag, stopTag) {
  	while ((e.nodeName.toLowerCase() != tag) && (e.nodeName.toLowerCase() != stopTag)) {
    		e = e.parentNode;
	}
  return (e.nodeName.toLowerCase() == stopTag) ? null : e;
}


		function getRowColumn(e) {
		// return table/row/cell coordinates
		// requires ascendDOM
			var rowColumn = new Array(1);
			
			// save this td or th
			var t = ascendDOM(e, 'td', 'table');
			if (t == null) {
				t = ascendDOM(e, 'th', 'table');
				if (t == null) return false;
			}			

			// locate parent row
			var parent_row = ascendDOM(t, 'tr', 'table');
			if (parent_row == null) return false;
	
			
			// locate table  
			parent_table = ascendDOM(t, 'tbody', 'table');

			// get row index (avoiding .rowIndex for Safari compatibility) 
			var ri = -1;
			for (var i = 0; i < parent_table.rows.length; i++) {
				if (parent_row === parent_table.rows[i]) {
					ri = i;
				}
			}
			if (ri == -1) return null; // error
			rowColumn[1] = ri
			
			var parent_table = ascendDOM(parent_row, 'table', 'html');
			if (parent_table == null) return false;
			rowColumn[0] = parent_table.id	
			
			// get column index (avoiding .cellIndex for Safari compatibility) 
			var ci = -1;
			for (var i = 0; i < parent_row.cells.length; i++) {
				if (t === parent_row.cells[i]) {
					ci = i;
				}
			}
			if (ci == -1) return null; // error
			rowColumn[2] = ci

			return rowColumn; // array containing [0] => tableId [1] => rowNumber of Cell [2] => columnNumber of Cell 
			
		}



















		function highlightRowColumnCell(e, onOff, highlightClassString) {
		
/*
			highlights/unhighlights row, column and cell using element e
			when onOff = true -> highlight, when onOff = false -> unhighlight
			adds Row, Column and Cell to highlightClassString to make class names
			define class names {highlighClassString}Row, {highlighClassString}Column and {highlighClassString}Cell 
*/
			
			var el;
			if (window.event && window.event.srcElement)
			el = window.event.srcElement;
			if (e && e.target)
			el = e.target;
			if (!el) return;

			el = ascendDOM(el, 'td', 'table');
			if (el == null) return;

			var parent_row = ascendDOM(el, 'tr', 'table');
			if (parent_row == null) return;

			var parent_table = ascendDOM(parent_row, 'table', 'body');
			if (parent_table == null) return;

			var r = new RegExp (highlightClassString + "row|" + highlightClassString + "column|" + highlightClassString + "cell", "gi"); // 		
			if(onOff) {
				parent_row.className +=  " " + highlightClassString + "Row ";
			}
			else {
				parent_row.className = parent_row.className.replace(r, ' ');
			}

			// column styling
			var ci = -1;
			for (var i = 0; i < parent_row.cells.length; i++) {
				if (el === parent_row.cells[i]) {
					ci = i;
				}
			}
			if (ci == -1) return; // this should never happen

			// set/unset the column classes 
			for (var i = 0; i < parent_table.rows.length; i++) {
				var cell = parent_table.rows[i].cells[ci];
				
				var suffix = "Column "
				if(cell == el) suffix = "Cell "
				if(onOff) {
					cell.className +=  " " + highlightClassString + suffix;
				}
				else {
					cell.className = cell.className.replace(r, '  ');
				}
			}
					
			
		}

		var newCell;
		var thisCell;
		function handleEvent(e) {
			var eTarget;
			if (window.event && window.event.srcElement)	{
				eTarget = window.event.srcElement;
				window.event.cancelBubble = true;
			}
			if (e && e.target) {
				eTarget = e.target;
				e.stopPropagation();
			}
			if (!eTarget) return false;

			var t = ascendDOM(eTarget, 'table', 'html');

			if( t != null) {
				// only if the event is within a table
				var containerDiv = ascendDOM(t, 'div', 'html');
				if((containerDiv === null) || (containerDiv.id != "ntt")) return false; // only if inside a designated div
				var tableId = t.id
				if(eTarget.id == tableId + 'TopLeft') return false; // and not top left cell of layout view
				
				
				if(e.type == 'mouseover') highlightRowColumnCell(e, true, 'highlight');
				if(e.type == 'mouseout') highlightRowColumnCell(e, false, 'highlight');
				
				if(e.type == 'click') {
				
					eTarget.className = eTarget.className.replace(/fade/gi, " ");
					
					// first handle click on layout links in th tags
                    if(eTarget.nodeName.toLowerCase() == 'a') {
                    	if(eTarget.className.toLowerCase().indexOf("row") != -1) {
                    		addRemoveRow(eTarget);// working on rows
                    	}
                         if(eTarget.className.toLowerCase().indexOf("column") != -1) {
                         	addRemoveColumn(eTarget);// working on columns
                         }						
						return false
                    }
							
					//  now handle clicks in the table data in td tags		
					newCell = ascendDOM(eTarget, 'td', 'table')
					removeEvent(newCell, 'click', handleEvent); // disable event until after update
					var thisImage = null;

					
					// catch a second click on an input element
					 if(eTarget.nodeName.toLowerCase() == 'input') {
					 	return false
					 }

                    for(var i = 0; i < newCell.childNodes.length; i++) {
                    	if(newCell.childNodes[i].nodeName.toLowerCase() == 'img') thisImage = newCell.childNodes[i];
                    }
                    if(thisImage != null) {
                         // there's an image in this cell
                         if(e.shiftKey) {
                              // shift-click -> so replace image with text
                              newCell.removeChild(thisImage); // remove the image
                              cellInput(newCell); // create a form/input -> get the text
                         }
                         else {
                              // deal with image (action changes according to the layer we're in)
                              var thisImageSrc = thisImage.getAttribute('src');
                              imageBrowse(newCell, thisImage); 
                         }
                    }						
					else {
						// no image in this cell
						if(e.shiftKey) {
							// it's a shift-click -> deal with image (action changes according to the layer we're in)
							imageBrowse(newCell, thisImage);
						}
						else {
								cellInput(newCell); // create a form/input
						}
					}
				}	               
          

				//if((e.type != 'mouseover')  && (e.type != 'mouseout')) alert(e.type);


				if(e.type == 'blur') {
					if(eTarget.nodeName.toLowerCase() == 'input') passCellDataNew(eTarget); // only onblur for input tag
				}

               if(e.type == 'change') {
					// must be a change from a select element
               	passCellDataNew(eTarget);
               }

				if(e.type == 'submit') {
					stopBubble(e)
					passCellDataNew(eTarget)
					return false
				}
				return false
			}

          if(e.type == 'dblclick') {
          	// a double! click outside a table -> no action
				return false;
          }			
			else return false;
		}

function cancelEvent(e) {
	//return false;
}

// here's the bit that installs the listeners

function addListeners(tag, event, action) {
  if (!document.getElementById)
    return;

  var tags = document.getElementsByTagName(tag);
  for (var i = 0; i < tags.length; i++) {
    addEvent(tags[i], event, handleEvent, false);
    tags[i].action = cancelEvent; // handle Safari non-standard behaviour
  }
}

function removeListeners(tag, event, action) {
  if (!document.getElementById)
    return;

  var tags = document.getElementsByTagName(tag);
  for (var i = 0; i < tags.length; i++) {
    removeEvent(tags[i], event, handleEvent, false);
    tags[i].action = cancelEvent; // handle Safari non-standard behaviour
  }
}


function stopBubble(e) {
          if (e && e.stopPropagation && e.preventDefault) {
          	e.stopPropagation();
				e.preventDefault();
				return false;
          }
          if (window.event) {
         	 	window.event.cancelBubble = true;
				window.event.returnValue = false;
				return false;
          }	
			return true
}

addEvent(window, 'load', addListeners, false);

