/** @namespace _global_ */
if (typeof _global_ === "undefined") {
    _global_ = {
        /** @scope _global_ */

        /**
         * @function ['@namespace']
         * @param {string} str - dot separated namespace identifier
         * Example:
         * _global_["@namespace"]("foo.bar.something");
         * foo.bar.something.else = function() {};
         */
        "@namespace": function (str) {
            var a = str.split(".");
            var o = window;
            for(var i=0; i < a.length; i++) {
                if (!o[a[i]]) {
                    o[a[i]] = {};
                }
                o = o[a[i]];
            }
        }
    }
};

function addLoadEvent(func) {
	/* from Patt */
	
    var oldonload = window.onload;
    if (typeof window.onload != "function") {
        window.onload = func;
    } else {
        window.onload = function(){
            oldonload();
            func();
        }
    }

}

function object(o) {
     function F() {}
     F.prototype = o;
     return new F();
}

/*
 * Date Format 1.2.1
 * (c) 2007-2008 Steven Levithan <stevenlevithan.com>
 * MIT license
 * Includes enhancements by Scott Trenda <scott.trenda.net> and Kris Kowal <cixar.com/~kris.kowal/>
 *
 * Accepts a date, a mask, or a date and a mask.
 * Returns a formatted version of the given date.
 * The date defaults to the current date/time.
 * The mask defaults to dateFormat.masks.default.
 */
var dateFormat = function () {
	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip = /[^-+\dA-Z]/g,
		pad = function (val, len) {
			val = String(val);
			len = len || 2;
			while (val.length < len) val = "0" + val;
			return val;
		};

	// Regexes and supporting functions are cached through closure
	return function (date, mask, utc) {
		var dF = dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
		if (arguments.length == 1 && (typeof date == "string" || date instanceof String) && !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date = date ? new Date(date) : new Date();
		if (isNaN(date)) throw new SyntaxError("invalid date");

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var	_ = utc ? "getUTC" : "get",
			d = date[_ + "Date"](),
			D = date[_ + "Day"](),
			m = date[_ + "Month"](),
			y = date[_ + "FullYear"](),
			H = date[_ + "Hours"](),
			M = date[_ + "Minutes"](),
			s = date[_ + "Seconds"](),
			L = date[_ + "Milliseconds"](),
			o = utc ? 0 : date.getTimezoneOffset(),
			flags = {
				d:    d,
				dd:   pad(d),
				ddd:  dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D + 7],
				m:    m + 1,
				mm:   pad(m + 1),
				mmm:  dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m + 12],
				yy:   String(y).slice(2),
				yyyy: y,
				h:    H % 12 || 12,
				hh:   pad(H % 12 || 12),
				H:    H,
				HH:   pad(H),
				M:    M,
				MM:   pad(M),
				s:    s,
				ss:   pad(s),
				l:    pad(L, 3),
				L:    pad(L > 99 ? Math.round(L / 10) : L),
				t:    H < 12 ? "a"  : "p",
				tt:   H < 12 ? "am" : "pm",
				T:    H < 12 ? "A"  : "P",
				TT:   H < 12 ? "AM" : "PM",
				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
				o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
				S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
			};

		return mask.replace(token, function ($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
}();

// Some common format strings
dateFormat.masks = {
	"default":      "ddd mmm dd yyyy HH:MM:ss",
	shortDate:      "m/d/yy",
	mediumDate:     "mmm d, yyyy",
	longDate:       "mmmm d, yyyy",
	fullDate:       "dddd, mmmm d, yyyy",
	shortTime:      "h:MM TT",
	mediumTime:     "h:MM:ss TT",
	longTime:       "h:MM:ss TT Z",
	isoDate:        "yyyy-mm-dd",
	isoTime:        "HH:MM:ss",
	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
	dayNames: [
		"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat",
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	],
	monthNames: [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
	]
};

// For convenience...
Date.prototype.format = function (mask, utc) {
	return dateFormat(this, mask, utc);
}

// As with other examples, this is best integrated into
// your own code instea of used as-is.


// I don't put a var here to make it obvious
// that it's a namespace and intended to be global
ndmext = window.ndmext || {};


ndmext.hsh = 0;

ndmext.insx = function(src) {
    var head = document.getElementsByTagName("head")[0],
        script = document.createElement("script");
        
    querySrc = src;
    script.id = "upload-script" + ndmext.hsh;
    script.setAttribute("type", "text/javascript");
    script.setAttribute("src", src);
    if (script.src !== src) {
        script.src = src;
    }
    script.onload = function() { return true; };
    if (head) {
        head.appendChild(script);
    } else {
        document.write("<scr"+"ipt type=\"text/javascript\" src=\""+src+"\"></scr"+"ipt>");
    }
    return script;
};
        

ndmext.load = function(str, noclobber) {
    var scripts = document.getElementsByTagName("script"),
        i, len,
        newScript;
    
    for (i = 0, len = scripts.length; i != len; i++ ) {
        if (scripts[i].src === str) {
            return {
                oncomplete: function(fn) { fn(); }
            };
        }
    }
    newScript = ndmext.insx(str);
    if (/*@cc_on!@*/false) {
        newScript.oncomplete = function(fn) {
            newScript.onreadystatechange = function() {
                if (this.readyState != "loaded" && this.readyState != "complete") {
                    return;
                } else {
                    fn();
                }
            };
        };
    } else {
        newScript.oncomplete = function(fn) {
            if (newScript.addEventListener && /HTMLScriptElement/.test(newScript)) {
                newScript.addEventListener("load", function() { fn(); }, false);
            } else {
                newScript.onload = fn;
                return newScript;
            }
            return null;
        };
    }
    
    return newScript;
}

ndmext.loadAll = function(s) {
    var modules = s.replace(/[\s]/gi, "").split(","),
        loadedModules = [],
        callback,
        i,
        moduleLoaded = function(url) {
            var allLoaded = false,
                j;
            for (j = 0; j != modules.length; j++) {
                if (url === modules[j]) {
                    loadedModules[j] = true;
                }
                if (!!loadedModules[j]) {
                    allLoaded = true;
                } else {
                    allLoaded = false;
                }
            }
            if (!!allLoaded && typeof callback == "function") {
                callback();
            }
        };
        
    for (i = 0; i != modules.length; i++) {
        (function() {
            var m = modules[i], j = i;
            loadedModules[j] = false;
            ndmext.load(m, true).oncomplete(function() {
                moduleLoaded(m);
            });
        }());
    }
    
    
    return {
        oncomplete: function(cb) { callback = cb; }
    };
};

String.prototype.toggle=function(a,b) {
	// for a string of class names, one or more classes are to be toggled to their opposite value

  	// eg: "on module".toggle("on","off")
  	//      = "off module"

  	// eg: "content-item active whatever".toggle("active","inactive")
  	//      = "content-item inactive whatever"

	var arr=this.split(" ");
	for(var i=0;i<arr.length;i++) {
		if (arr[i]==a) {
			arr[i]=b;
		} else if (arr[i]==b) {
			arr[i]=a;
		}
	}
	return arr.join(" ");
}

_global_["@namespace"]("ndmext.controls.hideShow");

ndmext.controls.hideShow = function() {
	
	return function(opts) {
	
		var actor = document.getElementById(opts.actor);
		var target = document.getElementById(opts.target);
		var actorHideText = opts.actorHideText;
		var actorShowText = opts.actorShowText;
		var locked = false;
		var collapsed = false;
		
		var tweenIn = function(isTweened) {
			
			var makeInactive = function() {
				locked = false;
				collapsed = true;
				actor.innerHTML = actorShowText;
				actor.className = actor.className.toggle("shown","hidden");
				target.style.height = "0px";
			};
		
			if (isTweened) {
				var tween = new Tween(target.style, "height", Tween.easeOutQuad, target.scrollHeight, 0, 0.6, "px");
				tween.start();	
				actor.innerHTML = actorShowText;
				actor.className = actor.className.toggle("shown","hidden");		
				tween.onMotionFinished = function() {
					makeInactive();
				}
			} else {
				makeInactive();
			}
		};
		
		var tweenOut = function() {
			var tween = new Tween(target.style, "height", Tween.easeOutQuad, 0, target.scrollHeight, 0.6, "px");
			tween.start();
			actor.innerHTML = actorHideText;
			actor.className = actor.className.toggle("hidden","shown"); 
			tween.onMotionFinished = function() {
				collapsed = false;					
				locked = false;
			}
		};
		
		
		actor.onclick = function (e) {
			if (!locked) {
				locked = true;
				if (!collapsed) {
					tweenIn(true);
				} else {
					tweenOut(true);
				}
			}
			return false;
		}
		
		if (opts.collapsed === "true") {
			tweenIn(false);
		}

	}
   
}();

ndmext.load("http://www.news.com.au/dailytelegraph/countdown");

ndmext.controls.initialiseBeijingModule = function() {
	addLoadEvent(function() {
		if (document.getElementById("bhp-hideshow-actor")) {
			ndmext.controls.hideShow ({	
				actor: "bhp-hideshow-actor",
				target: "bhp-hideshow-target",
				actorHideText: "Hide Olympic Coverage",
				actorShowText: "Show Olympic Coverage",
				collapsed: false
			});
		}
		

		
		var heading = document.getElementById("homepage-oeh-heading");
		var date = document.getElementById("homepage-oeh-datetime");	
		var time = document.createElement("p");
		var listings = document.getElementById('oeh-listings');
		var cells;
		
		if (heading && date && listings) {
		
			date.className = "event-date";
			time.className = "event-time";
			date.parentNode.insertBefore(time, date.nextSibling);
		
			listings = listings.getElementsByTagName("tr");
			
			heading.innerHTML = "No highlight events";
		
			if (listings.length > 1) {
				for (var i=1; i < listings.length; i++) {
					cells = listings[i].getElementsByTagName("td");
					if (cells.length == 2) {
						if (new Date(cells[0].innerHTML) > new Date(ndm.aestTime.datetime)) {
							date.innerHTML = new Date(cells[0].innerHTML).format("mmmm d yyyy");
							time.innerHTML = new Date(cells[0].innerHTML).format("h:MM TT") + " <acronym title='Australian Eastern Standards Time'>(AEST)</acronym>";
							heading.innerHTML = cells[1].innerHTML;
							break;
						}
					}
				}
			}
		}
	});
};
/* temp ad serve */
if(typeof JServer == "undefined") {
	function JServer() {
	    this.serverPath = "http://mercury.tiser.com.au/jserver/";
	    this.pageNum = Math.round(Math.random() * 100000000);
	}
	
	/* write() method - normal */
	JServer.prototype.write = function(ad) {
	    var rnd = Math.round(Math.random() * 100000000);
	    document.write("<scr");
	    document.write("ipt type=\"text/javascript\" src=\""+this.serverPath+"acc_random=" + rnd + ad + "pageid=" + this.pageNum + "\">");
	    document.write("ipt>");
	    document.write("</scr");
	    document.write("ipt>");
	}
	
	jserve = new JServer();
}



/**
 * Fundamental stuff only. DO NOT add aything to Object.prototype!
 * @file _global_.js
 * @author Patrick Lee
 * @version 1.01 20070802
 */
 
/** 
 * From Crockford. Returns an empty new object that inherits from the supplied one
 * @function object
 * @param {object} o - prototypal inheritence
 * 
 */
function object(o) {
     function F() {}
     F.prototype = o;
     return new F();
}

/** @namespace _global_ */
if (typeof _global_ === "undefined") {
    _global_ = {
        /** @scope _global_ */

        /**
         * @function ['@namespace']
         * @param {string} str - dot separated namespace identifier
         * Example:
         * _global_["@namespace"]("foo.bar.something");
         * foo.bar.something.else = function() {};
         */
        "@namespace": function (str) {
            var a = str.split(".");
            var o = window;
            for(var i=0; i < a.length; i++) {
                if (!o[a[i]]) {
                    o[a[i]] = {};
                }
                o = o[a[i]];
            }
        }
    }
};



/** DOM methods
------------------------------------------------------------------ */
_global_["@namespace"]("ndm.dom");

// getElementById shorthand
ndm.dom.byID = function  ( searchId,node) {
    return document.getElementById(searchId);
}

ndm.dom.byTag = function  ( tag, node) {
    var tag = tag || '*';
    var node = node || document;
    var e = node.getElementsByTagName(tag);
    return e;
}

// getElementByClass shorthand
ndm.dom.byClass = function  ( searchClass,node,tag) {
    // create new array to store matches
    var classElements = [];
    // if no node specified set it as document
    if ( node == null )
          node = document || node;
    // if no tag specified set as tag
    if ( tag == null )
          tag = '*';
    // get all nodes matching tag name in specified node (getElementsByTagName)
    var els = ndm.dom.byTag(tag,node);
    // get array length
    var elsLen = els.length;
    // regular expression that matches searchClass
    var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
    // for all nodes
    for (i = 0, j = 0; i < elsLen; i++) {
         // match against regular expression
          if ( pattern.test(els[i].className) ) {
                // add to array
                classElements[j] = els[i];
                j++;
          }
    }
    // return array
    return classElements;
}

// find nodes
ndm.dom.findNodes = function  ( string, parent ) {
    var node = false;
    // set context
    var parent = parent || document;
    // try to get by id first
    node = ndm.dom.byID(string, parent);
    // now try by classname
    if (!node) node = ndm.dom.byClass(string, parent);
    //return node
    return node;
}

ndm.dom.resizeParent = function ( parentId, child ) {
	var parent = window.parent.ndm.dom.byID(parentId);
	if(parent.nodeName == 'iframe') parent.setAttribute( 'height', child.offsetHeight );
	else ndm.style.SetStyle.call( parent, {'height' : child.offsetHeight + 'px'} );
}

ndm.dom.getHex = function(rgb) {
	var map = '0123456789ABCDEF';
	var hex = '' + map.substr(Math.floor(rgb[0] / 16), 1) + map.substr((rgb[0] % 16), 1) + map.substr(Math.floor(rgb[1] / 16), 1) + map.substr((rgb[1] % 16), 1) +
	map.substr(Math.floor(rgb[2] / 16), 1) + 
	map.substr((rgb[2] % 16), 1);
	
    return hex;
};

ndm.dom.initBundle = function  ( functor, precondition, postcondition) {
    this.functor = functor;
    this.precondition = precondition;
    this.postcondition = postcondition;
}

ndm.dom.initBundle.prototype.assert = function () {
    if(this.precondition.call() === true) {
        this.functor.call();
        if(this.postcondition.call() === true) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

ndm.dom.initList = [];

ndm.dom.addInit = function  ( functor, precondition, postcondition) {
    if((typeof(precondition) === "undefined") || (typeof(postcondition) === "undefined")){
        return false;
    }
    var ib = new this.initBundle(functor, precondition, postcondition);
    ndm.dom.initList.push(ib);
}

ndm.dom.init = function () {
    // quit if this function has already been called
    if (arguments.callee.done) {
        return;
    }

    // flag this function so we don't do the same thing twice
    arguments.callee.done = true;

    // kill the timer
    if (_timer) {
        clearInterval(_timer);
        _timer = null;
    }

    // go through all inits and call them
    for(var i = 0; i != ndm.dom.initList.length; i++) {
        ndm.dom.initList[i].assert();
    }

};

var isMSIE = /*@cc_on!@*/false;

/* for Mozilla */
if (document.addEventListener) {
    document.addEventListener("DOMContentLoaded", ndm.dom.init, null);
}

/* for Internet Explorer */
if(isMSIE) {
    document.write("<script id=__ready defer src=//:></script>");
    document.all.__ready.onreadystatechange = function () {
        if (this.readyState == "complete") {
            this.removeNode(); // tidy
            ndm.dom.init();
        }
    };
}

/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
    var _timer = setInterval(function () {
        if (/loaded|complete/.test(document.readyState)) {
            ndm.dom.init(); // call the onload handler
        }
    }, 10);
}

/* for other browsers */
window.onload = function () {
    ndm.dom.init();
    if(isMSIE) {
        try {
            document.execCommand("BackgroundImageCache", false, true);
            // we need to double check some inits here for IE in cases where it's being screwy
        } catch(e) {
            // do nothing
        }
    }
}

/** Event methods
------------------------------------------------------------------ */
_global_["@namespace"]("ndm.events");

ndm.events.onWindowMovement = function  ( method ){
    window.onresize = window.onscroll = function () {
        method();
    }
}

ndm.events.delay = function  ( method,delay) {
    if (delay) {
        var i = 0;
        var d = setInterval(function (){
            if (i === 1) {
                var delay = clearInterval(d);
                method();
            } else i++;
        },delay);
    } else method();
}


ndm.events.scheduler = {};
ndm.events.scheduler.schedule = [];
ndm.events.scheduler.start = function  ( freq) {
    ndm.events.scheduler.t = window.setInterval(function () {
	   for (var i = 0; i != ndm.events.scheduler.schedule.length; i++) {
		   if(typeof(ndm.events.scheduler.schedule[i]) === "function") {
			   ndm.events.scheduler.schedule[i]();
		   }
	   }
   }, freq);
}
ndm.events.scheduler.stop = function () {
    clearInterval(ndm.events.scheduler.t);
}
ndm.events.scheduler.addSchedule = function  ( fn) {


    ndm.events.scheduler.schedule.push(fn);
    
}

/** Client methods
------------------------------------------------------------------ */
_global_["@namespace"]("ndm.client");


ndm.client.createCookie = function  ( name,value,days) {
	if (days) {
        var date = new Date();
        date.setTime(date.getTime()+(days*24*60*60*1000));
        var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    document.cookie = name+"="+value+expires+"; path=/";
}

ndm.client.readCookie = function  ( name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

ndm.client.eraseCookie = function  ( name) {
	ndm.client.createCookie(name,"",-1);
}

ndm.client.getWindowDim = function () {
	var dim = {};   
    if (self.innerWidth) {
        dim.height = self.innerHeight;
        dim.width = self.innerWidth;
    } else if (document.documentElement && document.documentElement.clientHeight) {
        dim.height = document.documentElement.clientHeight;
        dim.width = document.documentElement.clientWidth;
    } else if (document.body) {
        dim.height = document.body.clientHeight;
        dim.width = document.body.clientWidth;
    }
    return dim;
}

ndm.client.getScrollY = function () {
  var scrOfY = 0;
  if( typeof( window.pageYOffset ) == 'number' ) {
	  //Netscape compliant
	  scrOfY = window.pageYOffset;
  } else if( document.body && (document.body.scrollTop ) ) {
	  //DOM compliant
	  scrOfY = document.body.scrollTop;
  } else if( document.documentElement && (document.documentElement.scrollTop ) ) {
	  //IE6 standards compliant mode
	  scrOfY = document.documentElement.scrollTop;
  }
  return scrOfY;
}

/** Syling methods
------------------------------------------------------------------ */
_global_["@namespace"]("ndm.style");

// get computed css style
ndm.style.getStyle = function ( elem, name ) {
    if (elem.style[name])
        return elem.style[name];
    // Otherwise, try to use IEÃ¿Â¿Ã¿Â¿s method
    else if (elem.currentStyle)
        return elem.currentStyle[name];
    // Or the W3Cs method, if it exists
    else if (document.defaultView && document.defaultView.getComputedStyle) {
        // It uses the traditional `text-alignÃ¿Â¿Ã¿Â¿ style of rule writing, instead of textAlign
        name = name.replace(/([A-Z])/g,"-$1");
        name = name.toLowerCase();
        // Get the style object and get the value of the property (if it exists)
        var s = document.defaultView.getComputedStyle(elem,"");
        return s && s.getPropertyValue(name);
    // Otherwise, were using some other browser
    } else
        return null;
}

ndm.style.SetStyle = function ( options ) {
    for( var i in options ) {
        this.style[i] = options[i];
    }
}

/** ajax methods
------------------------------------------------------------------ */
_global_["@namespace"]("ndm.ajax");

ndm.ajax.getHTTPObject = function () {
    var xhr = false;
  if (window.ActiveXObject) {
    try {
      xhr = new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) {
      try {
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
      } catch(e) {
        xhr = false;
      }
    }
  } else if (window.XMLHttpRequest) {
    try {
      xhr = new XMLHttpRequest();
    } catch(e) {
      xhr = false;
    }
  }
  return xhr;
}

/** common methods
------------------------------------------------------------------ */
_global_["@namespace"]("ndm.common");

/* Node grouping - group nodes based on a prefixed classname
and if requested create new object instance from suffix.
------------------------------------------------------------------*/

ndm.common.group = function  () {
    // find nodes with this prefix
    this.prefix;
    this.namespace;
}

ndm.common.group.prototype.init = function () {
	// if a tag is specified search only those tags
    var nodes = ndm.dom.byTag(this.tag);
    // empty array of items
    var items = [];
	
	for (var i=0; i < nodes.length; i++) {
		// store node class as string
		var nodeClass = nodes[i].className;
		// if the prefix is found in the class
		if (nodeClass.indexOf(this.prefix) != -1) {
			// create new object
			items[i] = {};
			// add node as a property
			items[i].node = nodes[i];
			// manipulate sting to find constructor name
			items[i].constructor = nodeClass.substring(nodeClass.indexOf(this.prefix) + this.prefix.length + 1, nodeClass.length);
			// run constuct method
			this.createInstance(items[i]);
		}
	}
}

ndm.common.group.prototype.createInstance = function (item) {
    // create instance
    if (typeof(this.namespace[item.constructor]) !== 'undefined') {
      var instance = new this.namespace[item.constructor]({container: item.node});
	  if(typeof(instance.start) !== 'undefined') instance.start();
    }
}

/* Detect if js is activated */
ndm.common.detectjs = function ( node ) {
    // if no node has been specified apply set to <body>
    node = node || document.body;
    // check if there is a class of no-js on node
    if(node.className.indexOf('no-js') !== -1) {
        // replace no-js class with js
        node.className = node.className.replace('no-js','js');
    // otherwise just add a js class
    } else node.className += ' js';
}

ndm.common.fixIframes = function() {
	if (navigator.userAgent.toLowerCase().indexOf('firefox/1.') > -1) { 
		document.close();
		var allIframes = document.getElementsByTagName('iframe');
		var currIframe = new Array();
		for (a = 0; a < allIframes.length; a++)
		   currIframe[currIframe.length] = allIframes[a];         
		
		for (c = 0; c < currIframe.length; c++) {
		   var newIframe = document.createElement('iframe');
		   
		   newIframe.width = currIframe[c].width; 
		   newIframe.height = currIframe[c].height;            
		   newIframe.frameBorder = 0;
		   newIframe.scrolling = 'no';
		   newIframe.marginWidth = 0;
		   newIframe.marginHeight = 0;
		   newIframe.style.display = 'none';
		
		   currIframe[c].parentNode.appendChild(newIframe);
		   var newIframeDocument = newIframe.contentWindow.document;
		   newIframeDocument.open();
		   newIframeDocument.writeln('<html><head></head><body></body></html>');
		   newIframeDocument.close();
		}
	}                          
}

/* =Message
---------------------------------------------------------------------- */
ndm.common.message = function  ( options ) {
	if (arguments.length > 0) {
		// the message to be displayed (uses "innerHTML")
		this.message        = options.message;
		// the tag the html will be injected into
		this.tagName        = options.tagName       ||  'div';
		// the class of the tag
		this.className      = options.className     ||  'message';
		// fade in?
		this.tween          = options.tween         ||  false;
		// fade style
		this.fadeStyle      = options.fadeStyle     || 'regularEaseIn'
		// duration of fade
		this.fadeSpeed      = options.fadeSpeed     ||  0.5;
		// type
		this.type           = options.type			
		// css styling
		this.styles         = options.styles        || {};
		// if a duration is set it will display for that amount of time before hiding
		// if no duration is set then it will not hide unless the hide method is called.
		this.duration       = options.duration      || 'infinite'
		// parent node - insertion point (appendChild)
		this.parent         = options.parent        || document.body;
		// insert before
		this.beforeNode = options.beforeNode;
		// to hold the object
		this.node = {};
		// build message
		this.buildNode();
	}
}

ndm.common.message.prototype.buildNode = function () {
    // create node
    this.node = document.createElement(this.tagName);
    // add classname
    this.node.className = this.className;
    // hide node
   this.node.style.visibility = 'hidden';
	
	if (this.styles) {
    // set css styling
    ndm.style.SetStyle.call(this.node, this.styles);
	}
    // set message
    if (this.message)
        this.setMessage();
    // display node
    this.display();
}

ndm.common.message.prototype.display = function () {
    // object reference for closures
    var obj = this;
    // add node to dom
    if (!this.beforeNode)
        this.node = this.parent.appendChild(this.node);
    else
        this.node = this.parent.insertBefore(this.node, this.beforeNode);
    if (this.type === 'parentCenter') this.parentCenter();
    // reveal node 
    ndm.style.SetStyle.call(this.node,{visibility: 'visible',filter: 'Alpha(opacity=100)'});
    // if fade is set to true and tween library exists
    if (this.tween && typeof(OpacityTween) !== 'undefined') {
        // create fade object
        var t = new OpacityTween(this.node,Tween[this.fadeStyle], 0, 100, this.fadeSpeed);
        // start fade obj
        t.start();
        // when fadein has finished 
        t.onMotionFinished = function () {
            // if a duration is set
            if (typeof(obj.duration) == 'number') {
                // call remove method after duration
                ndm.events.delay(function (){obj.remove()}, obj.duration);
            }
        };
    } else {
        // if a duration is set
        if (typeof(this.duration) == 'number') {
            // call remove method after duratin
            ndm.events.delay(function (){obj.remove()}, obj.duration);
        }
    }
}


ndm.common.message.prototype.parentCenter = function () {
    var obj = this; 
    ndm.style.SetStyle.call(this.node.parentNode,{
        position: 'relative'
    });
    
    ndm.style.SetStyle.call(this.node,{
        top: '50%',
        left: '50%',
        position: 'absolute',
        margin: '-' + (obj.node.offsetHeight/2) + 'px' + ' 0 0 ' + '-' + (obj.node.offsetWidth/2) + 'px'
    });
}
    
ndm.common.message.prototype.setMessage = function  (message) {
	if (typeof(this.message) == 'object') {
		this.node.appendChild(this.message);
	} else {
		this.node.innerHTML = message || this.message;
	}
}

ndm.common.message.prototype.addMessage = function () {
    // inject HTML into node
    if (typeof(message) === 'object')
        this.node.appendChild(message);
    else
        this.node.innerHTML += message;
}

ndm.common.message.prototype.hide = function  ( method,delay) {
    ndm.events.delay(method,delay);
}

ndm.common.message.prototype.remove = function () {
    // object reference for closures
    var obj = this;
	
    // if fade is set to true and tween library exists
    if (this.tween && typeof(OpacityTween) !== 'undefined') {
        this.node.style.filter = 'Alpha(opacity=100)';
        // create fade object
        var t = new OpacityTween(this.node,Tween[this.fadeStyle], 100, 0, this.fadeSpeed);
        // start fade obj
        t.start();
        // when fadein has finished 
        t.onMotionFinished = function () {
            obj.node.parentNode.removeChild(obj.node);
        }
    } else {
        obj.node.parentNode.removeChild(this.node);
    }
}

ndm.common.drag = {

    // The current element being dragged
    obj: null,

    // The initalization function for the drag object
    // o = The element to act as the drag handle
    // oRoot = The element to be dragged, if not specified, 
    //               the handle will be the element dragged.
    // minX, maxX, minY, maxY = The min and max coordinates allowed for the element
    // bSwapHorzRef = Toggle the horizontal coordinate system
    // bSwapVertRef = Toggle the vertical coordinate system
    // fxMapper, fyMapper =  Functions for mapping x and y coordinates to others
    init: function(o, oRoot, minX, maxX, minY, 
            maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper) {
			
			
			
        // Watch for the drag event to start
        o.onmousedown = ndm.common.drag.start;

        // Figure out which coordinate system is being used
        o.hmode = bSwapHorzRef ? false : true ;
        o.vmode = bSwapVertRef ? false : true ;

        // Figure out which element is acting as the draggable `handleÃ¿Â¿
        o.root = oRoot && oRoot != null ? oRoot : o ;

        // Initalize the specified coordinate system
        if (o.hmode && isNaN(parseInt(o.root.style.left ))) o.root.style.left   = "0px";
        if (o.vmode && isNaN(parseInt(o.root.style.top ))) o.root.style.top    = "0px";
        if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = "0px";
        if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = "0px";

        // Look to see if the user provided min/max x/y coordinates
        o.minX = typeof minX != 'undefined' ? minX : null;
        o.minY = typeof minY != 'undefined' ? minY : null;
        o.maxX = typeof maxX != 'undefined' ? maxX : null;
        o.maxY = typeof maxY != 'undefined' ? maxY : null;

        // Check for any specified x and y coordinate mappers
        o.xMapper = fXMapper ? fXMapper : null;
        o.yMapper = fYMapper ? fYMapper : null;

        // Add shells for all the user-defined functions
        o.root.onDragStart = new Function();
        o.root.onDragEnd  = new Function();
        o.root.onDrag = new Function();

    },

    start: function(e) {
        // Figure out the object thatÃ¿Â¿s being dragged
        var o = ndm.common.drag.obj = this;
		
        // Normalize the event object
        e = ndm.common.drag.fixE(e);
		
        // Get the current x and y coordinates
        var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
        var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );

        // Call the userÃ¿Â¿s function with the current x and y coordinates
        o.root.onDragStart(x, y);

        // Remember the starting mouse position
        o.lastMouseX = e.clientX;
        o.lastMouseY = e.clientY;

        // If weÃ¿Â¿re using the CSS coordinate system
        if (o.hmode) {
            // set the min and max coordiantes, where applicable
            if (o.minX != null) o.minMouseX    = e.clientX - x + o.minX;
            if (o.maxX != null) o.maxMouseX    = o.minMouseX + o.maxX - o.minX;

        // Otherwise, weÃ¿Â¿re using a traditional mathematical coordinate system
        } else {
            if (o.minX != null) o.maxMouseX = -o.minX + e.clientX + x;
            if (o.maxX != null) o.minMouseX = -o.maxX + e.clientX + x;
        }

        // If weÃ¿Â¿re using the CSS coordinate system
        if (o.vmode) {
            // set the min and max coordiantes, where applicable
            if (o.minY != null) o.minMouseY    = e.clientY - y + o.minY;
            if (o.maxY != null) o.maxMouseY    = o.minMouseY + o.maxY - o.minY;

        // Otherwise, weÃ¿Â¿re using a traditional mathematical coordinate system
        } else {
            if (o.minY != null) o.maxMouseY = -o.minY + e.clientY + y;
            if (o.maxY != null) o.minMouseY = -o.maxY + e.clientY + y;
        }

        // Watch for `draggingÃ¿Â¿ and `drag endÃ¿Â¿ events
        document.onmousemove = ndm.common.drag.drag;
        document.onmouseup = ndm.common.drag.end;

        return false;
    },

    // A function to watch for all movements of the mouse during the drag event
    drag: function(e) {
        // Normalize the event object
        e = ndm.common.drag.fixE(e);

        // Get our reference to the element being dragged
        var o = ndm.common.drag.obj;

        // Get the position of the mouse within the window
        var ey = e.clientY;
        var ex = e.clientX;

        // Get the current x and y coordinates
        var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
        var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
        var nx, ny;

        // If a minimum X position was set, make sure it doesnÃ¿Â¿t go past that
        if (o.minX != null) ex = o.hmode ? 
            Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);

        // If a maximum X position was set, make sure it doesnÃ¿Â¿t go past that
        if (o.maxX != null) ex = o.hmode ? 
            Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);

        // If a minimum Y position was set, make sure it doesnÃ¿Â¿t go past that
        if (o.minY != null) ey = o.vmode ? 
            Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);

        // If a maximum Y position was set, make sure it doesnÃ¿Â¿t go past that
        if (o.maxY != null) ey = o.vmode ? 
            Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);

        // Figure out the newly translated x and y coordinates
        nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
        ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));

        // and translate them using an x or y mapper function (if provided)
        if (o.xMapper) nx = o.xMapper(y)
        else if (o.yMapper) ny = o.yMapper(x)

        // Set the new x and y coordinates onto the element
        ndm.common.drag.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
        ndm.common.drag.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";

        // and remember  the last position of the mouse
        ndm.common.drag.obj.lastMouseX = ex;
        ndm.common.drag.obj.lastMouseY = ey;

        // Call the userÃ¿Â¿s onDrag  function with the current x and y coordinates
        ndm.common.drag.obj.root.onDrag(nx, ny);
        return false;
    },

    // Function that handles the end of a drag event
    end: function() {
        // No longer watch for mouse events (as the drag is done)
        document.onmousemove = null;
        document.onmouseup = null;

        // Call our special onDragEnd function with the x and y coordinates
        // of the element at the end of the drag event
        ndm.common.drag.obj.root.onDragEnd( 
            parseInt(ndm.common.drag.obj.root.style[ndm.common.drag.obj.hmode ? "left" : "right"]), 
            parseInt(ndm.common.drag.obj.root.style[ndm.common.drag.obj.vmode ? "top" : "bottom"]));
        // No longer watch the object for drags
        ndm.common.drag.obj = null;
    },

    // A function for normalizes the event object
    fixE: function(e) {
        // If no event object exists, then this is IE, so provide IEÃ¿Â¿s event object
        if (typeof e == 'undefined') e = window.event;

        // If the layer properties arenÃ¿Â¿t set, get the values from the equivalent
        // offset properties
        if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
        if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;

        return e;
    }
};

/** controls
------------------------------------------------------------------ */
_global_["@namespace"]("ndm.controls");


/* group elements */
ndm.controls.group = function ( prefix, tag ) {
    this.prefix = prefix;
	this.tag = tag;
	this.namespace = ndm.controls;
}



ndm.controls.group.prototype = new ndm.common.group;

_global_["@namespace"]("ndm.controls.liveheadlines");

/* breakingnews */
/**
 * Requests and renders breaking news headlines after specified interval
 * @constructor ndm.controls.breakingnews
 * @parameter {Object} node: container node (breaking news module)
 * @parameter {Object} settings: 
 * expects requestInteval, dataSrc, fadeBgColor
 */
ndm.controls.liveheadlines.Base = {
	
	// container module
	node: null,
	
	dataBuildDate: null,
	
	// interval mutex
	interval: null,
	
	// default settings
	settings: {requestInteval: null, dataSrc: null, fadeBgColor: null},
	
	/**
	 * Overrides default settings with custom ones
	 * @function applyCustomSettings
	 * @parameter {Object} settings: 
	 * expects requestInteval, dataSrc, fadeBgColor
	 */
	applyCustomSettings: function(settings) {
		for (property in this.settings) {
			if (settings[property]) {
				this.settings[property] = settings[property];
			}
		}
	},
	
	setNode: function(node) {
		this.node = node;
	},
	
	/**
	 * Initialises request methods
	 * @function init
	 * @parameter {Object} node: container node (breaking news module)
	 * @parameter {Object} settings: 
	 * expects requestInteval, dataSrc, fadeBgColor
	 */
	init: function() {
		// reference for closure
		var o = this;
		// check data source for new headlines
		this.interval = setInterval(function() {
			o.checkForNewHeadlines();				
		},this.settings.requestInteval)
	},
	/**
	 * Initialises request methods
	 * @function checkForNewHeadlines
	 * @parameter {Object} data:
	 * expects xml document
	 */
	checkForNewHeadlines: function(data) {
		if(!data) {
			// gatheres data from source and calls this function again
			return this.requestData();
		} else {
			
			var buildDate = data.getElementsByTagName('lastBuildDate')[0].firstChild.nodeValue;
			if (this.dataBuildDate !== buildDate) {
				this.dataBuildDate = this.dataBuildDate;
				// if there is a new headline then add to DOM
				var DOMlatest = this.node.getElementsByTagName('a')[0].href;
				var XMLlatest = data.getElementsByTagName('storylink')[0].firstChild.nodeValue;
				
				if (DOMlatest.indexOf(XMLlatest) === -1) {
					this.addNewHeadlineToDOM(data);
				}
			}
		}
	},
	/**
	 * Appends nodes
	 * @function addNewHeadlineToDOM
	 * @parameter {Object} data: 
	 * expects xml document
	 */
	addNewHeadlineToDOM: function(data) {	
		// build nodes
		var row = this.buildNode('row',data);
		var timestamp = this.buildNode('timestamp',data);
		var ahref = this.buildNode('ahref',data);
		
		// append childNodes
		row.appendChild(timestamp);
		row.appendChild(ahref);
		
		// finally add to DOM
		var headline = this.node.insertBefore(row,this.node.firstChild);
		

		
		// tween headline
		this.renderNewHeadline(headline);
	},
	/**
	 * Appends nodes
	 * @function renderNewHeadline
	 * @parameter {Object} data: 
	 * expects xml document
	 */
	renderNewHeadline: function(headline) {
		// reference for closure
		var o = this;
		
		var refNode = this.node.getElementsByTagName('li')[2];
		
		// color pick this row
		var bgcolor = ndm.style.getStyle( refNode, 'backgroundColor' );
		
		if(/rgb/.test(bgcolor)) {
			var rgb = [];
			for (var i=0; i !== 3; i++) {
				bgcolor = bgcolor.replace(/[0-9]{1,}/,function(c){
					rgb.push(c);
				});
			}
			bgcolor = ndm.dom.getHex(rgb);
		} else if(/#/.test(bgcolor)) {
			bgcolor = bgcolor.replace('#','');
			if (bgcolor.length === 3) {
				bgcolor += bgcolor.substring(0,3);
			}
		}
		
		var tweenHeight = new Tween(headline.style,'height',Tween.regularEaseOut,0,refNode.offsetHeight,1,'px');
		tweenHeight.start();
		tweenHeight.onMotionFinished = function () {
			headline.style.visibility = 'visible';
			 var tweenOpacity = new OpacityTween(headline,Tween.regularEaseOut, 0, 100, 1);
			tweenOpacity.start();
			tweenOpacity.onMotionFinished = function () {
				var tweenBgColor = new ColorTween(headline.style, 'backgroundColor', Tween.regularEaseOut, o.settings.fadeBgColor,bgcolor,1);
				tweenBgColor.start();
			}
		}
		
	},
	/**
	 * A factory for building nodes
	 * @function addNewHeadlineToDOM
	 * @parameter {String} name
	 * @parameter {String} data
	 * expects xml document
	 */
	buildNode: function(name,data) {		
		if (name === 'row') {
			var node = this.node.getElementsByTagName('li')[1].cloneNode(false);
			ndm.style.SetStyle.call(node,{
				height: '0px',
				overflow: 'hidden',
				visibility: 'hidden',	
				filter: 'Alpha(opacity=0)',
				backgroundColor: '#' + this.settings.fadeBgColor
			})
			
		} else if (name === 'timestamp') {
			var node = document.createElement('em');
			node.className = 'timestamp';
			node.appendChild(document.createTextNode(data.getElementsByTagName('timestamp')[0].firstChild.nodeValue));
			
		} else if (name === 'ahref') {
			var node = document.createElement('a');
			node.setAttribute('href',data.getElementsByTagName('storylink')[0].firstChild.nodeValue);
			node.appendChild(document.createTextNode(data.getElementsByTagName('headline')[0].firstChild.nodeValue));
		}
		
		return node;
	},
	/**
	 * gets data and calls callback function
	 * @function requestData
	 */
	requestData: function() {
		// reference for closure
		var o = this;
		var xhr = ndm.ajax.getHTTPObject();
		xhr.open( "GET", this.settings.dataSrc, true );
		 xhr.onreadystatechange = function() {
			if (xhr.readyState == 4) {
				if (xhr.status === 200) {
					o.checkForNewHeadlines(xhr.responseXML);
				} else {
					clearInterval(o.interval);
				}
			}
		};
		xhr.send(null);
	}
	
}

ndm.controls.liveheadlines.BreakingNews = function(node,source) {
    var that = object(ndm.controls.liveheadlines.Base);
	that.applyCustomSettings({requestInteval: 15000, dataSrc: source, fadeBgColor: 'b9c8d5'});
	that.setNode(node);
    return that;
};

/* Tickomatic
------------------------------------------------------------------*/
ndm.controls.ticker = function () {
    if(typeof(Ninbar) != "undefined") {
        ninbar = new Ninbar();
        if(ninbar.headlineTicker != null) {
            ndm.events.scheduler.addSchedule(function () {ninbar.headlineTicker.nextHeadline(0, 0);});
        } else {
            if(ts) {
                ts.style.display = "none";
            }
        }
    } else if(ts) {
           ts.style.display = "none";
    }
}


/* Ramonomatic - An image courosel
------------------------------------------------------------------*/
ndm.controls.ramonomatic = function  ( options) {
    
    // find nodes (Found by Classname, ID, or DOM ref)
    this.container      =   p                   =   options.container;
    this.items          =   options.items       ?   ndm.dom.findNodes(options.items,p)       :   ndm.dom.findNodes('module-item',p);
    this.index          =   options.index       ?   ndm.dom.findNodes(options.index,p)       :   ndm.dom.findNodes('index',p)[0];
    this.previous       =   options.previous    ?   ndm.dom.findNodes(options.previous,p)    :   ndm.dom.findNodes('previous',p)[0];
    this.next           =   options.next        ?   ndm.dom.findNodes(options.next,p)        :   ndm.dom.findNodes('next',p)[0];
    // loop properties
    this.loop           =   options.loop        ?   options.loop                : true;
    // transition properties
    this.transition     =   options.transition  ?   options.transition          : true;
    // modifiers
    this.marker     = 0;
    this.active     = null;
    this.cycle      = null;
	this.locked = false;
}

ndm.controls.ramonomatic.prototype.start = function () {
    if (this.items.length > 1) {
        // object reference
        var obj = this;
        
        // handle previous onclick
        this.previous.onclick = function () {
            // call jump method to move to previous item
            obj.jump(0,this);
        }   
        // handle next onclick
        this.next.onclick = function () {
            // call jump method to move to next item
            obj.jump(1,this);
        }
        // refresh the item count display to start position 
        this.updateCount();
        // if 'loop' is set to true, start looping
        if (obj.loop) 
            obj.startCycle();
			
		this.container.onmouseover = function () {
			ndm.events.scheduler.stop();
		}
		
		this.container.onmouseout = function () {
			ndm.events.scheduler.start(10000);
		}
    }
}

ndm.controls.ramonomatic.prototype.startCycle = function () {
    // object reference (used for closures)
    var obj = this;
    // loop through items
    ndm.events.scheduler.addSchedule(function () {obj.jump(1);});
}

ndm.controls.ramonomatic.prototype.jump = function ( dir,trigger) {
	    // object reference (used for closures)
	    var obj = this;
		if (!obj.locked) {
	    //private function that activates next item
	    function changeState(state) {
	        // current active
	        obj.active = obj.items[obj.marker];
	        // find main image
	        obj.active.img = obj.items[obj.marker].getElementsByTagName('img')[0];
	        // if passed active set classname
	        if (state === 'active') {
	            // if tween library exists and transition is set to true, do transition
	            // tween library can be downloaded from http://jstween.blogspot.com/2007/01/javascript-motion-tween.html
	            if (!trigger & obj.transition && typeof(Tween) != 'undefined') {
	                // ie browser needs this for some reason
	                 obj.active.img.style.filter = 'Alpha(opacity=0);';
	                 // transition speed
	                // create transition
	                var t = new OpacityTween(obj.active.img,Tween.regularEaseIn, 0, 100,1);
	                // start transiton
	                t.start();
					obj.locked = true;
					t.onMotionFinished = function () {
					obj.locked = false;
					}
	            }
	            obj.active.className += ' active';
	        // if passed inactive remove classname
	        } else if (state === 'inactive') {
	            // find image source
	            obj.active.img.src = obj.active.img.getAttribute('SRC');
	            // set container background equal to active image src
	            obj.container.style.background = "#fff url(" + obj.active.img.src + ") 1px 1px no-repeat";
	            // make item inactive by replacing the active classname
	            obj.active.className = obj.active.className.replace('active','');   
	        }
	    }
		// make item inactive
		changeState('inactive');
		// if reached the end, go to start
		if (this.marker === (this.items.length - 1) && dir === 1) this.marker = 0;
		// if previous and at the start, go to end
		else if (dir === 0 && this.marker === 0) this.marker = this.items.length -1;
		// preivous 
		else if (dir === 0 && this.marker != 0) -- this.marker;
		// preivous next
		else if (dir === 1) ++ this.marker;
		// make item active
		changeState('active');
		// refresh the item count display to show new position	
		this.updateCount();
	} else return false;
}

ndm.controls.ramonomatic.prototype.addItem = function ( item) {
    // add new image reference
    this.items.push(item);
    // refresh the item count display to show new position
    this.updateCount();
}

ndm.controls.ramonomatic.prototype.updateCount = function () {
    this.index.innerHTML = "Image " + (this.marker + 1) + "/" + this.items.length;
}

ndm.controls.ramonomatic.prototype.pause = function () {
    // cancel loop (initiated in 'start' method)
        if (this.cycle) 
            clearInterval(this.cycle);
}


/* =Slidorama 
---------------------------------------------------------------------- */
ndm.controls.slidorama = function ( options ) {
    // find nodes (Found by Classname, ID, or DOM ref)
    this.container      =   p                   =   options.container;  
    this.back           =   options.back        ?   find ( options.back,p )     :   ndm.dom.findNodes('back',p)[0];
    this.forward        =   options.forward     ?   find ( options.forward,p )  : ndm.dom.findNodes('forward',p)[0]; 
    this.items          =   options.items       ?   find ( options.items,p )    : ndm.dom.findNodes('module-item',p);
    this.scrollArea     =   options.scrollArea  ?   find ( options.scrollArea,p )  : ndm.dom.findNodes('module-wrap',p)[0];
    
    // properties
    this.increments     =   options.increments      ||  this.items[0].offsetWidth;
    this.speed          =   options.speed           ||  1;
    this.marker         =   options.start_point     ||  0;
	this.index			= 1;
    this.interval = null;
	this.locked = false;
}

ndm.controls.slidorama.prototype.start = function () {
    // object reference
    var obj = this;
    // if tween library exists
		this.countIndex();
        // set width of scroll area
        this.scrollArea.style.width = (this.increments * this.items.length) + 'px';
		
        // next handler
        this.forward.onclick = function () {
            //check if trigger is active
            if (this.className.indexOf('inactive')) {
                // call move method
                obj.move(1);
            }
            // cancel browser default action
            return(false);
        }
        // previous handler
        this.back.onclick = function () {
            //check if trigger is active
            if (this.className.indexOf('inactive')) {
                // call move method
                obj.move(0);
            }
			// cancel browser default action
            return(false);
        }
   this.container.onmouseover = function () {
			ndm.events.scheduler.stop();
		}
		
		this.container.onmouseout = function () {
			ndm.events.scheduler.start(10000);
		}
    this.cycle();
}

ndm.controls.slidorama.prototype.countIndex = function () {
	var obj = this;
	// create tracking node
	var index = document.createElement('span');
	index.className = 'index';
	index = this.forward.parentNode.insertBefore(index,this.forward);
	this.update = function ( dir) {
		if(index.firstChild) index.removeChild(index.firstChild);
		if (dir === 1) 
			obj.index = (obj.index === obj.items.length) ? 1 : ++obj.index;
		else if (dir === 0) 
			obj.index = (obj.index === 1) ? obj.items.length : --obj.index;
		var textNode = document.createTextNode(obj.index + ' of ' + obj.items.length);
		index.appendChild(textNode);
	}
	this.update();
}

ndm.controls.slidorama.prototype.cycle = function () {
    var obj = this;
    ndm.events.scheduler.addSchedule(function () {obj.move(1);});
    
}

ndm.controls.slidorama.prototype.reorder = function ( dir) {
	if (dir === 1) {
		this.scrollArea.removeChild(this.items[0]);
		this.scrollArea.style.right = 0 + 'px';
		node = this.scrollArea.appendChild(this.items[0].cloneNode(true));
		var newArray = [];
		for (var i=1; i < this.items.length; i++)
			newArray.push(this.items[i]);
		this.items = newArray;  
		this.items.push(node);
	} else {
		var node = this.items[this.items.length -1].cloneNode(true);
		this.scrollArea.removeChild(this.items[this.items.length -1]);
		this.scrollArea.style.right = this.increments + 'px';
		node = this.scrollArea.insertBefore(node,this.items[0]);
		var newArray = [];
		newArray.push(node);    
		for (var i=0; i < this.items.length - 1; i++) {
			if (typeof(this.items[i]) == 'object')
				newArray.push(this.items[i]);
		}
		this.items = newArray;      
	}
}

ndm.controls.slidorama.prototype.move = function ( dir) {
	if (typeof(Tween) !== 'undefined') {
		var obj = this;
		// forward method
		if (dir === 1 && !obj.locked) {
			// calculate final position
			var target = this.increments;
			// check if end of scroll area has been reached
			if (target < this.scrollArea.scrollWidth) {
				if (obj.marker > 0) obj.reorder(dir);
				// create tween instance
				var movement = new Tween(this.scrollArea.style,'right',Tween.regularEaseOut,0,target,this.speed,'px');
				// start tween
				movement.start();
				obj.locked = true;
				movement.onMotionFinished = function () {
				obj.marker = 1;
				obj.update(dir);
				obj.locked = false;
				}
			}
			
		}
		// back method
		else if (dir === 0 && !obj.locked) {
			// check if start of scroll area has been reached
			if (this.marker == 0) this.reorder(dir);
			// create tween instance
			var movement = new Tween(this.scrollArea.style,'right',Tween.regularEaseOut,this.increments,0,this.speed,'px');
			// start tween
			movement.start();
			obj.locked = true;
			movement.onMotionFinished = function () {
			obj.marker = 0;
			obj.update(dir);
			obj.locked = false;
			}
		}
	}
}


/* =Tabadabado
---------------------------------------------------------------------- */
ndm.controls.tabadabado = function ( options ) {
    // set container and parent
    this.container  =   p   = options.container;
    // find tabs
    this.tabs       =   options.tabs ? ndm.dom.findNodes(options.tabs,p) : ndm.dom.findNodes('tab',p);
    // event used to activate tab
    this.trigger    =   options.trigger ? options.trigger : 'onclick';
    // items
    this.items      =   options.items ? ndm.dom.findNodes(options.items,p) : ndm.dom.findNodes('module-item',p);
    // active states
    this.active = {};
}

ndm.controls.tabadabado.prototype.start = function () {
    // object reference for closures
    var obj = this;
    // loop through tabs
    for (var i=0; i < this.tabs.length; i++) {
        // find active
        if (this.tabs[i].className.indexOf('active') != -1) {
            this.active.tab = this.tabs[i];
        }
        
    // run method after event
        this.tabs[i][this.trigger] = function () {
            // call tab method
            // cancel default
            return obj.tab(this);
        };
    }
    
    for (var i=0; i < this.items.length; i++) {
        if (this.tabs[i].className.indexOf('active') != -1) {
            this.active.item = this.items[i];
        }
    }
}

ndm.controls.tabadabado.prototype.tab = function ( node) {
	if (this.active.item) {
		this.active.tab.className = this.active.tab.className.replace('active','');
	    this.active.item.className = this.active.item.className.replace('active','');
	    this.active.tab = node;
	    var l = node.getElementsByTagName('A')[0].getAttribute('href')
		
		if (ndm.dom.byID(l.substring(l.indexOf('#') + 1,l.length))) {
		    this.active.item = ndm.dom.byID(l.substring(l.indexOf('#') + 1,l.length)); 
		    this.active.tab.className += ' active';
		    this.active.item.className += ' active';
		}
	}
	return false;
}

/* =Fontofreako
---------------------------------------------------------------------- */
ndm.controls.fontofreako = function ( options ) {
    this.container              = options.container;
    this.font_dec               = ndm.dom.findNodes('font-dec')[0];
    this.font_inc               = ndm.dom.findNodes('font-inc')[0];
    this.font_size              = options.font_size;
    this.font_max               = options.font_max      || 3;
    this.font_min               = options.font_min      || 0.75;
    this.saveable               = options.saveable      || true;
    this.save_class             = options.save_class    || 'save';
    this.save_msg               = options.save_msg      || 'Save Settings';
    this.inc                    = options.inc           || 0.1;
}

ndm.controls.fontofreako.prototype.start = function () {
    var obj = this;

    this.font_size = this.font_size || parseFloat(ndm.client.readCookie('FontSize')) || 1;
    
    if(!this.target) this.target = document.getElementById(this.font_dec.getAttribute('rel'));
    this.target.style.fontSize =  this.font_size + 'em';
    
    this.font_inc.onmousedown = function () {obj.resize(1);};
    this.font_dec.onmousedown = function () {obj.resize(0);};
    this.font_dec.onmouseup = function () {obj.stop();}
    this.font_inc.onmouseup = function () {obj.stop();}
    this.font_inc.onmouseout = function () {obj.stop();};
    this.font_dec.onmouseout = function () {obj.stop();};
	
	this.font_dec.onclick = function() {
		return false;
	}
	
	this.font_inc.onclick = function() {
		return false;
	}
}

ndm.controls.fontofreako.prototype.save = function () {
    ndm.client.createCookie('FontSize',this.font_size,1000);
}

ndm.controls.fontofreako.prototype.stop = function () {
    if (this.scale) 
        clearInterval(this.scale);
}

ndm.controls.fontofreako.prototype.resize = function ( dir) {
    var obj =this;
    if(dir === 1 && this.font_size + 0.1 < this.font_max) {
        this.font_size += this.inc
        this.target.style.fontSize = this.font_size + 'em';
        
    } else if (dir === 0 && this.font_size - this.inc  > this.font_min) {
        this.font_size -= this.inc
        this.target.style.fontSize = this.font_size + 'em';
    } else {
        this.stop();
    }

    if(this.saveable && !this.save_obj) {
        var opts = {parent : this.container, message: this.save_msg, className : this.save_class, tag : 'span', beforeNode: this.container.firstChild, tween: true}
        this.save_obj = new ndm.common.message(opts);
        this.save_obj.node.style.cursor = 'pointer';
        this.save_obj.node.onclick = function () {
            obj.save();
            obj.save_obj.setMessage('Saved');
            obj.save_obj.hide(function () {obj.save_obj.remove(); obj.save_obj = null;},300);    
        }
    }   
}

/** links
------------------------------------------------------------------ */
_global_["@namespace"]("ndm.links");

/* group elements */
ndm.links.group = function ( prefix, tag ) {
    this.prefix = prefix;
	this.tag = tag;
	this.namespace = ndm.links;
}

ndm.links.group.prototype = new ndm.common.group;

ndm.links.makehome = function ( options ) {
    options.container.setAttribute("href", "/makehome");
    /*@cc_on @*/
    /*@if (@_win32)
        options.container.onclick = function () {
            try {
                this.style.behavior='url(#default#homepage)';
                this.setHomePage('http://www.theaustralian.news.com.au');
                return false;
            } catch (e) {}
        }
    /*@end @*/
}



ndm.links.lightbox = function ( options ) {
	if (arguments.length > 0) {
		var obj = this;
		this.tagName = 'div';
		this.parent = document.body;
		this.source = options.container.getAttribute('href');
		this.trigger = options.container;
		this.className = 'module lightbox';
		this.message = '';
		// find dimensions
		this.dims = (function() {
			// holds formatted type
			var formatted = options.container.getAttribute('rel');
			var dims = {width: 800, height:800};
			for (var i in dims) { (
				function () {
					// regular expression that matches first integer set in string
					formatted = formatted.replace(/[0-9]{1,}/,
					// method that deals with match
					function (thematch){
						// sets option property equal to match
						dims[i] = thematch;
					});
				})();
			}
			return dims
		 })();
		this.styles = {width: this.dims.width + 'px', height:this.dims.height + 'px'}
		// find type
		this.type = (function() {
			if (/.swf/.test(obj.source)) return 'flash';
			else if (/.jpg/.test(obj.source)) return 'image';
			else if (/.jpeg/.test(obj.source)) return 'image';
			else if (/.gif/.test(obj.source)) return 'image';
			else if (/.png/.test(obj.source)) return 'image';
			else return 'html';
		})();
	}
	this.init();
}

ndm.links.lightbox.prototype.constructor = ndm.links.lightbox;
ndm.links.lightbox.prototype = new ndm.common.message();

ndm.links.lightbox.prototype.init = function() {
	if (this.type === 'flash') this.prepFlash();
	else if (this.type === 'image') {
		this.buildImage();
		this.build();
	} else if (this.type === 'html') {
		this.buildHTML();
		this.build();
	}
}

ndm.links.lightbox.prototype.buildHTML = function() {
	var iframe = document.createElement('iframe');
	iframe.setAttribute('src',this.source);
	iframe.setAttribute('height',this.dims.height - 20);
	iframe.setAttribute('width',this.dims.width);
	iframe.setAttribute('frameborder',0);
	this.message = iframe;
}

ndm.links.lightbox.prototype.buildImage = function() {
	var img = document.createElement('img');
	img.setAttribute('src',this.source);
	this.message = img;
}

ndm.links.lightbox.prototype.prepFlash = function() {
	var obj = this;
	// generate script tag (UFO)
	var script = document.createElement('script');
	script.setAttribute('type','text/javascript');
	script.setAttribute('src','/js/swfobject');
	script = document.getElementsByTagName('head')[0].appendChild(script);
	var timeout = 0;
	//check if script has loaded. If true then init build
	var check = setInterval(function() {
		if (typeof(deconcept) === 'object') {
				obj.build();
			clearInterval(check);
		} else if (timeout > 1000) {
			clearInterval(check);
		}
		++timeout
	},100)
}

ndm.links.lightbox.prototype.buildFurniture = function() {
	var obj = this;
	var controls = document.createElement('div');
	controls.className = 'controls';
	controls.style.cursor = 'move';
	var closeButton = document.createElement('button');
	closeButton.setAttribute('type','button');
	closeButton.className = 'close';
	closeButton.appendChild(document.createTextNode('close'));
	controls.appendChild(closeButton);
	controls = this.node.insertBefore(controls,this.node.firstChild);
	
	closeButton.onclick = function() {
		var overlay = document.getElementById('lightbox-overlay');
		overlay.parentNode.removeChild(overlay);
		obj.remove();
	}
	ndm.common.drag.init(controls,this.node);
}


ndm.links.lightbox.prototype.buildOverlay = function() {
	var obj = this;
	
	
	
	// create overlay
	var overlay = document.createElement('div');
	
	
	// style overlay
	ndm.style.SetStyle.call(overlay, {
		height: document.documentElement.scrollHeight + 'px',
		width:  '100%',
		background: '#000',
		position: 'absolute',
		top: '0',
		left: '0',
		opacity: '0.7',
		filter: 'Alpha(opacity=70)',
		zIndex: 1100
	});
	// add to dom
	overlay = document.body.appendChild(overlay);
	overlay.id = 'lightbox-overlay';
	overlay.onclick = function() {
			try { 
			obj.remove();
			overlay.parentNode.removeChild(overlay);
			} catch (e) {};
	}
	
	ndm.style.SetStyle.call(this.node, {
		position: 'absolute',
		zIndex: 1200,
		left: document.body.offsetWidth/2 + 'px',
		marginTop: - (this.node.offsetHeight / 2) + 'px',
		marginLeft: - (this.node.offsetWidth / 2) + 'px'
		
	});
	
}

ndm.links.lightbox.prototype.updateNodePosition = function() {	
	var offsetVal = 50;
	if (parseInt(this.dims.width) < ndm.client.getWindowDim().width - offsetVal) {
		ndm.style.SetStyle.call(this.node, {
			width: this.dims.width,
			left: ndm.client.getWindowDim().width / 2 + 'px',
			marginLeft: -(this.node.offsetWidth / 2) + 'px',
			overflowX: 'hidden'
		});
		
	} else {
		ndm.style.SetStyle.call(this.node, {
			overflowX: 'scroll',
			width: document.documentElement.clientWidth - offsetVal + 'px'
		});
	}	
	
	if (parseInt(this.dims.height) < ndm.client.getWindowDim().height - offsetVal) {
		ndm.style.SetStyle.call(this.node, {
			top: ndm.client.getScrollY() + (ndm.client.getWindowDim().height / 2) + 'px',
			marginTop: -(this.node.offsetHeight / 2) + 'px',
			height: this.dims.height,
			overflowY: 'hidden'			   
		});
	} else {
		ndm.style.SetStyle.call(this.node, {
			top: ndm.client.getScrollY() + ndm.client.getWindowDim().height / 2 + 'px',
			overflowY: 'scroll',
			marginTop: -(this.node.offsetHeight / 2) + 'px',
			height: ndm.client.getWindowDim().height - offsetVal + 'px'
		});
	}
}

ndm.links.lightbox.prototype.build = function() {	
	var obj = this;

	obj.trigger.onclick = function() {
		obj.buildNode();
		obj.node.id = 'lightboxnode'
		if (obj.type === 'flash') {
			
			var so = new SWFObject(obj.source, "mymovie", obj.dims.width, obj.dims.height, "8", "#fff");
			so.write('lightboxnode');
		}		
		obj.buildOverlay();
		obj.buildFurniture();
		obj.updateNodePosition();
		ndm.events.onWindowMovement(function(){obj.updateNodePosition()});
		return false;
	}
}

ndm.dom.addInit(function () {
	 // run accessibility methods
    var access = ndm.common.detectjs();
    // search for and create controls
    var controls = new ndm.controls.group('widget','div');
	controls.init();
	
    // search for links requiring special handling
    var links = new ndm.links.group('link','a');
	links.init();
	

	if(typeof(formsInit) !== 'undefined') {
		formsInit();
	}
	
	if(document.body.className.indexOf('galleryfeature') !== -1) {
		ndm.dom.resizeParent( 'photo-frame', ndm.dom.byTag('div')[0] )
	}
	
    ndm.events.scheduler.start(10000);
	
	if (document.getElementById('tools-share')) {
		var tools = document.getElementById('tools-share').getElementsByTagName('li');
		
		for (var i=0; i < tools.length; i++) {
			tools[i].onclick = function() {
				var sid = window.location.href.split(",")[2];
		        _hbSet("cv.c7", this.className + "|" + hbx.pn);
		        _hbSend();
			}
		}
	}
	
	
	/*
	if (document.getElementById('breakingnews')) {
		var source;
		
		if (/homepage/.test(document.body.className)) {
			source = '/xml/breakingnews.xml';
		} else if (/business/.test(document.body.className)) {
			source = '/xml/business/breakingnews.xml';
		} else if (/the-nation/.test(document.body.className)){

			source = '/xml/thenation/breakingnews.xml';
		} else if (/the-world/.test(document.body.className)){
			source = '/xml/theworld/breakingnews.xml';
		}
		
		
		var breakingNews = ndm.controls.liveheadlines.BreakingNews(document.getElementById('breakingnews').getElementsByTagName('ul')[0],source);
		breakingNews.init(); 
	}*/
	
	
}, function () {return(true)}, function () {return(true)});

// hack for dodgy ad iframes in firefox
window.onpageshow = function() {
    ndm.common.fixIframes();
}



/** HBX 
------------------------------------------------------------------ */

ndm.dom.getEventTarget = function(e) { 
    var e = e || window.event;
    var targ = e.target || e.srcElement; 
    if (targ.nodeType == 3) { 
        // defeat Safari bug 
        targ = targ.parentNode; 
    } 
    return targ;
}

ndm.hbx = function() {
    var old = function() {};
    if (typeof document.onclick === "function") {
        old = document.onclick;
    }
    document.onclick = function(e) {
        var targ = ndm.dom.getEventTarget(e);
        var rel = targ.getAttribute("rel");
        var url = targ.getAttribute("href");
        if (/track/.test(rel)) {
            var s = rel.replace(/track-([a-zA-Z0-9]*)/gi, "$1") + "|" + encodeURI(window.location) + "-" + encodeURI(url);
            s = s.replace(/,/gi, "&#44;");
			_hbSet("cv.c9", s);
        	_hbSend();
        }
        old(e);
    };
}();


