// Script:  ddobj v3.00 (DHTML Drag-and-Drop Objects Framework)
// Company: Interaxis
// Author:  dynamicreport.com
// Website: http://dynamicreport.com/ddobj.html
// License: This script is subject to the EULA included in the ddobj package



// ****************** configurable drag and drop global variables

var dd_path = "gallery/images/"; // relative image path (transparent image, object skins, icons, etc.)
if (typeof dd_count == 'undefined')
	var dd_count = 3; // total # of objects -- increase for multiple concurrent drag-drop components
var dd_order = 300; // starting zIndex of first object (incremented with each object instance)
var dd_preload = "<p align = \"top\"><img src = \"" + dd_path + "preloader.gif\"></p>"; // preloader tag
var dd_copyright = false; // display copyright notice flag

// ****************** skin constants
var dd_s = {TAB : 0, CON : 1, CAP : 2, SLV : 3, CAP1 : 4, DEF : 5, MEDIA : 6, METAL : 7, PLAIN : 8, TAB1 : 9, CAP2 : 10};

// ****************** global variables

var dd_images = new Array (); // preloaded images array
var dd_groups = new Array (); // preloaded image group count array
var dd_pkg = new ddpkg (); // drag and drop object package
var dd_skin = new ddskin (); // drag and drop object skins
var dd_obj = new Array (); // drag and drop objects

// image preloader callback function
var dd_image_cb = function dd_image_default (grp)
			{
				for (var i = 0; i < dd_count; i++) // traverse all objects
				{
					if (dd_obj[i].getVis () == set_show) // visible object
					{
						if (dd_obj[i].skin == grp) // object belongs to completed skin image load
						{ // force object update
							// dd_obj[i].output ("", "", 0, 1); // update object's new dimension data and actual location to synchronize with final appearance
						}
					}
				}
			};

// browser detection and browser-specific DOM object values
var is_ns = is_ie = is_opera = features = 0;
var set_show = set_hide = "";
var is_css1_compatible = (document.compatMode == 'CSS1Compat' ? true : false); // pertains to doctype and DOM property interpretations



// ****************** general purpose functions

function dd_img_onload ()
{
	// ensure the object dimensions and location are up-to-date and in sync following load completion of all skin images
	dd_groups[this.grp]--;
	if (dd_groups[this.grp] <= 0) // completed group load of images
		if (dd_image_cb)
			dd_image_cb (this.grp); // call the callback function
}

function dd_img_preload ()
{ // generic image preloader
	if (!document.images)
		return;
	var args = dd_img_preload.arguments;
	var len = dd_images.length;
	var grp = args[0] - 1;
	var ii; // image index

	if (grp >= 0)
		dd_groups[grp] = args.length - 2; // number of images in this group
	for (var i = 2; i < args.length; i++)
	{ // first arg. is relative path
		ii = len + i - 2;
		dd_images[ii] = new Image();
		if (grp >= 0)
		{ // call group image onload event handler only if image group was specified (group index parameter = 1+)
			dd_images[ii].grp = grp;
			dd_images[ii].onload = dd_img_onload;
		}
		dd_images[ii].src = args[1] + args[i];
	}
}

function dd_setBrowser ()
{ // browser detection and DHTML feature selection
	var agt = navigator.userAgent.toLowerCase ();

	// determine browser types and versions
	if (agt.indexOf ("opera") != -1)
		is_opera = parseInt (navigator.appVersion);
	else if (navigator.appName == "Microsoft Internet Explorer")
		is_ie = parseInt (navigator.appVersion);
	else if (navigator.appName == "Netscape")
		is_ns = parseInt (navigator.appVersion);

	// browser-specific visibility flags
	set_show = (is_ns) ? 'show' : 'visible';
	set_hide = (is_ns) ? 'hide' : 'hidden';

	if (is_ns >= 5)
	{
		set_show = 'visible';
		set_hide = 'hidden';
	}

	// determine applicable features
	if (is_ie >= 4 || is_ns >= 5 || is_opera)
		features = 1;
	else if (is_ns >= 4)
		features = 2;
	else
		features = 0;
}

function dd_getClientX ()
{ // absolute left coordinate of visible screen relative to entire document
	if (is_css1_compatible)
		return document.documentElement.scrollLeft;
	return document.body.scrollLeft;
}

function dd_getClientY ()
{ // absolute top coordinate of visible screen relative to entire document
	if (is_css1_compatible)
		return document.documentElement.scrollTop;
	return document.body.scrollTop;
}

function dd_getClientW ()
{ // document width
	if (is_css1_compatible)
		return document.documentElement.clientWidth;
	return document.body.clientWidth;
}

function dd_getClientH ()
{ // document height
	if (is_css1_compatible && !is_opera)
		return document.documentElement.clientHeight;
	return document.body.clientHeight;
}

function dd_getAbsLeft (el)
{ // get relative object's absolute left coordinate
	var left = el.offsetLeft;
	while ((el = el.offsetParent) != null)
		left += el.offsetLeft;
	return left;
}

function dd_getAbsTop (el)
{ // get relative object's absolute top coordinate
	var top = el.offsetTop;
	while ((el = el.offsetParent) != null)
		top += el.offsetTop;
	return top;
}

function dd_trim (str)
{ // cross-browser friendly trim function
	var i, j = 0;
	for (i = 0; i < str.length; i++)
		if (str.charAt(i) == " ") continue;
		else
		{ // trim left
			str = str.substr (i, str.length);
			break;
		}
	for (i = str.length - 1; i >= 0; i--) // trim right
		if (str.charAt(i) == " ") continue;
		else return str.substr (0, i + 1);
}



// ****************** drag and drop object class

function ddobj ()
{
	// DOM object components -- when the motion flag is set, they are tracked by the document's mousemove and mousedown events
	this.ddobj = this.ddflt = this.ddcover = this.ddimg = this.ddc = this.ddw = null;

	// parameters adjustable within object params () function
	this.lock = 0; // button state depressed on object
	this.dragall = 0; // object array: internal flag marks whether the entire object is draggable (1) or just a portion (0 = default)
	this.drag = 1; // object specific flag to enable/disable draggable region
	this.flashobj = 0; // enable object on-off focus effect
	this.opacityin = 10; // initial opacity
	this.opacitystep = 20; // opacity adjustment amount
	this.opacityon = 100; // opacity of object on focus
	this.opacityoff = 55; // opacity of object off focus
	this.fadereset = 1; // reset fade when focus is lost (fade out is avoided)
	this.ignore_showhide = 0; // next function call to object's show () or hide () functions will exit immediately if set, flag is then cleared
	this.noreset = 0; // object specific flag to enable/disable object trigger reset (0 = reset is enabled by default)
	this.hideticks = -1; // object specific timer to hide object after a period of inactivity (-1 = no auto-hide by default)
	this.childticks = 100; // object specific timer to hide object after its child object has disappeared
	this.caption = ""; // object embedded caption (optional)
	this.content = dd_preload; // object embedded content (required)
	this.rewrite = 1; // rewrite caption/content each time output() or show() is called (default = 1), set to 0 for static content
	this.index = this.skin = 0; // object layer index and skin selector index
	this.id = ""; // object identification is blank by default
	this.anchor = ""; // object anchor element ID string
	this.anchor_el = ""; // object anchor element pointer
	this.anchor_w = 0; // offset object to anchor width
	this.anchor_h = 0; // offset object to anchor height
	this.x = -1; // initial popup object x location
	this.y = -1; // initial popup object y location
	this.w = 400; // object width (specification required)
	this.offx = this.offy = -15; // offset x, y from cursor
	this.ctrl = 1; // control panel activation
	this.ctrl_content = ""; // control panel embedded content (blank = default)
	this.ctrlw = 0; // control panel width
	this.ctrlh = 0; // control panel height
	this.parent = -1; // parent node of this object (-1 = root object, 0+ = index of other object)
	this.ploc = 0; // child node appears at parent node location
	this.pw = 0; // child node appears at an x offset of parent node width
	this.ph = 0; // child node appears at a y offset of parent node height
	this.drag_delay = 0; // 0 = end auto-hide delay of object if drag operation is initiated, 1 = resume delay
	this.cursor = "move"; // default move cursor for drag and drop hotspot region

	this.limit_t = -1; // limit top edge (-1 = top window edge, 0 = no limit, positive whole number = custom edge)
	this.limit_l = -1; // limit left edge (-1 = left window edge, 0 = no limit, positive whole number = custom edge)
	this.limit_b = -1; // limit bottom edge (-1 = bottom window edge, 0 = no limit, positive whole number = custom edge)
	this.limit_r = -1; // limit right edge (-1 = right window edge, 0 = no limit, positive whole number = custom edge)
	this.autox = -1; // auto adjust horizontal offset of tooltip to opposite edge if boundary is touched (0 = no limit, 1 = auto limit, -1 = force edge)
	this.autoy = 1; // auto adjust vertical offset of tooltip to opposite edge if boundary is touched (0 = no limit, 1 = auto limit, -1 = force edge)

	// internal working values
	this.forced = 0; // forced tooltip motion flag
	this.rx = this.ry = 0; // cursor position relative to layer
	this.ddw_w = this.ddw_h = this.off_w = 0; // object specific
	this.posx = this.posy = 0; // top, left object coordinates
	this.written = 0; // output flag working values
	this.opacity = 0; // current opacity
	this.opacitydir = 0; // direction of gradual opacity adjustment
	this.child = new Array (); // array of child nodes
	this.zIndex = 0; // z-index record
	this.sVis = set_hide; // object visibility flag
	this.tmp_limit_t = this.tmp_limit_l = this.tmp_limit_b = this.tmp_limit_r = 0;

	// *** additional information stored by objects and for use by external apps. / class prototypes outside the scope of this framework
	this.arr_extra = new Array ();

	// class function assignment
	this.params = params;
	this.init = init;
	this.mklyrs = mklyrs;
	this.startHide = startHide;
	this.stopHide = stopHide;
	this.resetHide = resetHide;
	this.update = update;
	this.setW = setW;
	this.getX = getX;
	this.getY = getY;
	this.getW = getW;
	this.getH = getH;
	this.getPX = getPX;
	this.getPY = getPY;
	this.getPW = getPW;
	this.getPH = getPH;
	this.getVis = getVis;
	this.setOffX = setOffX;
	this.setOffY = setOffY;
	this.setOffset = setOffset;
	this.down = down;
	this.release = release;
	this.output = output;
	this.effect = effect;
	this.order = order;
	this.show = show;
	this.hide = hide;
	this.vis = vis;
	this.setControls = setControls;


	function params (arr_params)
	{
		if (!dd_pkg.ok ())
			return false;

		for (var key in arr_params)
		{
			switch (key)
			{
				case "NORESET":
					this.noreset = arr_params[key];
					if (this.noreset && this.sVis == set_hide)
						this.noreset = 0; // avoid forever hidden object situation
					break;
				case "IGNORE_SHOWHIDE":
					this.ignore_showhide = arr_params[key];
					break;
				case "OFFX":
					this.offx = arr_params[key];
					break;
				case "OFFY":
					this.offy = arr_params[key];
					break;
				case "DRAGALL":
					this.dragall = arr_params[key];
					break;
				case "DRAG":
					this.drag = arr_params[key];
					break;
				case "DRAG_DELAY":
					this.drag_delay = arr_params[key];
					break;
				case "CONTROL":
					this.ctrl = arr_params[key];
					break;
				case "LIMIT_T":
					this.limit_t = arr_params[key];
					break;
				case "LIMIT_L":
					this.limit_l = arr_params[key];
					break;
				case "LIMIT_R":
					this.limit_r = arr_params[key];
					break;
				case "LIMIT_B":
					this.limit_b = arr_params[key];
					break;
				case "AUTOX":
					this.autox = arr_params[key];
					break;
				case "AUTOY":
					this.autoy = arr_params[key];
					break;
				case "X":
					this.x = this.posx = arr_params[key];	
					break;
				case "Y":
					this.y = this.posy = arr_params[key];
					break;
				case "W":
					this.w = arr_params[key];
					break;
				case "ANCHOR":
					if (features == 2) break; // not supported by NS4
					this.anchor = arr_params[key];
					if (document.getElementById (this.anchor)) // valid object ID
						this.anchor_el = document.getElementById (this.anchor);
					else // invalid object ID
						this.anchor = this.anchor_el = "";
					break;
				case "ANCHOR_W":
					this.anchor_w = arr_params[key];
					break;
				case "ANCHOR_H":
					this.anchor_h = arr_params[key];
					break;
				case "ID":
					this.id = arr_params[key];
					break;
				case "INDEX":
					this.index = arr_params[key];
					if (this.index < 0)
						this.index = 0;
					else if (this.index >= dd_count)
						this.index = dd_count - 1;
					break;
				case "SKIN":
					this.skin = arr_params[key];
					if (this.skin < 0 || this.skin >= dd_skin.skins)
						this.skin = 0; // safety measure to force skin index 0 if beyond limits
					break;
				case "FLASHOBJ":
					this.flashobj = arr_params[key];
					break;
				case "OPACITY_ON":
					this.opacityon = arr_params[key];
					if (this.opacityon < 10)
						this.opacityon = 10;
					break;
				case "OPACITY_OFF":
					this.opacityoff = arr_params[key];
					if (this.opacityoff < 10)
						this.opacityoff = 10;
					break;
				case "OPACITY_IN":
					this.opacityin = arr_params[key];
					if (this.opacityin < 10)
						this.opacityin = 10;
					break;
				case "OPACITY_STEP":
					this.opacitystep = arr_params[key];
					if (this.opacitystep <= 0)
						this.opacitystep = 1;
					break;
				case "CURSOR":
					this.cursor = arr_params[key];
					break;
				case "FADERESET":
					this.fadereset = arr_params[key];
					break;
				case "REWRITE":
					this.rewrite = arr_params[key];
					break;
				case "PARENT":
					this.parent = arr_params[key];
					if (this.parent >= 0 && this.index != this.parent && this.parent < dd_count)
					{ // valid node index, add node to child list for this object
						var len = dd_obj[this.parent].child.length;
						dd_obj[this.parent].child[len] = this.index;
					}
					break;
				case "PLOC":
					this.ploc = arr_params[key];
					break;
				case "PW":
					this.pw = arr_params[key];
					break;
				case "PH":
					this.ph = arr_params[key];
					break;
				case "RESET_PARAMS":
					this.dragall = 0;
					this.drag = 1;
					this.flashobj = 0;
					this.opacityin = 10;
					this.opacitystep = 20;
					this.opacityon = 100;
					this.opacityoff = 55;
					this.fadereset = 1;
					this.ignore_showhide = 0;
					this.noreset = (arr_params[key] == 2 ? 0 : this.noreset);
					this.caption = "";
					this.content = dd_preload;
					this.x = this.y = -1;
					this.w = 400;
					this.offx = this.offy = -15;
					this.ctrl = 1;
					if (arr_params[key] == 2)
						this.ctrl_content = "";
					this.limit_t = this.limit_l = this.limit_b = this.limit_r = -1;
					this.autox = -1;
					this.autoy = 1;
					this.drag_delay = 0;
					this.parent = -1;
					this.ploc = this.pw = this.ph = 0;
					this.cursor = "move";
					this.rewrite = 1;
					break;
			}
		}
		if (!this.noreset && !dd_pkg.locked)
			this.update (0);

		return true;
	}

	function init ()
	{
		if (init.arguments.length > 0)
			this.index = init.arguments[0];

		var sExt = "dd" + this.index;

		this.mklyrs (sExt);

		if (features == 1)
		{
			this.ddobj = document.getElementById ("ovr_" + sExt); // set all object references
			this.ddflt = document.getElementById ("flt_" + sExt);
			this.ddimg = document.getElementById (sExt);
			this.ddc = document.getElementById ("c_" + sExt);
			if (is_ie) // iframe hack for IE
				this.ddcover = document.getElementById ("cvr_" + sExt);
			// track W3C DOM standard events
			this.ddimg.onmousedown = this.down;
			this.update (0);
		}
		else if (features == 2)
		{
			this.ddimg = document[sExt];
			this.ddobj = document.layers["ovr_" + sExt];
			this.ddflt = document.layers["flt_" + sExt];
			this.ddc = document.layers["c_" + sExt];
			// track DOM events with Netscape 4.x
			window.document.layers["ovr_" + sExt].captureEvents (Event.MOUSEDOWN);
			window.document.layers["ovr_" + sExt].onmousedown = this.down;
			this.update (0);
		}
	}

	function mklyrs (sExt)
	{
		var lyr = null;
		var static_index = this.index;

		if (document.layers)
		{
			// drag region hotspot image layer
			lyr = document.layers["ovr_" + sExt] = new Layer (0);
			lyr.name = "ovr_" + sExt; lyr.position = "absolute"; lyr.visibility = "hide";
			lyr.left = "0"; lyr.top = "0"; lyr.zIndex = dd_order + 1;
			lyr.document.open ();
			lyr.document.write ("<img src = '" + dd_path + "trans.gif' name = '" + sExt + "' id = '" + sExt + "' alt = '' onmouseover = 'javascript: dd_obj[" + this.index + "].stopHide ();' onmouseout = 'javascript: dd_obj[" + this.index + "].startHide ();'>");
			lyr.document.close ();

			// control panel object layer
			lyr = document.layers["c_" + sExt] = new Layer (0);
			lyr.name = "c_" + sExt; lyr.position = "absolute"; lyr.visibility = "hide";
			lyr.left = "0"; lyr.top = "0"; lyr.zIndex = dd_order + 2;
			lyr.onmouseover = function () { dd_obj[static_index].stopHide (); };
			lyr.onmouseout = function () { dd_obj[static_index].startHide (); };

			// entire object layer encompasses everything inside
			lyr = document.layers["flt_" + sExt] = new Layer (0);
			lyr.name = "flt_" + sExt; lyr.position = "absolute"; lyr.visibility = "hide";
			lyr.left = "0"; lyr.top = "0"; lyr.zIndex = dd_order;
			lyr.onmouseover = function () { dd_obj[static_index].stopHide (); };
			lyr.onmouseout = function () { dd_obj[static_index].startHide (); };
		}
		else if (document.getElementById)
		{
			// drag region hotspot image layer
			lyr = document.createElement ('div');
			document.body.appendChild (lyr);
			lyr.id = "ovr_" + sExt; lyr.style.position = "absolute"; lyr.style.visibility = "hidden";
			lyr.style.left = "0"; lyr.style.top = "0";
			lyr.style.zIndex = dd_order + 1;
			lyr.innerHTML = "<img src = '" + dd_path + "trans.gif' name = '" + sExt + "' id = '" + sExt + "' galleryimg = 'no' alt = '' title = '' onmouseover = 'javascript: dd_obj[" + this.index + "].stopHide ();' onmouseout = 'javascript: dd_obj[" + this.index + "].startHide ();'>";

			// object iframe cover to overlap select drop down lists for IE
			if (is_ie)
			{
				lyr = document.createElement ('iframe');
				document.body.appendChild (lyr);
				lyr.id = "cvr_" + sExt; lyr.style.position = "absolute"; lyr.style.visibility = "hidden";
				lyr.style.left = "0"; lyr.style.top = "0";
				lyr.style.display = "none"; lyr.scrolling = "no"; lyr.frameborder = 0; lyr.marginwidth = 0; lyr.marginheight = 0; lyr.src = "";
				lyr.style.zIndex = 1;
			}

			// entire object layer encompasses everything inside
			lyr = document.createElement ('div');
			document.body.appendChild (lyr);
			lyr.id = "flt_" + sExt; lyr.style.position = "absolute"; lyr.style.visibility = "hidden";
			lyr.style.left = "0"; lyr.style.top = "0";
			lyr.style.zIndex = dd_order;
			lyr.onmouseup = function () { dd_obj[static_index].order (); return false; };
			lyr.onmouseover = function () { dd_obj[static_index].stopHide (); };
			lyr.onmouseout = function () { dd_obj[static_index].startHide (); };

			// control panel object layer
			lyr = document.createElement ('div');
			document.getElementById ("ovr_" + sExt).appendChild (lyr);
			lyr.id = "c_" + sExt; lyr.style.position = "absolute"; lyr.style.visibility = "hidden";
			lyr.style.left = "0"; lyr.style.top = "0";
			lyr.style.zIndex = dd_order + 1;
			lyr.onmouseover = function () { dd_obj[static_index].stopHide (); };
			lyr.onmouseout = function () { dd_obj[static_index].startHide (); };
		}
		dd_order += 2; // increase z-order (draw stacking order index) for next object
	}

	function startHide ()
	{
		if (this.hideticks == -2)
			this.hideticks = 1;
	}

	function stopHide ()
	{
		if (this.hideticks >= 0)
			this.hideticks = -2;
	}

	function resetHide ()
	{
		if (!dd_pkg.locked) // do not allow this object visibility timer to be reset if an object is locked (moving)
			this.hideticks = 1;
	}

	function update (active)
	{
		var sExt = "dd" + this.index;

		if (features == 1)
		{
			if (active)
			{
				this.ddimg.style.width = this.ddw.offsetWidth + "px";
				this.ddimg.style.height = (this.dragall && this.drag ? this.ddflt.offsetHeight : (!this.drag ? 1 : dd_skin.dragy[this.skin])) + "px";
				this.ddflt.style.width = this.ddobj.style.width = this.ddw.offsetWidth + "px";
				this.ddobj.style.height = (this.dragall && this.drag ? this.ddflt.offsetHeight : (!this.drag ? 1 : dd_skin.dragy[this.skin])) + "px";
				this.ddw_w = (is_ns ? this.ddflt.offsetWidth : this.ddw.offsetWidth);
				this.ddw_h = (is_ns ? this.ddflt.offsetHeight : this.ddw.offsetHeight);
				this.ddc.style.width = this.ctrlw + "px";
				this.ddc.style.height = this.ctrlh + "px";
				this.off_w = parseInt (this.ddflt.style.width);
				if (!this.drag)
					this.ddobj.style.cursor = "default";
				else
					this.ddobj.style.cursor = this.cursor;
				if (is_ns)
				{ // set the offset position of the control panel object layer (Mozilla browsers)
					this.ddc.style.top = dd_skin.ctrly[this.skin] + "px";
					this.ddc.style.left = this.ddobj.offsetWidth - this.ddc.offsetWidth + dd_skin.ctrlx[this.skin] + "px";
				}
				else
				{ // set the offset position of the control panel object layer (other browsers)
					this.ddc.style.posTop = dd_skin.ctrly[this.skin];
					this.ddc.style.posLeft = this.ddobj.offsetWidth - this.ddc.offsetWidth + dd_skin.ctrlx[this.skin];
				}
				var img;
				if (this.ddc.getElementsByTagName)
					for (var i = 0; i < this.ddc.getElementsByTagName('IMG').length; i++)
					{ // ensure all contained image cursors are associated with the hyperlink cursor
						var img = this.ddc.getElementsByTagName('IMG')[i];
						img.style.cursor = "hand";
					}
			}
			else
			{
				this.ddflt.style.visibility = set_hide;
				this.ddobj.style.visibility = set_hide;
				this.ddc.style.visibility = set_hide;
			}
			if (is_ie)
			{
				if (active)
				{
					this.ddcover.style.width = this.ddw.style.width;
					this.ddcover.style.height = this.ddw.offsetHeight;
				}
				else
				{
					this.ddcover.style.visibility = set_hide;
					this.ddimg.style.visibility = set_hide;
				}
				// iframe hack for drop-down in earlier IE versions to appear below layer
				this.ddcover.style.display = "inline";
				this.ddcover.style.left = this.ddflt.style.left;
				this.ddcover.style.top = this.ddflt.style.top;
			}
			if (active) // ensure the offset is adjusted to take into account limits after content has loaded completely (e.g. AJAX)
				this.setOffset (this.posx, this.posy); // move action associated with object tracking cursor -- set offset from cursor position (cx/cy already assigned by move or down event handlers)

		}
		else if (features == 2)
		{
			if (this.ddflt)
			{
				if (active)
				{
					this.ddobj.left = this.ddflt.left;
					this.ddobj.top = this.ddflt.top;
					this.ddobj.document.open ();
					this.ddobj.document.write ("<img src = '" + dd_path + "trans.gif' id = '" + sExt + "' name = '" + sExt + "' border = '0' width = '" + this.ddflt.clip.right + "' height = '" + (this.dragall && this.drag ? this.ddflt.clip.bottom : (!this.drag ? 1 : dd_skin.dragy[this.skin])) + "'>");
					this.ddobj.document.close ();
					this.ddw_w = this.ddflt.clip.right;
					this.ddw_h = this.ddflt.clip.bottom;
				}
				else
				{
					this.ddflt.visibility = set_hide;
					this.ddobj.visibility = set_hide;
					this.ddc.visibility = set_hide;
				}
			}
		}
		return true;
	}

	function setW (w)
	{ // resize the object content width
		if (features == 2 || w == this.getW ())
			return false; // width is already set or NS4 not supported by this method
		this.w = w;
		this.ddw.style.width = w + "px";
		this.update (1); // resize the entire drag and drop object based on the new width
		return true;
	}

	function getX () { return this.posx; }
	
	function getY () { return this.posy; }

	function getW () { return this.ddw_w; }

	function getH () { return this.ddw_h; }

	function getVis () { return this.sVis; }

	function getPX ()
	{
		// return parent X coord.
		if (this.ploc && this.parent >= 0)
			return dd_obj[this.parent].getX ();
	}

	function getPY ()
	{
		// return parent Y coord.
		if (this.ploc && this.parent >= 0)
			return dd_obj[this.parent].getY ();
	}

	function getPW ()
	{
		// return parent width dimension
		if (this.ph && this.ploc && this.parent >= 0)
			return dd_obj[this.parent].getW ();
	}

	function getPH ()
	{
		// return parent height dimension
		if (this.ph && this.ploc && this.parent >= 0)
			return dd_obj[this.parent].getH ();
	}

	function setOffX (offsetX)
	{
		if (features == 1)
		{
			if (this.limit_l < 0 || this.forced) // tooltip motion forced to client dimensions
				this.tmp_limit_l = dd_getClientX ();
			else if (this.limit_l)
				this.tmp_limit_l = this.limit_l;
			if (this.limit_r < 0 || this.forced) // tooltip motion forced to client dimensions
				this.tmp_limit_r = dd_getClientX () + dd_getClientW () - 1;
			else if (this.limit_r)
				this.tmp_limit_r = this.limit_r;
	
			if (this.limit_l && (offsetX < this.tmp_limit_l))
			{
				if (!dd_pkg.locked && this.autox == 1)
				{ // enable tooltip auto-adjust location
					offsetX += (this.offx > 0 ? this.offx + (this.offx - this.ddw_w) : (this.ddw_w + this.offx * 2));
					if (this.limit_r && (offsetX + this.off_w > this.tmp_limit_r))
						offsetX = this.tmp_limit_l;
				}
				else if (dd_pkg.locked || this.autox == -1)
					offsetX = this.tmp_limit_l;
			}
			else if (this.limit_r && (offsetX + this.off_w > this.tmp_limit_r))
			{
				if (!dd_pkg.locked && this.autox == 1)
				{ // enable tooltip auto-adjust location
					offsetX -= (this.ddw_w - (this.offx > 0 ? this.offx : this.offx * 2));
					if (this.limit_l && (offsetX < this.tmp_limit_l))
						offsetX = this.tmp_limit_r - this.off_w;
				}
				else if (dd_pkg.locked || this.autox == -1)
				{
					if (!dd_pkg.locked && (this.ph || this.pw))
					{
						if (this.ph)
							offsetX = this.getPX () + this.getPW () - this.getW ();
						if (this.pw)
							offsetX = this.getPX () - this.getW () + this.offx;
					}
					else
						offsetX = this.tmp_limit_r - this.off_w;
				}
			}
		}
		return offsetX;
	}

	function setOffY (offsetY)
	{
		if (features == 1)
		{
			if (this.limit_t < 0 || this.forced) // tooltip motion forced to client dimensions
				this.tmp_limit_t = dd_getClientY ();
			else if (this.limit_t)
				this.tmp_limit_t = this.limit_t;
			if (this.limit_b < 0 || this.forced) // tooltip motion forced to client dimensions
				this.tmp_limit_b = dd_getClientY () + dd_getClientH ();
			else if (this.limit_b)
				this.tmp_limit_b = this.limit_b;

			if (this.limit_t && (offsetY < this.tmp_limit_t))
			{
				if (!dd_pkg.locked && this.autoy == 1)
				{ // enable tooltip auto-adjust location
					offsetY += (this.offy > 0 ? this.offy + (this.offy - this.ddw_h) : (this.ddw_h + this.offy * 2));
					if (this.limit_b && (offsetY + this.ddw_h > this.tmp_limit_b))
						offsetY = this.tmp_limit_t;
				}
				else if (dd_pkg.locked || this.autoy == -1)
					offsetY = this.tmp_limit_t;
			}
			else if (this.limit_b && (offsetY + this.ddw_h > this.tmp_limit_b))
			{
				if (!dd_pkg.locked && this.autoy == 1)
				{ // enable tooltip auto-adjust location
					if (this.ph)
						offsetY = this.getPY () - this.getH () + this.offy;
					else
						offsetY -= (this.ddw_h - (this.offy > 0 ? this.offy : this.offy * 2));
					if (this.limit_t && (offsetY < this.tmp_limit_t))
						offsetY = this.tmp_limit_b - this.ddw_h;

				}
				else if (dd_pkg.locked || this.autoy == -1)
					offsetY = this.tmp_limit_b - this.ddw_h;
			}
		}
		return offsetY;
	}

	function setOffset (offsetX, offsetY)
	{
		if (features == 1)
		{
			offsetX = this.setOffX (offsetX); // restrict horizontal offset to boundary dimensions
			offsetY = this.setOffY (offsetY); // restrict vertical offset to boundary dimensions
			if (is_ns)
			{
				this.ddobj.style.left = this.ddflt.style.left = offsetX + "px";
				this.ddobj.style.top = this.ddflt.style.top = offsetY + "px";
			}
			else
			{
				this.ddobj.style.posLeft = this.ddflt.style.posLeft = offsetX;
				this.ddobj.style.posTop = this.ddflt.style.posTop = offsetY;
				if (is_ie)
				{
					this.ddcover.style.posLeft = offsetX;
					this.ddcover.style.posTop = offsetY;
					// ensure cover (iframe) height is synchronized with table
					if (this.ddcover.style.height != this.ddw.offsetHeight)
						this.ddcover.style.height = this.ddw.offsetHeight;
				}
			}
		}
		else if (features == 2)
		{
			this.ddobj.left = this.ddflt.left = offsetX;
			this.ddobj.top = this.ddflt.top = offsetY;
			this.ddc.top = offsetY + dd_skin.ctrly[this.skin];
			this.ddc.left = this.ddobj.left + this.ddflt.clip.right - this.ddc.clip.right + dd_skin.ctrlx[this.skin];
		}
		this.posx = offsetX;
		this.posy = offsetY;
	}

	function down (e) // called once only when the mouse button is clicked initially
	{
		if (features == 1)
		{
			if (is_ns)
			{
				if (!e)
					return true;
				i = parseInt (e.target.name.substr (2, e.target.name.length));
				dd_pkg.cx = e.pageX; // obtain cursor position
				dd_pkg.cy = e.pageY;
			}
			else
			{
				if (!window.event)
					return false;
				i = parseInt (window.event.srcElement.id.substr (2, window.event.srcElement.id.length));
				dd_pkg.cx = window.event.clientX + dd_getClientX (); // obtain cursor position
				dd_pkg.cy = window.event.clientY + dd_getClientY ();
			}
			dd_obj[i].forced = 0;
			dd_obj[i].order (); // bring the selected layer to the front

			if (!dd_obj[i].drag) // disable drag operation
			{
				dd_obj[i].release ();
				if (dd_obj[i].cbdown)
					dd_obj[i].cbdown (); // *** prototype callback for object button click
				return false;
			}
			if (!dd_obj[i].drag_delay) // disable object auto-hide delay
				dd_obj[i].hideticks = -1;
			dd_obj[i].lock = 1; // individual object lock down
			dd_pkg.locked = 1; // flag the lock down (global lock flag)

			dd_obj[i].rx = dd_pkg.cx - parseInt (dd_obj[i].ddobj.style.left); // calculate cursor position relative to layer
			dd_obj[i].ry = dd_pkg.cy - parseInt (dd_obj[i].ddobj.style.top);

			if (dd_obj[i].cbdown)
				dd_obj[i].cbdown (); // *** prototype callback for object button click

			return false;
		}
		else if (features == 2)
		{
			if (!e)
				return false;
			dd_pkg.cx = e.pageX; // obtain cursor location
			dd_pkg.cy = e.pageY;

			i = parseInt (e.target.name.substr (2, e.target.name.length));
			dd_obj[i].forced = 0;
			dd_obj[i].order (); // bring the selected layer to the front
			if (!dd_obj[i].drag) // disable drag operation
			{
				dd_obj[i].release ();
				if (dd_obj[i].cbdown)
					dd_obj[i].cbdown (); // *** prototype callback for object button click
				return false;
			}
			if (!dd_obj[i].drag_delay) // disable object auto-hide delay
				dd_obj[i].hideticks = -1;
			dd_obj[i].lock = 1; // individual object lock down
			dd_pkg.locked = 1; // flag the lock down (global lock flag)

			dd_obj[i].rx = dd_pkg.cx - dd_obj[i].ddobj.left; // calculate cursor position relative to layer
			dd_obj[i].ry = dd_pkg.cy - dd_obj[i].ddobj.top;

			if (dd_obj[i].cbdown)
				dd_obj[i].cbdown (); // *** prototype callback for object button click

			return false;
		}
		return true;
	}

	function release ()
	{
		// clear current objects since they're not being tracked for motion (drag-drop operation non-existent)
		// user-call version of the up function to release the object drag operation safely without obscure interruption
		// of the drag operation of another object
		if (!dd_pkg.locked)
		{
			dd_pkg.locked = this.forced = this.lock = 0;
		}
		return true;
	}

	function output (sCaption, sContent, w, force)
	{
		if (!dd_pkg.ready) // not yet initialized or object is in motion
			return false;

		if (!force)
		{
			if (dd_pkg.locked) // not yet initialized or object is in motion
				return false;
			if (this.written && !this.rewrite)
				return false;
		}
		if (sCaption)
			this.caption = sCaption;
		if (sContent)
			this.content = sContent;
		if (w == null)
			w = 0;
		if (w >= 0)
			this.w = w;

		var sOpen = "<table id = 'w_dd" + this.index + "' width = '" + this.w + "' cellpadding = '0' cellspacing = '0' border = '0'";
		if (features == 1)
			sOpen += " style = 'width:" + this.w + ";'";
		sOpen += "><tr><td valign = 'top' align = 'left'>";
		var sClose = "</td></tr></table>";
		if (features == 1)
		{ // skin the object, and embed the caption and content
			this.ddflt.innerHTML = sOpen + dd_skin.sHeaderT[this.skin] + this.caption + dd_skin.sHeaderB[this.skin] + "<div id = 'content_dd" + this.index + "'>" + this.content + "</div>" + dd_skin.sFooter[this.skin] + sClose;
			this.ddw = document.getElementById ("w_dd" + this.index); // obtain the table ID only after the table has been written/created dynamically
			if (this.ctrl && this.ctrl_content == "")
			{ // skin-specific control panel
				this.ddc.innerHTML = "<a href = '#' onclick = 'javascript: dd_obj[" + this.index + "].noreset = 0; dd_obj[" + this.index + "].hide (); return false;'><img src = '" + (dd_skin.sClose[this.skin] ? dd_skin.sClose[this.skin] : dd_path + "close.gif") + "' galleryimg = 'no' title = '' border = '0'></a>";
				this.ctrlw = dd_skin.ctrlw[this.skin];
				this.ctrlh = dd_skin.ctrlh[this.skin];
				this.ddc.style.width = this.ctrlw + "px";
				this.ddc.style.height = this.ctrlh + "px";
			}
			else
			{ // object-specific control panel replaces skin-specific control panel
				this.ddc.innerHTML = this.ctrl_content;
				this.ddc.style.width = this.ctrlw + "px";
				this.ddc.style.height = this.ctrlh + "px";
			}
		}
		else if (features == 2) // visible, initializing the drag-drop layer
		{ // skin the object, and embed the caption and content
			this.ddflt.document.open ();
			this.ddflt.document.write (sOpen + dd_skin.sHeaderT[this.skin] + this.caption + dd_skin.sHeaderB[this.skin] + this.content + dd_skin.sFooter[this.skin] + sClose);
			this.ddflt.document.close ();

			// skin-specific control panel replaces default
			this.ddc.document.open ();
			this.ddc.document.write ("<a href = '#' onclick = 'javascript: dd_obj[" + this.index + "].noreset = 0; dd_obj[" + this.index + "].hide (); return false;'><img src = '" + (dd_skin.sClose[this.skin] ? dd_skin.sClose[this.skin] : dd_path + "close.gif") + "' alt = '' border = '0'></a>");
			this.ddc.document.close ();
		}

		// acquire actual content width occupancy for object width auto-correction
		if (features == 2) // legacy browser - NS
			this.ddw_w = this.ddflt.clip.right;
		else // contemporary browsers
			this.ddw_w = this.ddw.offsetWidth;
		if (this.ddw_w > this.w) // auto-correct the width of the drag and drop object based on the content width occupancy 
		{ // overflow -- content takes up more width than specified directly
			this.w = this.ddw_w;
			// output of HTML template layout and embedded caption, content (again)
			this.output (sCaption ? sCaption : null, sContent ? sContent : null, this.w);
			return true; // avoid duplicated execution below
		}

		this.update (1); // update object layer dimensions, etc.
		this.written = 1; // flag written output
		return true;
	}

	function effect (amt)
	{
		if (features != 1)
			return false;
		if (is_ie)
		{
			this.ddflt.style.filter = "alpha(opacity:" + amt + ")";
			this.ddobj.style.filter = "alpha(opacity:" + amt + ")";
			this.ddc.style.filter = "alpha(opacity:" + amt + ")";
			this.ddcover.style.filter = "alpha(opacity:" + 10 + ")";
		}
		else if (is_opera && this.flashobj)
			return true;
		else if (is_ns || is_opera)
		{
			if (is_ns && amt == 100)
				amt = 0.9999; // ns flickers when rendering object with 100% opacity
			else
				amt /= 100;
			this.ddflt.style.opacity = amt;
			this.ddobj.style.opacity = amt;
			this.ddc.style.opacity = amt;
		}
		return true;
	}

	function order ()
	{
		if (features == 1)
		{
			if (!dd_pkg.locked)
			{ // bring the selected layer to the front
				this.opacitydir = 1;
				this.zIndex = dd_order;
				this.ddflt.style.zIndex = dd_order;
				this.ddobj.style.zIndex = dd_order + 1;
				this.ddc.style.zIndex = dd_order + 1;
				dd_order += 2;
				for (var i = 0; i < dd_count; i++)
				{ // unfocused object effect
					if (i == this.index || !dd_obj[i].fadereset)
						continue;
					dd_obj[i].opacitydir = -1;
				}
			}
		}
		else if (features == 2)
		{
			if (!dd_pkg.locked) // bring the selected layer to the front
			{
				this.ddflt.zIndex = dd_order;
				this.ddobj.zIndex = dd_order + 1;
				this.ddc.zIndex = dd_order + 1;
				dd_order += 2;
			}
		}
	}

	function show (skin, sCaption, sContent, w)
	{
		if (!dd_pkg.ready) // not yet initialized
			return false;
		if (dd_pkg.locked) // object already in control, avoid interruptions unless object hide is forced
			return true;

		if (this.ignore_showhide)
		{ // ignore this function call if flag was set prior to its calling (avoids an event call to this function)
			this.ignore_showhide = 0;
			return false;
		}

		if (this.noreset)
		{
			if (this.getVis () == set_hide) // no show reset cannot be true if object is hidden
				this.noreset = 0; // force show reset on hidden object
			else
			{ // no show reset is valid, since the object is already visible
				this.hideticks = -1; // disable auto-delay hide while object is showing (-1 indicates no timer)
				return false; // reset object trigger is disabled, do not reset object position, etc.
			}
		}

		if (skin != null)
			this.skin = skin; // set object skin
		if (this.skin >= dd_skin.skins)
			this.skin = 0;

		this.opacity = this.opacityin; // reset initial opacity
		this.opacitydir = 1; // upward object fade in
		this.effect (this.opacity); // set actual object opacity

		// hide object before making it visible again (avoid glitch appearance when reused object is redrawn during transitional change)
		this.vis (set_hide);

		this.forced = 0; // reset forced coordinate flag

		// output of HTML template layout and embedded caption, content
		this.output (sCaption ? sCaption : null, sContent ? sContent : null, w);

		// disable auto-delay hide while object is showing (-1 indicates no timer)
		this.hideticks = -1;

		this.lock = 1; // lock object for motion

		if (this.ploc && this.parent >= 0)
		{ // snap this object to its offset (if specified) from the parent node location
			this.x = dd_obj[this.parent].getX () - this.offx + (this.pw ? dd_obj[this.parent].getW () : 0);
			this.y = dd_obj[this.parent].getY () - this.offy + (this.ph ? dd_obj[this.parent].getH () : 0);
		}
		else if (this.anchor)
		{ // snap to anchor object offset relative to document (0,0) and optionally offset width and/or height
			this.x = dd_getAbsLeft (this.anchor_el) - this.offx;
			this.y = dd_getAbsTop (this.anchor_el) - this.offy;
			if (this.anchor_w)
				this.x += this.anchor_el.offsetWidth;
			if (this.anchor_h)
				this.y += this.anchor_el.offsetHeight;
		}

		// force initial move
		this.forced = 1;
		dd_pkg.move (0, this); // (update current location before making visible to avoid glitch)
		this.update (1); // update object layer dimensions, etc.

		this.vis (set_show, 1);

		return true;
	}

	function hide (force)
	{ // x and y parameters are optional, and indicate the initial window opening location

		if (!dd_pkg.ready) // not yet initialized
			return false;
		if (dd_pkg.locked && !force) // object already in control, avoid interruptions unless object hide is forced
			return true;

		if (this.ignore_showhide)
		{ // ignore this function call if flag was set prior to its calling (avoids an event call to this function)
			this.ignore_showhide = 0;
			return false;
		}

		if (!this.cbhide ()) // prototype callback for object hide
			return false;

		if (this.vis (set_hide, force))
			this.noreset = 0;
		this.release ();
		this.child.splice (0, this.child.length);
		if (this.parent >= 0) // hide child object at a different rate from normal off-focus rate (if this is a parent)
			if (dd_obj[this.parent].hideticks >= 0)
				dd_obj[this.parent].hideticks = dd_obj[this.parent].childticks;
		this.parent = -1;
		return true;
	}

	function vis (sVis, force)
	{
		if (dd_pkg.locked && !force) // an object is locked (being dragged), do not enable change of other object visibilities
			return false; // unless third parameter is set to override this restriction
	
		if (sVis == set_hide && this.noreset && !force)
			return false;
	
		// toggle visibility of all components belonging to a single object by index
		if (features == 1)
		{
			if (this.ddobj.style.visibility == sVis)
				return false;
			this.ddobj.style.visibility = sVis;
			this.ddflt.style.visibility = sVis;
			if (!this.drag) // non-drag object drag region should remain hidden
				this.ddimg.style.visibility = set_hide;
			else
				this.ddimg.style.visibility = sVis;
			if (this.ctrl)
				this.ddc.style.visibility = sVis;
			else
				this.ddc.style.visibility = set_hide;
			if (is_ie)
			{
				if (dd_skin.hidecvr[this.skin]) // force underside cover frame hiding if set
					this.ddcover.style.visibility = set_hide;
				else
					this.ddcover.style.visibility = sVis;
			}
		}
		else if (features == 2)
		{
			if (this.ddflt.visibility == sVis)
				return false;
			if (!this.drag) // non-drag object drag region should remain hidden
				this.ddobj.visibility = set_hide;
			else
				this.ddobj.visibility = sVis;
			this.ddflt.visibility = sVis;
			if (this.ctrl)
				this.ddc.visibility = sVis;
			else
				this.ddc.visibility = set_hide;
		}

		this.sVis = sVis; // set object's visibility flag

		if (sVis == set_hide)
		{
			var zMax = 0;
			var iMax = 0;
			for (var i = 0; i < dd_count; i++)
				if (dd_obj[i].sVis != set_hide && dd_obj[i].zIndex >= zMax)
				{ // off-focus hidden object should bring next top stack object into focus
					zMax = dd_obj[i].zIndex;
					iMax = i;
				}
			dd_obj[iMax].opacitydir = 1;
		}

		return true;
	}

	function setControls (sCtrl, w, h)
	{
		if (features == 2)
			return false;
		if (!dd_pkg.ready) // not yet initialized
			return false;
		if (dd_pkg.locked) // object already in control, avoid interruptions
			return true;

		this.ctrl_content = sCtrl;
		this.ctrlw = w;
		this.ctrlh = h;
	}


} // end of ddobj class



// ****************** drag and drop objects package class

function ddpkg ()
{
	this.locked = 0; // toggle the drag-and-drop operation of an object so that obscure interruptions amongst various objects are avoided
	this.ready = 0; // this script has not yet been initialized by a call to init ()
	this.moveticks = -1; // onmousemove event timer to set objects in motion after a period of time (regulates main thread resource usage)
	this.delay_move = 1; // hundredths of a second delaying the move ticker
	this.cx = this.cy = 0; // top/left corner of the page

	// timer instances
	this.timer = null; // drag and drop timer

	// timer delays (constants)
	this.delay_hide = 200; // hundredths of a second delaying the hide ticker

	// object instance function assignment
	this.init = init;
	this.params = params;
	this.initTimer = initTimer;
	this.ok = ok;
	this.move = move;
	this.up = up;
	this.down = down;
	this.ajaxUpdate = ajaxUpdate;



	function params (arr_params)
	{
		if (this.ready) // ddobj package already initialized, cannot modify parameters after initialization
			return false; // a call to method params() must be made before a call to method init()

		for (var key in arr_params)
		{
			switch (key)
			{
				case "DELAY_HIDE":
					this.delay_hide = arr_params[key];
					if (this.delay_hide < 0) // must be absolute value
						this.delay_hide = -this.delay_hide;
					break;
				case "SQRSKIN":
					dd_skin.sqrskin = arr_params[key]; // use square skin with no transparency for corners 
					break; // (uses alternative images for skins that apply -- i.e. completely opaque images)
				case "HIDECVR":
					dd_skin.bhidecvr = arr_params[key]; // hide skin cover (Internet Explorer hack disabled when true)
					break; // uses a frame cover to overlap select drop down boxes on forms for IE browsers v6.0 or lower when enabled
				case "CCLOSE":
					dd_skin.cclose = arr_params[key]; // custom close button image path for custom skin (8)
					break; // overrides default custom skin close button image
			}
		}
		return true;
	}

	function init ()
	{
		var args = init.arguments;

		dd_skin.skin_selector (args, dd_path);

		for (var dd_i = 0; dd_i < dd_count; dd_i++)
			dd_obj[dd_i].init (dd_i); // initialize object(s)

		this.timer = setInterval ("dd_pkg.initTimer ()", 10); // timer frequency: 10 = hundredth of a second or 100 cycles per second

		if (features == 1)
		{
			document.onmouseup = this.up;
			document.onmousemove = this.move;
			document.onmousedown = this.down;
		}
		else if (features == 2)
		{
			window.captureEvents (Event.MOUSEUP | Event.MOUSEMOVE);
			window.onmouseup = this.up;
			window.onmousemove = this.move;
		}

		this.ready = 1; // ok to begin tracking the objects -- avoid premature interruption of initialization
	}

	function ok ()
	{
		if (!this.ready || this.locked) // not yet initialized or object is in motion
			return false; // use should be prohibited
		return true; // ready for use

	}

	function down (e)
	{
		if (is_opera && dd_pkg.locked)
			return false;
	}

	// called continuously for the duration of the object mouse move event
	function move (e, obj) // MSIE does not receive an event object parameter (only Mozilla browsers -- NN, Firefox, etc.)
	{
		if (is_ns) // obtain cursor location
		{
			if (e)
			{
				dd_pkg.cx = e.pageX;
				dd_pkg.cy = e.pageY;
			}
		}
		else if (e != 0)
		{
			dd_pkg.cx = dd_getClientX () + window.event.clientX;
			dd_pkg.cy = dd_getClientY () + window.event.clientY;
		}

		if (is_opera && dd_pkg.locked && window.getSelection)
		{ // clear the window selection before dragging an object (removes locked highlight in opera)
			var sel = window.getSelection();
			if (sel && sel.removeAllRanges)
				sel.removeAllRanges ();
		}

		if (obj)
		{ // initial object is passed for initial setting and positioning
			if (obj.forced)
			{ // set offset from cursor position (relative offset)
				obj.rx = obj.offx;
				obj.ry = obj.offy;
			}
			if (features == 1) // initial offset location is set
			{
				if (is_ie)
				{ // iframe hack for IE
					// ensure cover (iframe) height is synchronized with table
					if (obj.ddcover.style.height != obj.ddw.offsetHeight)
						obj.ddcover.style.height = obj.ddw.offsetHeight;
				}
			}
			obj.order (); // bring the selected layer to the front, send others behind
			obj.setOffset ((obj.x >= 0 ? obj.x : dd_pkg.cx - obj.rx), (obj.y >= 0 ? obj.y : dd_pkg.cy - obj.ry)); // move action associated with object tracking cursor -- set offset from cursor position (cx/cy already assigned by move or down event handlers)
		}

		if (features == 2)
			return true;
		else if (!dd_pkg.locked) // no object is locked, enable browser's default move handler
			return true;
		return false;
	}

	function up ()
	{
		for (var i = 0; i < dd_count; i++)
		{
			if (dd_pkg.cbup && dd_obj[i].lock)
				dd_pkg.cbup (i); // *** prototype callback for pkg button up
			dd_obj[i].lock = 0;
		}
		dd_pkg.locked = 0;
		return true;
	}

	function ajaxUpdate (i)
	{
		dd_obj[i].update (1);
		return true;
	}

	function initTimer ()
	{
		var obj = null;

		for (var i = 0; i < dd_count; i++)
		{
			obj = dd_obj[i]; // object alias

			if (!this.moveticks)
			{ // delay indicates this cycle is ready for an onmousemove event update of object motions, raise the commotion!
				if (obj.lock)
				{
					obj.setOffset (this.cx - obj.rx, this.cy - obj.ry);
					if (this.cbmove)
						this.cbmove (i); // *** prototype callback for pkg mouse move
				}
			}
			else // update ticks
				this.moveticks++;
			if (this.moveticks > 0) // obtain remaining ticks from current tick to total delay ticks
				this.moveticks %= this.delay_move;

			if (obj.hideticks > 0)
			{
				obj.hideticks++;
				obj.hideticks %= this.delay_hide;
			}
			if (!obj.hideticks)
			{
				for (var ch = 0; ch < obj.child.length; ch++)
				{
					var node = obj.child[ch];
					if (dd_obj[node].hideticks == -1)
						obj.child.splice (ch, 1);
				}
				if (!obj.child.length)
				{
					obj.hideticks = -1;
					obj.noreset = 0; // force trigger reset
					obj.hide (1); // force object hide regardless of an object lock (drag motion)
				}
			}

			// fade object gradually
			if (obj.opacitydir > 0 && obj.opacity < obj.opacityon)
			{ // fade into the on-focus opacity level upwards
				obj.opacity += obj.opacitystep;
				if (obj.opacity >= obj.opacityon)
				{
					obj.opacity = obj.opacityon;
					obj.opacitydir = 0;
				}
				obj.effect (obj.opacity);
			}
			else if (obj.opacitydir < 0 && obj.opacity != obj.opacityoff)
			{ // fade out
				if (obj.opacity < obj.opacityoff)
				{ // fade into the off-focus opacity level upwards
					obj.opacity += obj.opacitystep;
					if (obj.opacity >= obj.opacityoff)
					{
						obj.opacity = obj.opacityoff;
						obj.opacitydir = 0;
					}
				}
				else if (obj.opacity > obj.opacityoff)
				{ // fade into the off-focus opacity level downwards
					obj.opacity -= obj.opacitystep;
					if (obj.opacity <= obj.opacityoff)
					{
						obj.opacity = obj.opacityoff;
						obj.opacitydir = 0;
					}
				}
				obj.effect (obj.opacity);
			}
		}
	}

} // end of ddpkg class



// ****************** drag and drop object skins class

function ddskin ()
{
	this.path = ""; // relative image path
	this.sqrskin = 0; // use square skin with no transparency for corners (uses alternative images for skins that apply)
	this.cclose = ""; // custom close button image path for custom skin (8) -- no specification uses default image
	this.bhidecvr = true; 	// (set for transparent components of skin, but will enable select list bug for IE 6 or lower in this case)
	this.css_appendage_l = " style = 'float: left;'"; // CSS left-align style for compatible documents (Web page doctype declaration dependent)
	this.css_appendage_r = " style = 'float: right;'"; // CSS right-align style for compatible documents (Web page doctype declaration dependent)

	this.skins = 0; // skin count
	this.dragy = new Array (); // skin array: offset pixels of vertical space will activate the drag-drop operation if dragall is not set (0)
	this.ctrlx = new Array (); // skin array: offset control panel # pixels left from top-right corner of drag-drop layer
	this.ctrly = new Array (); // skin array: offset control panel # pixels down from top-right corner of drag-drop layer
	this.ctrlw = new Array (); // skin array: width in pixels of control panel
	this.ctrlh = new Array (); // skin array: height in pixels of control panel
	this.hidecvr = new Array (); // skin array: hide browser iframe underneath object

	// SKIN TEMPLATE -- CAPTION & CONTENT IS ENCOMPASSED BY THE HEADER AND FOOTER
	this.sHeaderT = new Array (); // skin array: top header HTML
	this.sHeaderB = new Array (); // skin array: bottom header HTML
	this.sFooter = new Array (); // skin array: footer HTML
	this.sClose = new Array (); // skin close array: substitute skin-specific close icon image file

	// add your own skin entry here ... define a function based on an existing one first, 
	// then modify this vector (index->function pointers)
	this.s = {0 : "skin_tab", 1 : "skin_con", 2 : "skin_cap", 3 : "skin_slv", 4 : "skin_cap1", 
				5 : "skin_default", 6 : "skin_media", 7 : "skin_metal", 8 : "skin_plain", 
				9 : "skin_tab1", 10 : "skin_cap2"};

	// ------------------------------------- SKIN SELECTOR FUNCTIONS (DEFINE YOUR OWN SKINS HERE)
	// Note: image heights must be specified for skins using images so that browsers such as IE accurately size ddobj components

	this.skin_selector = function (arr, spath)
	{
		var i = 0; // skin index incrementer
		var si = 0; // actual selected skin index
		this.path = spath; // assign the relative image path

		// remove CSS style for incompatible documents (Web page doctype declaration dependent)
		if (!is_css1_compatible) this.css_appendage_l = this.css_appendage_r = "";

		dd_img_preload (0, this.path, 'preloader.gif', 'close.gif');
		if (!arr.length)
		{ // enable all skins if no skins were specified through init(...) params.
			arr = new Array ();
			for (var key in this.s)
				arr[i++] = key;
		}

		for (i = 0; i < arr.length; i++)
		{ // initialize skins: call custom skin functions
			si = arr[i];
			if (this.s[si])
				eval ("this." + this.s[si] + "();");
		}
		if (this.sHeaderT.length <= 0) // ensure that at least the default skin is allowable if none else
			this.skin_default ();
		this.skins = this.sHeaderT.length; // skin count
	};


	this.skin_tab = function ()
	{
		var i = this.sHeaderT.length;
	
		dd_img_preload (i + 1, this.path + "skins/tab/", 'tab-l1.gif', 'tab-c1.gif', 'tab-r10.gif', 'tab-r10bg.jpg', 'tab-r11.gif', 'tab-l2.jpg', 
			'tab-bg.jpg', 'tab-r20_bg.jpg', 'tab-r20_bg1.jpg', 'tab-r20bg.jpg', 'tab-r21_bg.jpg', 'tab-l3.gif', 'tab-c3.jpg', 'tab-r30bg.jpg',
			'tab-r30.jpg', 'tab-r30bg.jpg', 'tab-r31.jpg', 'tab-l4.jpg', 'tab-r4.jpg', 'tab-l5.gif', 'tab-c5.jpg', 'tab-r5.gif');

		this.sHeaderT[i] = "" +
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '10'><img src = '" + this.path + "skins/tab/tab-l1.gif' height = '10'" + this.css_appendage_l + "></td>" +
		"  <td width = '175' background = '" + this.path + "skins/tab/tab-c1.jpg' valign = 'top'><img src = '" + this.path + "skins/tab/tab-c1.jpg' height = '10'" + this.css_appendage_l + "></td>" +
		"  <td width = '20' align = 'left' background = '" + this.path + "skins/tab/tab-r10bg.jpg'><img src = '" + this.path + "skins/tab/tab-r10.gif' height = '10'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/tab/tab-r10bg.jpg' align = 'left'><img src = '" + this.path + "skins/tab/tab-r10bg.jpg' height = '10'" + this.css_appendage_l + "></td>" +
		"  <td width = '8'><img src = '" + this.path + "skins/tab/tab-r11.gif' height = '10'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '10' background = '" + this.path + "skins/tab/tab-l2.jpg' valign = 'top'><img src = '" + this.path + "skins/tab/tab-l2.jpg' height = '11'" + this.css_appendage_l + "></td>" +
		"  <td width = '175' background = '" + this.path + "skins/tab/tab-bg.jpg'>";
	
		// header text parameter would appear here
	
		this.sHeaderB[i] = "" + 
		"  </td>" +
		"  <td width = '20' background = '" + this.path + "skins/tab/tab-r20_bg.jpg' align = 'left' valign = 'top'><img src = '" + this.path + "skins/tab/tab-r20.jpg' height = '11'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/tab/tab-r20_bg1.jpg' align = 'left' valign = 'top'><img src = '" + this.path + "skins/tab/tab-r20bg.jpg' height = '11'" + this.css_appendage_l + "></td>" +
		"  <td width = '8' background = '" + this.path + "skins/tab/tab-r21_bg.jpg' valign = 'top'><img src = '" + this.path + "skins/tab/tab-r21.jpg' height = '11'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '10'><img src = '" + this.path + "skins/tab/tab-l3.gif' height = '6'" + this.css_appendage_l + "></td>" +
		"  <td width = '175' background = '" + this.path + "skins/tab/tab-c3.jpg'><img src = '" + this.path + "skins/tab/tab-c3.jpg' height = '6'" + this.css_appendage_l + "></td>" +
		"  <td width = '20' align = 'left' background = '" + this.path + "skins/tab/tab-r30bg.jpg'><img src = '" + this.path + "skins/tab/tab-r30.jpg' height = '6'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/tab/tab-r30bg.jpg' align = 'left' valign = 'top'><img src = '" + this.path + "skins/tab/tab-r30bg.jpg' height = '6'" + this.css_appendage_l + "></td>" +
		"  <td width = '8'><img src = '" + this.path + "skins/tab/tab-r31.jpg' height = '6'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>" + 
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '10' background = '" + this.path + "skins/tab/tab-l4.jpg'><img src = '" + this.path + "skins/tab/tab-l4.jpg' height = '6'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' valign = 'top' background = '" + this.path + "skins/tab/tab-bg.jpg'>";
	
		// main window text parameter would appear here
	
		this.sFooter[i] = (dd_copyright ? "<p class = 'dd_footer' align = 'right'>ddobj - dynamicreport.com</p>" : "") +
		"  </td>" +
		"  <td width = '8' background = '" + this.path + "skins/tab/tab-r4.jpg'><img src = '" + this.path + "skins/tab/tab-r4.jpg' height = '6'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '10'><img src = '" + this.path + "skins/tab/tab-l5.gif' height = '11'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/tab/tab-c5.jpg'><img src = '" + this.path + "skins/tab/tab-c5.jpg' height = '11'" + this.css_appendage_l + "></td>" +
		"  <td width = '8'><img src = '" + this.path + "skins/tab/tab-r5.gif' height = '11'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>";

		this.dragy[i] = 35;
		this.ctrlx[i] = -5;
		this.ctrly[i] = 5;
		this.ctrlw[i] = 20;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = 0; // always show cover regardless of bhidecvr parameter, since this skin is opaque only (no transparency)
	};


	this.skin_con = function ()
	{
		var i = this.sHeaderT.length;

		dd_img_preload (i + 1, this.path + "skins/console/", 'con-l1.jpg', 'con-c1bg.jpg', 'con-c1.jpg', 'con-r1.jpg', 'con-l2bg.jpg',
			'con-l2.jpg', 'con-bg.jpg', 'con-r2bg.jpg', 'con-r2.jpg', 'con-l3.jpg', 'con-c3bg.jpg', 'con-c3.jpg', 'con-r3.jpg');
	
		this.sHeaderT[i] = "" +
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '19' background = '" + this.path + "skins/console/con-l1.jpg'><img src = '" + this.path + "skins/console/con-l1.jpg' height = '27'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/console/con-c1bg.jpg' align = 'right'><img src = '" + this.path + "skins/console/con-c1.jpg' height = '27'" + this.css_appendage_r + "></td>" +
		"  <td width = '26'><img src = '" + this.path + "skins/console/con-r1.jpg' height = '27'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '19' background = '" + this.path + "skins/console/con-l2bg.jpg' valign = 'top'><img src = '" + this.path + "skins/console/con-l2.jpg' height = '79'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/console/con-bg.jpg'>";
	
		// header text parameter would appear here
	
		this.sHeaderB[i] = "";
	
		// main window text parameter would appear here
	
		this.sFooter[i] = (dd_copyright ? "<p class = 'dd_footer' align = 'right'>ddobj - dynamicreport.com</p>" : "") +
		"  </td>" +
		"  <td width = '26' background = '" + this.path + "skins/console/con-r2bg.jpg' valign = 'bottom'><img src = '" + this.path + "skins/console/con-r2.jpg' height = '79'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '19' background = '" + this.path + "skins/console/con-l3.jpg'><img src = '" + this.path + "skins/console/con-l3.jpg' height = '29'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/console/con-c3bg.jpg'><img src = '" + this.path + "skins/console/con-c3.jpg' height = '29'" + this.css_appendage_l + "></td>" +
		"  <td width = '26'><img src = '" + this.path + "skins/console/con-r3.jpg' height = '29'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>";
	
		this.dragy[i] = 30;
		this.ctrlx[i] = -1;
		this.ctrly[i] = 4;
		this.ctrlw[i] = 20;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = 0; // always show cover regardless of bhidecvr parameter, since this skin is opaque only (no transparency)
	};


	this.skin_cap = function ()
	{
		var i = this.sHeaderT.length;

		dd_img_preload (i + 1, this.path + "skins/caption/", 'cap-l1.gif', 'cap-c1.jpg', 'cap-r1.gif', 'cap-l2.gif', 'cap-l2bg.jpg', 
			'cap-c2.jpg', 'cap-r2.gif', 'cap-r2bg.jpg', 'cap-l3.gif', 'cap-c3.jpg', 'cap-r3.gif', 'cap-l4bg.jpg', 'cap-c4.jpg',
			'cap-r4bg.jpg', 'cap-l5.gif', 'cap-c5.jpg', 'cap-r5.gif', 'cap-l1s.gif', 'cap-r1s.gif', 'cap-l5s.gif', 'cap-r5s.gif');
	
		this.sHeaderT[i] = "" +
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '9'><img src = '" + this.path + "skins/caption/cap-l1" + (this.sqrskin ? "s" : "") + ".gif' height = '9'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/caption/cap-c1.jpg' align = 'right'><img src = '" + this.path + "skins/caption/cap-c1.jpg' height = '9'" + this.css_appendage_l + "></td>" +
		"  <td width = '9'><img src = '" + this.path + "skins/caption/cap-r1" + (this.sqrskin ? "s" : "") + ".gif' height = '9'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '9' background = '" + this.path + "skins/caption/cap-l2bg.jpg' valign = 'top'><img src = '" + this.path + "skins/caption/cap-l2.gif' height = '19'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/caption/cap-c2.jpg'>";
	
		// header text parameter would appear here
	
		this.sHeaderB[i] = "" +
		"  </td>" +
		"  <td width = '9' background = '" + this.path + "skins/caption/cap-r2bg.jpg' valign = 'top'><img src = '" + this.path + "skins/caption/cap-r2.gif' height = '19'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '9'><img src = '" + this.path + "skins/caption/cap-l3.gif' height = '2'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/caption/cap-c3.jpg'><img src = '" + this.path + "skins/caption/cap-c3.jpg' height = '2'" + this.css_appendage_l + "></td>" +
		"  <td width = '9' align = 'right'><img src = '" + this.path + "skins/caption/cap-r3.gif' height = '2'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '9' background = '" + this.path + "skins/caption/cap-l4bg.jpg' valign = 'top'><img src = '" + this.path + "trans.gif' width = '9' height = '1'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/caption/cap-c4.jpg'>";

		// main window text parameter would appear here

		this.sFooter[i] = (dd_copyright ? "<p class = 'dd_footer_lg' align = 'right'>ddobj - dynamicreport.com</p>" : "") + 
		"  </td>" +
		"  <td width = '9' background = '" + this.path + "skins/caption/cap-r4bg.jpg' valign = 'top'><img src = '" + this.path + "trans.gif' width = '9' height = '1'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '9'><img src = '" + this.path + "skins/caption/cap-l5" + (this.sqrskin ? "s" : "") + ".gif' height = '15'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/caption/cap-c5.jpg'><img src = '" + this.path + "skins/caption/cap-c5.jpg' height = '15'" + this.css_appendage_l + "></td>" +
		"  <td width = '9' align = 'right'><img src = '" + this.path + "skins/caption/cap-r5" + (this.sqrskin ? "s" : "") + ".gif' height = '15'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>";
	
		this.dragy[i] = 30;
		this.ctrlx[i] = -10;
		this.ctrly[i] = 5;
		this.ctrlw[i] = 20;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = this.bhidecvr; // set to bhidecvr, since this skin can use opaque or transparency option (determined by sqrskin flag)
	};


	this.skin_cap1 = function ()
	{
		var i = this.sHeaderT.length;
	
		dd_img_preload (i + 1, this.path + "skins/caption1/", 'cap1-l1.jpg', 'cap1-c1.jpg', 'cap1-r1.jpg', 'cap1-l2.jpg', 'cap1-bg.jpg',
			'cap1-r2.jpg', 'cap1-l3.jpg', 'cap1-c3.jpg', 'cap1-r3.jpg');
	
		this.sHeaderT[i] = "" +
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '7' background = '" + this.path + "skins/caption1/cap1-l1.jpg'><img src = '" + this.path + "skins/caption1/cap1-l1.jpg' height = '34'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/caption1/cap1-c1.jpg' align = 'right'><img src = '" + this.path + "skins/caption1/cap1-c1.jpg' height = '34'" + this.css_appendage_l + "></td>" +
		"  <td width = '7'><img src = '" + this.path + "skins/caption1/cap1-r1.jpg' height = '34'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '7' background = '" + this.path + "skins/caption1/cap1-l2.jpg' valign = 'top'><img src = '" + this.path + "skins/caption1/cap1-l2.jpg' height = '1'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/caption1/cap1-bg.jpg'>";
	
		// header text parameter would appear here
	
		this.sHeaderB[i] = "";
	
		// main window text parameter would appear here
	
		this.sFooter[i] = (dd_copyright ? "<p class = 'dd_footer' align = 'right'>ddobj - dynamicreport.com</p>" : "") +
		"  </td>" +
		"  <td width = '7' background = '" + this.path + "skins/caption1/cap1-r2.jpg' valign = 'bottom'><img src = '" + this.path + "skins/caption1/cap1-r2.jpg' height = '1'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '7' background = '" + this.path + "skins/caption1/cap1-l3.jpg'><img src = '" + this.path + "skins/caption1/cap1-l3.jpg' height = '8'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/caption1/cap1-c3.jpg'><img src = '" + this.path + "skins/caption1/cap1-c3.jpg' height = '8'" + this.css_appendage_l + "></td>" +
		"  <td width = '7'><img src = '" + this.path + "skins/caption1/cap1-r3.jpg' height = '8'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>";
	
		this.dragy[i] = 35;
		this.ctrlx[i] = -1;
		this.ctrly[i] = 6;
		this.ctrlw[i] = 20;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = 0; // always show cover regardless of bhidecvr parameter, since this skin is opaque only (no transparency)
	};


	this.skin_slv = function ()
	{
		var i = this.sHeaderT.length;
	
		dd_img_preload (i + 1, this.path + "skins/silver/", 'slv-l1.gif', 'slv-c1.jpg', 'slv-r1.gif', 'slv-l2.jpg', 'slv-bg.jpg',
			'slv-r2.jpg', 'slv-l3.gif', 'slv-c3.jpg', 'slv-r3.gif', 'slv-l1s.gif', 'slv-r1s.gif');
	
		this.sHeaderT[i] = "" +
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '14' align = 'left'><img src = '" + this.path + "skins/silver/slv-l1" + (this.sqrskin ? "s" : "") + ".gif' width = '14' height = '29'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/silver/slv-c1.jpg' align = 'right'><img src = '" + this.path + "skins/silver/slv-c1.jpg' height = '29'" + this.css_appendage_l + "></td>" +
		"  <td width = '14' align = 'left'><img src = '" + this.path + "skins/silver/slv-r1" + (this.sqrskin ? "s" : "") + ".gif' width = '14' height = '29'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '14' background = '" + this.path + "skins/silver/slv-l2.jpg' valign = 'top'><img src = '" + this.path + "skins/silver/slv-l2.jpg' height = '1'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/silver/slv-bg.jpg'>";
	
		// header text parameter would appear here
	
		this.sHeaderB[i] = "";
	
		// main window text parameter would appear here
	
		this.sFooter[i] = (dd_copyright ? "<p class = 'dd_footer' align = 'right'>ddobj - dynamicreport.com</p>" : "") +
		"  </td>" +
		"  <td width = '14' background = '" + this.path + "skins/silver/slv-r2.jpg' valign = 'bottom'><img src = '" + this.path + "skins/silver/slv-r2.jpg' height = '1'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '14'><img src = '" + this.path + "skins/silver/slv-l3.gif' height = '25'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/silver/slv-c3.jpg'><img src = '" + this.path + "skins/silver/slv-c3.jpg' height = '25'" + this.css_appendage_l + "></td>" +
		"  <td width = '14'><img src = '" + this.path + "skins/silver/slv-r3.gif' height = '25'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>";
	
		this.dragy[i] = 35;
		this.ctrlx[i] = -8;
		this.ctrly[i] = 2;
		this.ctrlw[i] = 20;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = this.bhidecvr; // set to bhidecvr, since this skin can use opaque or transparency option (determined by sqrskin flag)
	};


	this.skin_media = function ()
	{
		var i = this.sHeaderT.length;
	
		dd_img_preload (i + 1, this.path + "skins/media/", 'media-l1.gif', 'media-c1l.jpg', 'media-c1bg.jpg', 'media-c1r.jpg', 'media-r1.gif',
			'media-l2.jpg', 'media-bg.jpg', 'media-r2.jpg', 'media-l3.gif', 'media-c3bg.jpg', 'media-r3.gif', 
			'media-l1s.gif', 'media-r1s.gif', 'media-l3s.gif', 'media-r3s.gif', 'media-close.gif');
	
		this.sHeaderT[i] = "" +
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '17'><img src = '" + this.path + "skins/media/media-l1" + (this.sqrskin ? "s" : "") + ".gif' width = '17' height = '39'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/media/media-c1bg.jpg'><img src = '" + this.path + "skins/media/media-c1l.jpg' height = '39' align = 'left'><img src = '" + this.path + "skins/media/media-c1r.jpg' height = '39' align = 'right'" + this.css_appendage_l + "></td>" +
		"  <td width = '17'><img src = '" + this.path + "skins/media/media-r1" + (this.sqrskin ? "s" : "") + ".gif' width = '17' height = '39'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '17' background = '" + this.path + "skins/media/media-l2.jpg' valign = 'top'><img src = '" + this.path + "skins/media/media-l2.jpg' height = '1'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/media/media-bg.jpg'>";

		// header text parameter would appear here

		this.sHeaderB[i] = "";

		// main window text parameter would appear here

		this.sFooter[i] = (dd_copyright ? "<p class = 'dd_footer' align = 'right'>ddobj - dynamicreport.com</p>" : "") +
		"  </td>" +
		"  <td width = '17' background = '" + this.path + "skins/media/media-r2.jpg' valign = 'bottom'><img src = '" + this.path + "skins/media/media-r2.jpg' height = '1'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '17'><img src = '" + this.path + "skins/media/media-l3" + (this.sqrskin ? "s" : "") + ".gif' height = '55'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/media/media-c3bg.jpg'><img src = '" + this.path + "skins/media/media-c3bg.jpg' height = '55'" + this.css_appendage_l + "></td>" +
		"  <td width = '17'><img src = '" + this.path + "skins/media/media-r3" + (this.sqrskin ? "s" : "") + ".gif' height = '55'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>";

		this.sClose[i] = this.path + "skins/media/media-close.gif";

		this.dragy[i] = 34;
		this.ctrlx[i] = -6;
		this.ctrly[i] = 4;
		this.ctrlw[i] = 20;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = this.bhidecvr; // set to bhidecvr, since this skin can use opaque or transparency option (determined by sqrskin flag)
	};


	this.skin_metal = function ()
	{
		var i = this.sHeaderT.length;

		dd_img_preload (i + 1, this.path + "skins/metal/", 'metal-l1.gif', 'metal-c1.jpg', 'metal-r1.gif', 'metal-l2.jpg', 'metal-c2.jpg',
			'metal-r2.jpg', 'metal-l3.gif', 'metal-c3.jpg', 'metal-r3.gif', 'metal-l1s.gif', 'metal-r1s.jpg', 'metal-l3s.gif', 
			'metal-r3s.gif', 'metal-close.gif');
	
		this.sHeaderT[i] = "" +
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '12' align = 'left'><img src = '" + this.path + "skins/metal/metal-l1" + (this.sqrskin ? "s" : "") + ".gif' width = '12' height = '12'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/metal/metal-c1.jpg' align = 'right'><img src = '" + this.path + "skins/metal/metal-c1.jpg' height = '12'" + this.css_appendage_l + "></td>" +
		"  <td width = '12' align = 'left'><img src = '" + this.path + "skins/metal/metal-r1" + (this.sqrskin ? "s" : "") + ".gif' width = '12' height = '12'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '12' background = '" + this.path + "skins/metal/metal-l2.jpg' valign = 'top'><img src = '" + this.path + "skins/metal/metal-l2.jpg' height = '72'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/metal/metal-c2.jpg'>";
	
		// header text parameter would appear here
	
		this.sHeaderB[i] = "";
	
		// main window text parameter would appear here
	
		this.sFooter[i] = (dd_copyright ? "<p class = 'dd_footer' align = 'right'>ddobj - dynamicreport.com</p>" : "") +
		"  </td>" +
		"  <td width = '12' background = '" + this.path + "skins/metal/metal-r2.jpg' valign = 'top'><img src = '" + this.path + "skins/metal/metal-r2.jpg' height = '72'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '12'><img src = '" + this.path + "skins/metal/metal-l3" + (this.sqrskin ? "s" : "") + ".gif' height = '12'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/metal/metal-c3.jpg'><img src = '" + this.path + "skins/metal/metal-c3.jpg' height = '12'" + this.css_appendage_l + "></td>" +
		"  <td width = '12'><img src = '" + this.path + "skins/metal/metal-r3" + (this.sqrskin ? "s" : "") + ".gif' height = '12'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>";

		this.sClose[i] = this.path + "skins/metal/metal-close.gif";

		this.dragy[i] = 35;
		this.ctrlx[i] = -6;
		this.ctrly[i] = 8;
		this.ctrlw[i] = 33;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = this.bhidecvr; // set to bhidecvr, since this skin can use opaque or transparency option (determined by sqrskin flag)
	};


	this.skin_default = function ()
	{
		var i = this.sHeaderT.length;
	
		this.sHeaderT[i] = "<table width = '100%' cellpadding = '0' cellspacing = '0' border = '1'>" +
		"<tr><td bgcolor = '#DFDFEE' height = '20' valign = 'top'>";
	
		// header text parameter would appear here
	
		this.sHeaderB[i] = "</td></tr>" +
		"<tr><td bgcolor = '#EDEDED' valign = 'top'>";
	
		// main window text parameter would appear here
		
		this.sFooter[i] = (dd_copyright ? "<p class = 'dd_footer' align = 'right'>ddobj - dynamicreport.com</p>" : "") +
		"</td></tr></table>";
	
		this.dragy[i] = 25;
		this.ctrlx[i] = -1;
		this.ctrly[i] = 1;
		this.ctrlw[i] = 20;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = 0; // always show cover regardless of bhidecvr parameter, since this skin is opaque only (no transparency)
	};


	this.skin_plain = function ()
	{
		var i = this.sHeaderT.length;
	
		this.sHeaderT[i] = "<table width = '100%' cellpadding = '0' cellspacing = '0' border = '0'>" +
		"<tr><td valign = 'top'>";
	
		// header text parameter would appear here
	
		this.sHeaderB[i] = "";
	
		// main window text parameter would appear here
		
		this.sFooter[i] = "</td></tr></table>";

		if (this.cclose) // custom close button image
			this.sClose[i] = this.path + this.cclose;

		this.dragy[i] = 25;
		this.ctrlx[i] = -1;
		this.ctrly[i] = 1;
		this.ctrlw[i] = 20;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = 0; // always show cover regardless of bhidecvr parameter, since this skin is opaque only (no transparency)
	};


	this.skin_tab1 = function ()
	{
		var i = this.sHeaderT.length;
	
		dd_img_preload (i + 1, this.path + "skins/tab1/", 'tab1-l1.gif', 'tab1-l1s.gif', 'tab1-c1.jpg', 'tab1-r10.gif', 'tab1-r10bg.jpg', 'tab1-r11.gif', 'tab1-r11s.gif', 
			'tab1-l2.jpg', 'tab1-bg.jpg', 'tab1-r20_bg.jpg', 'tab1-r20_bg1.jpg', 'tab1-r20bg.jpg', 'tab1-r21_bg.jpg', 'tab1-l3.gif', 'tab1-c3.jpg', 
			'tab1-r30bg.jpg', 'tab1-r30.jpg', 'tab1-r30bg.jpg', 'tab1-r31.jpg', 'tab1-l4.jpg', 'tab1-r4.jpg', 'tab1-l5.gif', 'tab1-l5s.gif', 'tab1-c5.jpg', 
			'tab1-r5.gif', 'tab1-r5s.gif', 'tab1-close.gif');
	
		this.sHeaderT[i] = "" +
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '6'><img src = '" + this.path + "skins/tab1/tab1-l1" + (this.sqrskin ? "s" : "") + ".gif' height = '8'" + this.css_appendage_l + "></td>" +
		"  <td width = '131' background = '" + this.path + "skins/tab1/tab1-c1.jpg' valign = 'top'><img src = '" + this.path + "skins/tab1/tab1-c1.jpg' height = '8'" + this.css_appendage_l + "></td>" +
		"  <td width = '5' align = 'left' background = '" + this.path + "skins/tab1/tab1-r10bg.jpg'><img src = '" + this.path + "skins/tab1/tab1-r10.gif' height = '8'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/tab1/tab1-r10bg.jpg' align = 'left'><img src = '" + this.path + "skins/tab1/tab1-r10bg.jpg' height = '8'" + this.css_appendage_l + "></td>" +
		"  <td width = '6'><img src = '" + this.path + "skins/tab1/tab1-r11" + (this.sqrskin ? "s" : "") + ".gif' height = '8'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '6' background = '" + this.path + "skins/tab1/tab1-l2.jpg' valign = 'top'><img src = '" + this.path + "skins/tab1/tab1-l2.jpg' height = '9'" + this.css_appendage_l + "></td>" +
		"  <td width = '131' background = '" + this.path + "skins/tab1/tab1-bg.jpg'>";
	
		// header text parameter would appear here
	
		this.sHeaderB[i] = "" + 
		"  </td>" +
		"  <td width = '5' background = '" + this.path + "skins/tab1/tab1-r20_bg.jpg' align = 'left' valign = 'top'><img src = '" + this.path + "skins/tab1/tab1-r20.jpg' height = '9'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/tab1/tab1-r20_bg1.jpg' align = 'left' valign = 'top'><img src = '" + this.path + "skins/tab1/tab1-r20bg.jpg' height = '9'" + this.css_appendage_l + "></td>" +
		"  <td width = '6' background = '" + this.path + "skins/tab1/tab1-r21_bg.jpg' valign = 'top'><img src = '" + this.path + "skins/tab1/tab1-r21.jpg' height = '9'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '6'><img src = '" + this.path + "skins/tab1/tab1-l3.gif' height = '6'" + this.css_appendage_l + "></td>" +
		"  <td width = '131' background = '" + this.path + "skins/tab1/tab1-c3.jpg'><img src = '" + this.path + "skins/tab1/tab1-c3.jpg' height = '6'" + this.css_appendage_l + "></td>" +
		"  <td width = '5' align = 'left' background = '" + this.path + "skins/tab1/tab1-r30bg.jpg'><img src = '" + this.path + "skins/tab1/tab1-r30.jpg' height = '6'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/tab1/tab1-r30bg.jpg' align = 'left' valign = 'top'><img src = '" + this.path + "skins/tab1/tab1-r30bg.jpg' height = '6'" + this.css_appendage_l + "></td>" +
		"  <td width = '6'><img src = '" + this.path + "skins/tab1/tab1-r31.jpg' height = '6'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>" +
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '6' background = '" + this.path + "skins/tab1/tab1-l4.jpg'><img src = '" + this.path + "skins/tab1/tab1-l4.jpg' width = '6' height = '6'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' valign = 'top' background = '" + this.path + "skins/tab1/tab1-bg.jpg'>";
	
		// main window text parameter would appear here
	
		this.sFooter[i] = (dd_copyright ? "<p class = 'dd_footer' align = 'right'>ddobj - dynamicreport.com</p>" : "") +
		"  </td>" +
		"  <td width = '6' background = '" + this.path + "skins/tab1/tab1-r4.jpg'><img src = '" + this.path + "skins/tab1/tab1-r4.jpg' width = '6' height = '6'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '6'><img src = '" + this.path + "skins/tab1/tab1-l5" + (this.sqrskin ? "s" : "") + ".gif' height = '8'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/tab1/tab1-c5.jpg'><img src = '" + this.path + "skins/tab1/tab1-c5.jpg' height = '8'" + this.css_appendage_l + "></td>" +
		"  <td width = '6'><img src = '" + this.path + "skins/tab1/tab1-r5" + (this.sqrskin ? "s" : "") + ".gif' height = '8'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>";

		this.sClose[i] = this.path + "skins/tab1/tab1-close.gif";

		this.dragy[i] = 35;
		this.ctrlx[i] = -5;
		this.ctrly[i] = 6;
		this.ctrlw[i] = 20;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = this.bhidecvr; // set to bhidecvr, since this skin can use opaque or transparency option (determined by sqrskin flag)
	};


	this.skin_cap2 = function ()
	{
		var i = this.sHeaderT.length;
	
		dd_img_preload (i + 1, this.path + "skins/caption2/", 'cap2-l1.gif', 'cap2-c1.jpg', 'cap2-r1.jpg', 'cap2-l2.gif', 'cap2-l2bg.jpg', 
			'cap2-c2.jpg', 'cap2-r2.gif', 'cap2-r2bg.jpg', 'cap2-l3.gif', 'cap2-c3.jpg', 'cap2-r3.gif', 'cap2-l4bg.jpg', 'cap2-c4.jpg',
			'cap2-r4bg.jpg', 'cap2-l5.gif', 'cap2-c5.jpg', 'cap2-r5.gif', 'cap2-l1s.gif', 'cap2-r1s.gif', 'cap2-l5s.gif', 'cap2-r5s.gif', 
			'cap2-close.gif');
	
		this.sHeaderT[i] = "" +
		"<table width = '100%' border = '0' cellspacing = '0' cellpadding = '0'>" +
		" <tr>" +
		"  <td width = '9'><img src = '" + this.path + "skins/caption2/cap2-l1" + (this.sqrskin ? "s" : "") + ".gif' height = '10'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/caption2/cap2-c1.jpg' align = 'right'><img src = '" + this.path + "skins/caption2/cap2-c1.jpg' height = '10'" + this.css_appendage_l + "></td>" +
		"  <td width = '9'><img src = '" + this.path + "skins/caption2/cap2-r1" + (this.sqrskin ? "s" : "") + ".gif' height = '10'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '9' background = '" + this.path + "skins/caption2/cap2-l2bg.jpg' valign = 'top'><img src = '" + this.path + "skins/caption2/cap2-l2.gif' height = '10'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/caption2/cap2-c2.jpg'>";
	
		// header text parameter would appear here
	
		this.sHeaderB[i] = "" +
		"  </td>" +
		"  <td width = '9' background = '" + this.path + "skins/caption2/cap2-r2bg.jpg' valign = 'top'><img src = '" + this.path + "skins/caption2/cap2-r2.gif' height = '10'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '9'><img src = '" + this.path + "skins/caption2/cap2-l3.gif' height = '12'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/caption2/cap2-c3.jpg'><img src = '" + this.path + "skins/caption2/cap2-c3.jpg' height = '12'" + this.css_appendage_l + "></td>" +
		"  <td width = '9' align = 'right'><img src = '" + this.path + "skins/caption2/cap2-r3.gif' height = '12'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '9' background = '" + this.path + "skins/caption2/cap2-l4bg.jpg' valign = 'top'><img src = '" + this.path + "trans.gif' width = '9' height = '1'" + this.css_appendage_l + "></td>" +
		"  <td width = '100%' background = '" + this.path + "skins/caption2/cap2-c4.jpg'>";

		// main window text parameter would appear here

		this.sFooter[i] = (dd_copyright ? "<p class = 'dd_footer' align = 'right'>ddobj - dynamicreport.com</p>" : "") +
		"  </td>" +
		"  <td width = '9' background = '" + this.path + "skins/caption2/cap2-r4bg.jpg' valign = 'top'><img src = '" + this.path + "trans.gif' width = '9' height = '1'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		" <tr>" +
		"  <td width = '9'><img src = '" + this.path + "skins/caption2/cap2-l5" + (this.sqrskin ? "s" : "") + ".gif' height = '13'" + this.css_appendage_l + "></td>" +
		"  <td width = '*' background = '" + this.path + "skins/caption2/cap2-c5.jpg'><img src = '" + this.path + "skins/caption2/cap2-c5.jpg' height = '13'" + this.css_appendage_l + "></td>" +
		"  <td width = '9' align = 'right'><img src = '" + this.path + "skins/caption2/cap2-r5" + (this.sqrskin ? "s" : "") + ".gif' height = '13'" + this.css_appendage_l + "></td>" +
		" </tr>" +
		"</table>";

		this.sClose[i] = this.path + "skins/caption2/cap2-close.gif";

		this.dragy[i] = 35;
		this.ctrlx[i] = -8;
		this.ctrly[i] = 7;
		this.ctrlw[i] = 22;
		this.ctrlh[i] = 20;
		this.hidecvr[i] = this.bhidecvr; // set to bhidecvr, since this skin can use opaque or transparency option (determined by sqrskin flag)
	};



} // end of ddskin class



// prototype function definition
ddobj.prototype.cbhide = function ()
{ // shell -- define extended custom functionality for object hide, refer to object using this.index or this.id
	return true; // default execution next, if callback returns true
};

// prototype function definition
ddobj.prototype.cbdown = function ()
{ // shell -- define extended custom functionality for object button click
	return true; // refer to object using this.index or this.id
};

// prototype function definition
ddpkg.prototype.cbup = function (i)
{ // shell -- define extended custom functionality for pkg button up
	return true; // parameter i refers to object index in object list: dd_obj[i]
};

// prototype function definition
ddpkg.prototype.cbmove = function (i)
{ // shell -- define extended custom functionality for pkg mouse move
	return true; // parameter i refers to object index in object list: dd_obj[i]
};


dd_setBrowser (); // obtain client browser information

for (var dd_i = 0; dd_i < dd_count; dd_i++)
	dd_obj[dd_i] = new ddobj (); // instantiate object(s) here before their availability
