//
// Copyright (c) Just2Easy Limited 2007,2008
//
// All rights reserved.
//
// see - www.j2e.com
//

var timer
var framesPerSecond = 40
var frameTime = 1000 / framesPerSecond
var bin
var lastLayer = 1
var links = new Array();
var nextId = 0
var selected

function getElementById(id){
	return document.getElementById(id)
}

function time(){
	var date = new Date()
	return date.getTime()
}

function setSize(id,sx,sy,sw,sh){
	var o = getElementById(id)
	o.sx = sx
	o.sy = sy
	o.sw = sw
	o.sh = sh
}

function setShadow(id,shadow){
	var o = getElementById(id)
	o.shadow = shadow
}

function flash(id,time,hidden){
	var o = getElementById(id)

	if (o.flash!=true){	// stop double event
		o.flash = true
		flash1(id,time,hidden)
	}
}

function flash1(id,time,hidden){
	var o = getElementById(id)

      if (o.flash!=false){
		hidden = !hidden

		if (hidden==true)
			hide(id)
		else
			show(id)

		var cmd = "flash1('"+id+"',"+time+","+hidden+")"
		setTimeout(cmd,time)
	}
}

function hide(id){
	var o = getElementById(id)
	o.style.visibility = "hidden"
}

function show(id){
	var o = getElementById(id)
	o.style.visibility = "visible"
}

function hideO(id){
	var o = getElementById(id)
	o.hidden = true
	setOpacity(id,0)

	if (o.shadow!=undefined)
		hideO(o.shadow)
}

function showO(id){
	var o = getElementById(id)
	o.hidden = false

	if (o.j2eOpacity!=undefined)
		setOpacity(id,o.j2eOpacity)
	else
		setOpacity(id,100)

	if (o.shadow!=undefined)
		showO(o.shadow)
}

function fade(id,time){
	var o = getElementById(id)

	if (o.fade!=true){
		o.fade = true
		o.appear = false
		fade1(id,time,100)
	}
}

function fade1(id,time,opacity){
	var o = getElementById(id)

      if (o.fade!=false){
		opacity = opacity-1;
		setOpacity(id,opacity)

		if (opacity>0){
			var cmd = "fade1('"+id+"',"+time+","+opacity+")"
			setTimeout(cmd,time)
		}
	}
}

function appear(id,time){
	var o = getElementById(id)

	if (o.appear!=true){	// stop double event
		o.fade = false
		o.appear = true
		appear1(id,time,0)
	}
}

function appear1(id,time,opacity){
	var o = getElementById(id)

      if (o.appear!=false){
		opacity = opacity+1;
		setOpacity(id,opacity)

		if (opacity<100){
			var cmd = "appear1('"+id+"',"+time+","+opacity+")"
			setTimeout(cmd,time)
		}
	}
}

function ghost(id){
	var o = getElementById(id)

	if (o.ghost!=true){	// stop double event
		o.ghost = true
		ghost1(id,0,80,-1)
	}
}

function ghost1(id,time,opacity,inc){
	var o = getElementById(id)

      if (o.ghost!=false){
		opacity = opacity+inc

		if (opacity<10){
			inc = 1
			opacity = 10
		}
		else if (opacity>80){
			inc = -1
			opacity = 80
		}

		setOpacity(id,opacity);
		var cmd = "ghost1('"+id+"',"+time+","+opacity+","+inc+")"
		setTimeout(cmd,time)
	}
}

function browser(){
	var agent = navigator.userAgent

	if ( agent.indexOf("Firefox")>-1)
		return "FF"

	if ( agent.indexOf("MSIE")>-1)
		return "IE"

	return "CSS3"
}

function setOpacity(id,opacity){
	var o = getElementById(id)

	if (o.group!=undefined){
		var group = o.group

		for (i=0;i<group.members.length;i++){
			var member = group.members[i];
			setO(member,opacity)
		}
	}
	else
		setO(o,opacity)
}

function j2eOpacity(id,opacity){
	var o = getElementById(id)

	if (o!=undefined)
		o.j2eOpacity = opacity
}

function setO(o,opacity){
	var opac = ""+opacity/100;

	if (browser()=="FF")
		o.style.MozOpacity=opac
	else if (browser()=="IE"){
		try{
			o.filters.alpha.opacity=""+opacity
		}
		catch(err){
			var e = err
		}
	}
	else
		o.style.opacity=opac
}

function balloon(id,speed){
	var o = getElementById(id)

	if (o.balloon!=true){	// stop double event
		o.balloon = true
		o.fall = false
		o.balloonSpeed = speed
		setGroupOffsets(o)
		balloon1(id,speed,o.sy,time())
	}
}

function balloon1(id,speed,top,starttime){
	var o = getElementById(id)

      if (o.balloon!=false){
		var t = size(top)
		var u = units(top)
		t = (t - speed * (time()-starttime)/1000)

		o.sy = t+u
		o.style.top = o.sy

		moveShadow(o)
		moveGroup(o)

		if (t+groupHeight(o)>0){
			var cmd = "balloon1('"+id+"',"+speed+",'"+top+"',"+starttime+")"
			setTimeout(cmd,frameTime)
		}
	}
}

function groupHeight(o){
	if (o.group!=undefined){
		var h = setGroupHeight(o)
		return h * 25.4 / 96
	}

	return size(o.sh)
}

function bounce(id,damp){
	var o = getElementById(id)

	if (o.bounce!=true){	// stop double event
		o.bounce = true
		o.fall = false
		o.balloon = false
		o.damp = damp

		o.ydrag = 1 * damp /100
		o.t = 0
		o.t0 = 0
		o.yo = size(o.sy)
		o.h = size(o.sh)

            if (units(o.sy)=="in"){
			o.yo = o.yo * 25.4
			o.h = o.h * 25.4
		}
		else if (units(o.sy)=="px"){
			o.yo = o.yo * 25.4 / 96
			o.h = o.h * 25.4 / 96
		}

		if (o.group!=undefined)
			o.h = setGroupHeight(o) *25.4 / 96;

		o.vyo = 0
		o.amplitude = 1000000

		var window = windowSize()
		setGroupOffsets(o)
		bounce1(id,damp,time(),pixelsToMM(window.height)-1)
	}
}

function setGroupHeight(o){
	if (o.group!=undefined){
		var group = o.group
		var docPos = getPosition(o)
		var bottom = docPos.y + docPos.h

		for (i=0;i<group.members.length;i++){
			var member = group.members[i];

			if (member != o){
				var memPos = getPosition(member)
				bottom = Math.max(bottom, memPos.y+memPos.h)
			}
		}

		return bottom - docPos.y
	}

	return o.height
}

function bounce1(id,damp,starttime,windowHeight){
	var o = getElementById(id)

      if (o.bounce!=false){
		var g = 10		// constant
		var dt = 0.1	// constant

		var e = o.t - o.t0
		var down = 0.5 * g * e * e
		var up = o.vyo*e
		var y = down + o.yo + up
		var vy = g*e + o.vyo
		o.amplitude = Math.min(o.amplitude,y)

		if (Math.abs(down) > Math.abs(up) && hasLanded(y,o.h,windowHeight)){
			o.ydrag = o.ydrag - 0.01

			o.t0 = o.t
			o.vyo = -vy * o.ydrag

//			if (hasLanded(y,o.h,windowHeight))
				o.yo = windowHeight - o.h
// TODO hit other object...

			y = o.yo

			if (y-o.amplitude<0.5)
				return

			o.amplitude = y
		}

		try{
			var pos1 = getPosition(o)
			o.style.top = y+"mm"
			var pos2 = getPosition(o)

			o.t = o.t+dt
			moveShadow(o)
			moveGroup(o)

			var cmd = "bounce1('"+id+"',"+damp+","+starttime+","+windowHeight+")"
			setTimeout(cmd,10)
		}
		catch(err){}	// Happens if talking while bouncing
	}
}

function hasLanded(y,height,windowHeight){
	if (y+height > windowHeight)
		return true;

	return false;
}

function fall(id,speed){
	var o = getElementById(id)

	if (o.fall != true){
		o.fall = true
		o.balloon = false
		o.fallSpeed = speed
		o.h = setGroupHeight(o)
		setGroupOffsets(o)
		fall1(id,speed,o.sy,time())
	}
}

function fall1(id,speed,top,starttime){
	var o = getElementById(id)

      if (o.fall!=false){
		var t1 = size(top)
		t1 = t1 - -(speed * (time()-starttime)/1000)
		o.style.top = t1+units(top)

		t1 += 3
		moveShadow(o)
		moveGroup(o)

		var pos = getPosition(o)
		var window = windowSize()

		if (pos.y+o.h<window.height-4){	// -4 to stop firefox adding vertical scroll bar
			var cmd = "fall1('"+id+"',"+speed+",'"+top+"',"+starttime+")"
			setTimeout(cmd,frameTime)
		}
	}
}

function moveShadow(o){
	if (o.shadow!=undefined){
		var shadow = getElementById(o.shadow)
		var docPos = getPosition(o)

		if (o.shadowY!=undefined)
			shadow.style.top = docPos.y + size(o.shadowY)

		if (o.shadowX!=undefined){
			var frame = getElementById("content")
			var framePos = getPosition(frame)
			shadow.style.left = docPos.x - framePos.x + size(o.shadowX)
		}
	}
}

var quake = new Array(-5, 4, 6, -4, -3, 5, 3, -6, -4, 5, 1 )

function earthquake(id,i){
	var o = getElementById(id)
	var x = size(o.sx)
	x += quake[i]

	if (i==0)
		setGroupOffsets(o)

	o.style.left = x+"mm"
	moveShadow(o)
	moveGroup(o)

	i++
	if (i<quake.length){
		var cmd = "earthquake('"+id+"',"+i+")"
		setTimeout(cmd,40)
	}
}

function follow(id,duration,loop){
	var o = getElementById(id)

	if (o.followEnd==true){
		o.followEnd=false
		o.follow=false
		positionOnly(id,o.sx,o.sy)	// tidy up
		moveShadow(o)
		moveGroup(o)
	}
	else if (o.follow!=true){	// stop double event
		o.follow = true
		setGroupOffsets(o)
		followLoop(id,duration,loop,time())
	}
}

function setGroupOffsets(o){
	var docPos = getPosition(o)

	if (o.group!=undefined){
		var group = o.group

		for (i=0;i<group.members.length;i++){
			var member = group.members[i];

			if (member != o){
				var memPos = getPosition(member)
				member.groupOffsetX = docPos.x - memPos.x
				member.groupOffsetY = docPos.y - memPos.y
			}
		}
	}

	var h = o.id+"h"
	var handle = getElementById(h)

	if (handle!=undefined){
		var handlePos = getPosition(handle)
		handle.handleOffsetX = docPos.x - handlePos.x
		handle.handleOffsetY = docPos.y - handlePos.y
	}
}

function moveGroup(o){
	if (o.group!=undefined){
		var group = o.group
		var docPos = getPosition(o)
		var frame = getElementById("content")
		var framePos = getPosition(frame)

		for (i=0;i<group.members.length;i++){
			var member = group.members[i];

			if (member != o){
				member.style.position = 'absolute'
				member.style.left = (docPos.x - member.groupOffsetX - framePos.x)
				member.style.top  = (docPos.y - member.groupOffsetY)
			}
		}
	}

	var h = o.id+"h"
	var handle = getElementById(h)

	if (handle!=undefined){
		var docPos = getPosition(o)
		var frame = getElementById("content")
		var framePos = getPosition(frame)
		handle.style.left = (docPos.x - handle.handleOffsetX - framePos.x)
		handle.style.top  = (docPos.y - handle.handleOffsetY)
	}
}

function followLoop(id,dur,loop,starttime){
	var o = getElementById(id)
	var elapsed = time() - starttime;
	var coord = o.coord
	var length = pathLength(coord)

	while (elapsed > dur){
		if (loop==0){
			o.followEnd=true
			return
		}

		elapsed -= dur
	}

	var i = 0
	var d = length * elapsed / dur
	var length = 0

	while (i+3 < coord.length ){
		var x = coord[i+2] - coord[i]
		var y = coord[i+3] - coord[i+1]
		var len = Math.sqrt( x * x + y * y )

		if ( length + len >= d ){
			var dist = d - length
			var w = size(o.sw)
			var h = size(o.sh)

			x = x * dist / len - w/2
			y = y * dist / len - h/2

			o.style.left = (coord[i]+x)+"mm"
			o.style.top  = (coord[i+1]+y)+"mm"
			moveShadow(o)
			moveGroup(o)

			var cmd = "followLoop('"+id+"','"+dur+"',"+loop+","+starttime+")"
			setTimeout(cmd,30)
			return
		}

		length += len;
		i += 2
	}

	o.follow = false
}

function diff(o,n){
	var x = size(o)
	var y = size(n)
	return (y-x) * 25.4 / 96;
}

function pathLength(coord){
	var i = 0
	var length = 0

	while (i+3 < coord.length ){
		var x = coord[i+2] - coord[i]
		var y = coord[i+3] - coord[i+1]
		var len = Math.sqrt( x * x + y * y )
		length += len;
		i += 2
	}

	return length
}

var col = new Array('#ff0f00','#ff1f00','#ff2e00','#ff3d00','#ff4d00','#ff5c00','#ff6b00','#ff7a00','#ff8a00','#ff9900\
','#ffa800','#ffb800','#ffc700','#ffd600','#ffe600','#fff500','#faff00','#ebff00','#dbff00','#ccff00','#bdff00','#adff00\
','#9eff00','#8fff00','#7fff00','#70ff00','#61ff00','#52ff00','#42ff00','#33ff00','#24ff00','#14ff00','#05ff00','#00ff0a\
','#00ff19','#00ff29','#00ff38','#00ff47','#00ff57','#00ff66','#00ff75','#00ff85','#00ff94','#00ffa3','#00ffb2','#00ffc2\
','#00ffd1','#00ffe0','#00fff0','#00ffff','#00f0ff','#00e0ff','#00d1ff','#00c2ff','#00b3ff','#00a3ff','#0094ff','#0085ff\
','#0075ff','#0066ff','#0057ff','#0047ff','#0038ff','#0029ff','#001aff','#000aff','#0500ff','#1400ff','#2400ff','#3300ff\
','#4200ff','#5200ff','#6100ff','#7000ff','#7f00ff','#8f00ff','#9e00ff','#ad00ff','#bd00ff','#cc00ff','#db00ff','#eb00ff\
','#fa00ff','#ff00f5','#ff00e6','#ff00d6','#ff00c7','#ff00b8','#ff00a8','#ff0099','#ff008a','#ff007a','#ff006b','#ff005c\
','#ff004d','#ff003d','#ff002e','#ff001f','#ff000f','#ff0000','#ff0000')

function rainbow(id,type){
	var o = getElementById(id)

	if (o.rainbow != true){	// stop double event
		o.rainbow = true
		rainbow1(id,0,type)
	}
}

function rainbow1(id,i,type){
	var o = getElementById(id)

      if (o.rainbow!=false){
		if (type=="text")
			o.style.color = col[i]
		else if (type=="fill")
			o.style.background = col[i]
		else if (type=="outline")
			o.style.borderColor = col[i]

		i++

		if (i>=col.length)
			i=0

		var cmd = "rainbow1('"+id+"',"+i+",'"+type+"')"
		setTimeout(cmd,100)
	}
}

function slideOn(id,sx,sy,sw,sh,duration,direction){
	var window = windowSize()
	var o = getElementById(id)
	var frame = getElementById("content")
	var framePos = getPosition(frame)

	var bottom = pixelsToMM(window.height)
	var right = pixelsToMM(window.width)-pixelsToMM(framePos.x)
	var left = size(sw)+pixelsToMM(framePos.x)
	var top= "-"+sh

	bottom = bottom+"mm"
	right = right+"mm"
	left = (-left)+"mm"
	setGroupOffsets(o)

	if (direction=="north" || direction=="top")
		moveSize( id, sx, top, sw, sh, sx, sy, sw, sh, time(), duration )
	else if (direction=="south" || direction=="bottom")
		moveSize( id, sx, bottom, sw, sh, sx, sy, sw, sh, time(), duration )
	else if (direction=="east" || direction=="right")
		moveSize( id, right, sy, sw, sh, sx, sy, sw, sh, time(), duration )
	else if (direction=="west" || direction=="left")
		moveSize( id, left, sy, sw, sh, sx, sy, sw, sh, time(), duration )
	else if (direction=="nw")
		moveSize( id, left, top, sw, sh, sx, sy, sw, sh, time(), duration )
	else if (direction=="ne")
		moveSize( id, right, top, sw, sh, sx, sy, sw, sh, time(), duration )
	else if (direction=="se")
		moveSize( id, right, bottom, sw, sh, sx, sy, sw, sh, time(), duration )
	else // if (direction=="sw")
		moveSize( id, left, bottom, sw, sh, sx, sy, sw, sh, time(), duration )
}

function shrinkH(id,duration){
	var o = getElementById(id)
	var x = size(o.sx)
	var w = size(o.sw)
	x = x + w/2

	moveSize( id, o.sx, o.sy, o.sw, o.sh, x+"mm", o.sy, "0mm", o.sh, time(), duration )
}

function shrinkV(id,duration){
	var o = getElementById(id)
	var y = size(o.sy)
	var h = size(o.sh)
	y = y + h/2

	moveSize( id, o.sx, o.sy, o.sw, o.sh, o.sx, y+"mm", o.sw, "0mm", time(), duration )
}

function shrink(id,duration){
	var o = getElementById(id)
	var x = size(o.sx)
	var w = size(o.sw)
	var y = size(o.sy)
	var h = size(o.sh)

	x = x + w/2
	y = y + h/2

	moveSize( id, o.sx, o.sy, o.sw, o.sh, x+"mm", y+"mm", "0mm", "0mm", time(), duration )
}

function growH(id,duration){
	var o = getElementById(id)
	var x = size(o.sx)
	var w = size(o.sw)
	x = x + w/2

	moveSize( id, x+"mm", o.sy, "0mm", o.sh, o.sx, o.sy, o.sw, o.sh, time(), duration )
}

function growV(id,duration){
	var o = getElementById(id)
	var y = size(o.sy)
	var h = size(o.sh)
	y = y + h/2

	moveSize( id, o.sx, y+"mm", o.sw, "0mm", o.sx, o.sy, o.sw, o.sh, time(), duration )
}

function grow(id,duration){
	var o = getElementById(id)
	var x = size(o.sx)
	var w = size(o.sw)
	var y = size(o.sy)
	var h = size(o.sh)

	x = x + w/2
	y = y + h/2

	moveSize( id, x+"mm", y+"mm", "0mm", "0mm", o.sx, o.sy, o.sw, o.sh, time(), duration )
}

function pulse(id,frequency){
	var o = getElementById(id)

	if (o.pulse!=true){	// stop double event
		o.pulse = true
		throb(id,"hv",frequency,0)
	}
}

function pulseH(id,frequency){
	var o = getElementById(id)

	if (o.pulse!=true){	// stop double event
		o.pulse = true
		throb(id,"h",frequency,0)
	}
}

function pulseV(id,frequency){
	var o = getElementById(id)

	if (o.pulse!=true){	// stop double event
		o.pulse = true
		throb(id,"v",frequency,0)
	}
}

function throb(id,type,frequency,t){
	var o = getElementById(id)

	t = t + frequency*2*Math.PI/framesPerSecond;
	var amp = Math.cos(t);

      if (o.pulse!=false || amp!=1){
		var x = size(o.sx)
		var y = size(o.sy)
		var w = size(o.sw)
		var h = size(o.sh)
	
		if (type!="v"){
			var xx = w/20
			var delta = xx - xx * amp
			w = w - delta
      		x = x + delta/2
		}

		if (type!="h"){
			var yy = h/20
			var delta = yy - yy * amp
			h = h - delta
      		y = y + delta/2
		}

		var unit = units(o.sx)
		position(id,x+unit,y+unit,w+unit,h+unit)

		var cmd = "throb('"+id+"','"+type+"',"+frequency+","+t+")"
		setTimeout(cmd,frameTime)
	}
	else
		position(id,o.sx,o.sy,o.sw,o.sh)	// tidy up
}

function position(id,sx,sy,sw,sh){
	var o = getElementById(id)
	o.style.left   = sx
	o.style.top    = sy
	o.style.width  = sw
	o.style.height = sh
}

function positionOnly(id,sx,sy){
	var o = getElementById(id)
	o.style.left   = sx
	o.style.top    = sy
}

function pixelsToMM(pixels){
	return pixelsToInch(pixels)*25.4
}

function pixelsToInch(pixels){
	return pixels / 96
}

function moveSize( id, sx, sy, sw, sh, sx1, sy1, sw1, sh1, starttime, duration ){
	var t = time()
	var o = getElementById(id)

	var x = size(sx)
	var y = size(sy)
	var w = size(sw)
	var h = size(sh)
	var x1 = size(sx1)
	var y1 = size(sy1)
	var w1 = size(sw1)
	var h1 = size(sh1)
	
	if (x!=x1){
		x = x - - (x1-x) * (t-starttime)/duration	// - - to force arithmetic, not concatenation
		o.style.left = dp2(x)+units(sx)
	}

	if (y!=y1){
		y = y - - (y1-y) * (t-starttime)/duration	// - - to force arithmetic, not concatenation
		o.style.top = dp2(y)+units(sy)
	}

	moveShadow(o)
	moveGroup(o)

	if (w!=w1){
		w = w - - (w1-w) * (t-starttime)/duration	// - - to force arithmetic, not concatenation

		if (w<=0)
			hide(id)
		else{
			o.style.width = dp2(w)+units(sw)
			show(id)
		}
	}

	if (h!=h1){
		h = h - - (h1-h) * (t-starttime)/duration	// - - to force arithmetic, not concatenation

		if (h<=0)
			hide(id)
		else{
			o.style.height = dp2(h)+units(sh)
			show(id)
		}
	}

	if ( t-starttime < duration ){
		var cmd = "moveSize('"+id+"','"+sx+"','"+sy+"','"+sw+"','"+sh+"','"+sx1+"','"+sy1+"','"+sw1+"','"+sh1+"',"+starttime+","+duration+")"
		setTimeout(cmd,frameTime)
	}
	else{	// final size
		if (sx!=sx1)
 			o.style.left = sx1

		if (sy!=sy1)
			o.style.top = sy1

		if (sw!=sw1){
			if (size(sw1)==0)
				hide(id)
			else
				o.style.width = sw1
		}

		if (sh!=sh1){
			if (size(sh1)==0)
				hide(id)
			else
 				o.style.height = sh1
		}	
	}
}

function dp2(value){
	value = value*100
	value = Math.round(value)
 	return value/100
}

function size(length){
	return parseFloat(length)
}

function units(length){
	if (length.indexOf("mm")>-1)
		return "mm"

	if (length.indexOf("px")>-1)
		return "px"

	return "in"
}

function mouseMove(ev){
	ev = ev || window.event
	var mousePos = mouseCoords(ev)
}

function mouseCoords(ev){
	if(ev.pageX || ev.pageY)
		return {x:ev.pageX, y:ev.pageY}

	return {
		x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
		y:ev.clientY + document.body.scrollTop- document.body.clientTop
	}
}

document.onmousemove = mouseMove
document.onmouseup = mouseUp

var dragObject= null

function getMouseOffset(target, ev){
	ev = ev || window.event

	var docPos = getPosition(target)
	var mousePos = mouseCoords(ev)
	return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y}
}

function getPosition(e){
	var left = 0;
	var top = 0;
	
	var width = ('width' in e) ? e.width : e.offsetWidth;
	var height = ('height' in e) ? e.height : e.offsetHeight;

	while (e.offsetParent){
		left += e.offsetLeft;
		top += e.offsetTop;
		e = e.offsetParent;
	}

	left += e.offsetLeft;
	top+= e.offsetTop;

	return {x:left, y:top, w:width, h:height};
}

dialogueToDrag=undefined;

function mouseMove(ev){
	ev = ev || window.event
	var mousePos = mouseCoords(ev)

	if (dialogueToDrag!=undefined)
		return moveDialogue(ev);
	
	if(dragObject){
		var frame = getElementById("content")
		var framePos = getPosition(frame)
		dragObject.style.position = 'absolute'

		if (ev.shiftKey==false){	// move
			var top = mousePos.y - dragObject.mouseOffset.y - framePos.y
			var left = mousePos.x - dragObject.mouseOffset.x - framePos.x
			dragObject.style.top = top
			dragObject.style.left = left

			if ( dragObject.sy!=undefined )
				dragObject.sy = setSizeUnit(dragObject,top)

			if ( dragObject.sy!=undefined )
				dragObject.sx = setSizeUnit(dragObject,left)

			if (dragObject.shadow!=undefined){
				var shadow = getElementById(dragObject.shadow)

				if (shadow != undefined){
					shadow.style.position = 'absolute'
					var mouseEnd = mouseCoords(ev)
					shadow.style.top = mousePos.y - shadow.mouseOffset.y - framePos.y
					shadow.style.left = mousePos.x - shadow.mouseOffset.x - framePos.x

					if (shadow.shadow!=undefined){
						var shadow1 = getElementById(shadow.shadow)
						shadow1.style.position = 'absolute'
						var mouseEnd = mouseCoords(ev)
						shadow1.style.top = mousePos.y - shadow1.mouseOffset.y - framePos.y
						shadow1.style.left = mousePos.x - shadow1.mouseOffset.x - framePos.x
					}
				}
			}

			if (dragObject.group!=undefined){
				var group = dragObject.group

				for (i=0;i<group.members.length;i++){
					var member = group.members[i];

					if (member != dragObject){
						member.style.position = 'absolute'
						var mouseEnd = mouseCoords(ev)
						member.style.top = mousePos.y - member.mouseOffset.y - framePos.y
						member.style.left = mousePos.x - member.mouseOffset.x - framePos.x 

						if ( member.sy!=undefined )
							member.sy = setSizeUnit(member,top)

						if ( member.sy!=undefined )
							member.sx = setSizeUnit(member,left)
					}	
				}
			}

			var video = videoFromHandle(dragObject)
			if (video!=undefined){	// moving video
				if (video.sy!=undefined){
					video.sy = setSizeUnit(video,top)
					video.sx = setSizeUnit(video,left)
				}

				var sizer = sizerFromHandle(dragObject)

				if (sizer!=undefined){
					var v = getVideoFrame(dragObject)

					if (v!=undefined){
						var pos = getPosition(v)
						sizer.style.top  = (pos.y+pos.h*1-14-framePos.y)+"px"
						sizer.style.left = (pos.x+pos.w*1-14-framePos.x)+"px"
					}
				}
			}
			else{	// sizing video
				video = videoFrameFromSizer(dragObject)

				if (video!=undefined){
					var coords = mouseCoords(ev)
					var yDiff = coords.y - dragObject.mouseStart.y
					var xDiff = coords.x - dragObject.mouseStart.x;
					video.style.height = (video.j2eHeight + yDiff) + "px"
					video.style.width  = (video.j2eWidth + xDiff) + "px"
					video.width = video.j2eWidth + xDiff
					video.height = video.j2eHeight + yDiff

					var v = videoFromSizer(dragObject)
					v.style.height = (video.j2eHeight + yDiff) + "px"
					v.style.width  = (video.j2eWidth + xDiff) + "px"

					if (v.shadow!=undefined){
						var s = getElementById(v.shadow)

						if (s!=undefined){
							s.style.height = (s.j2eHeight + yDiff) + "px"
							s.style.width  = (s.j2eWidth + xDiff) + "px"
						}
					}

					v = videoHandleFromSizer(dragObject)
					v.style.width  = (video.j2eWidth + xDiff) + "px"
					v.style.height = (video.j2eHeight + yDiff + 10) + "px"
				}
			}
		}
		else{	// Size with shift key
			var coords = mouseCoords(ev)
			var yDiff = coords.y - dragObject.mouseStart.y
			var xDiff = coords.x - dragObject.mouseStart.x;
			dragObject.style.height = (dragObject.j2eHeight + yDiff) + "px"
			dragObject.style.width = (dragObject.j2eWidth + xDiff) + "px"

			if (dragObject.shadow!=undefined){
				var s = getElementById(dragObject.shadow)

				if (s!=undefined){
					s.style.height = (s.j2eHeight + yDiff) + "px"
					s.style.width  = (s.j2eWidth + xDiff) + "px"
				}
			}
		}

		return false
	}
}

function setSizeUnit(o,value){
	if (units(o.sy)=="in"){
		value = value / 96
		return value+"in"
	}
	else{
		value = value * 25.4 / 96
		return value+"mm"
	}
}

function mouseUp(ev){
	solid()

	if (bin!=undefined && dragObject!=undefined){
		ev = ev || window.event
		var mousePos = mouseCoords(ev)
		var trash = getElementById(bin)

		if (trash!=dragObject){
			var pos = getPosition(trash)

			if (mousePos.x > pos.x && mousePos.x < pos.x+pos.w && mousePos.y > pos.y && mousePos.y < pos.y+pos.h)
				binIt(dragObject)
		}
	}

	if (dragObject!=undefined){
		if (dragObject.jigsaw!=undefined)
			jigsawSnap(dragObject,dragObject.jigsaw)

		restart(dragObject)

		var video = videoFromHandle(dragObject)
		if (video!=undefined){
			restart(video)
			dragObject.style.height = "10px"
		}

		var v = videoHandleFromSizer(dragObject)
		if (v!=undefined)	// Reset move handle height
			v.style.height = "10px"

		if (dragObject.group!=undefined){
			var group = dragObject.group

			for (i=0;i<group.members.length;i++){
				var member = group.members[i];

				if (member != dragObject)
					restart(member)
			}
		}
	}

	selected = new Array(dragObject)
	dragObject = null
	
	if (dialogueToDrag!=undefined)
		endMove();
}

function videoFromHandle(o){
	var uniqueId = ""+o.id
	if (uniqueId.substr(uniqueId.length-1) == "h")
		return getElementById(uniqueId.substring(0,uniqueId.length-1));

	return undefined
}

function getVideoFrame(o){
	var uniqueId = ""+o.id
	if (uniqueId.substr(uniqueId.length-1) == "h" )
		return getElementById(uniqueId.substring(0,uniqueId.length-1)+"v");

	return undefined
}

function sizerFromHandle(o){
	var uniqueId = ""+o.id
	if (uniqueId.substr(uniqueId.length-1) == "h" )
		return getElementById(uniqueId.substring(0,uniqueId.length-1)+"z");

	return undefined
}

function videoFrameFromSizer(o){
	var uniqueId = ""+o.id
	if (uniqueId.substr(uniqueId.length-1) == "z" )
		return getElementById(uniqueId.substring(0,uniqueId.length-1)+"v");

	return undefined
}

function videoFromSizer(o){
	var uniqueId = ""+o.id
	if (uniqueId.substr(uniqueId.length-1) == "z" )
		return getElementById(uniqueId.substring(0,uniqueId.length-1));

	return undefined
}

function videoHandleFromSizer(o){
	var uniqueId = ""+o.id
	if (uniqueId.substr(uniqueId.length-1) == "z" )
		return getElementById(uniqueId.substring(0,uniqueId.length-1)+"h");

	return undefined
}

function restart(o){
	if (o.damp!=undefined)
		bounce(o.id,o.damp)

	if (o.fallSpeed!=undefined)
		fall(o.id,o.fallSpeed)

	if (o.balloonSpeed!=undefined)
		balloon(o.id,o.balloonSpeed)
}

function binIt(o){
	if (o.shadow!=undefined){
		var shadow = getElementById(o.shadow)
		binIt(shadow)
	}

	o.setAttribute("hidden",true)
	o.setAttribute("id","")

	if (o.getAttribute("src")==undefined)
		o.innerHTML = ""

	setO(o,0.0)
	o.trashed = true
	o.style.width = 0
	o.style.height = 0
}

function windowSize(){ 
	var frame = getElementById("content")
	var framePos = getPosition(frame)

	if(document.body.clientWidth) { 
		this.x= -framePos.x
		this.y=0
		this.width=document.body.clientWidth
		this.height=document.body.clientHeight
	} else { 
		this.x= -framePos.x
		this.y=0
		this.width = window.innerWidth
		this.height=document.innerheight
	} 
	return this
} 

function makeCopyable(item){
	var o = getElementById(item)
	o.copies = true
	makeDraggable(item)
}

function makeDraggable(item){
	var o = getElementById(item)

	if (o==undefined) return false

	var isiPad = navigator.platform=='iPad' || navigator.platform=='iPhone' || navigator.platform=='iPod';
	//var isiPad = navigator.userAgent.match(/iPad/i) != null;
	//var isiPad = typeof(window['ontouchstart']) != 'undefined';	better, but did not seem to work.
	if(isiPad && typeof webkit_draggable != "undefined")
		o.iPadDrag = new webkit_draggable(item);
	else
		o.onmousedown = function(ev){
			ev = ev || window.event
	
			if (ev.button == 2 ) return false
			if (this.trashed!=undefined) return false
	
			if (ev.shiftKey==false && ((this.copies && ev.ctrlKey==false) || (this.copies==undefined && ev.ctrlKey==true)) ){	// Code to drag copy
				var shadow = undefined
	
				if (this.shadow!=undefined){
					shadow = getElementById(this.shadow)
					shadow = clone(shadow)
				}
	
				dragObject = clone(this)
				dragObject.mouseOffset = getMouseOffset(dragObject, ev)
	
				if (shadow!=undefined)
					dragObject.shadow = shadow.id
	
				makeDraggable( dragObject.id )
			}
			else{
				dragObject = this
				stopPlaying(this,ev)
	
				var video = videoFromHandle(dragObject)
				if (video!=undefined){
					stopPlaying(video,ev)
					var frame = getVideoFrame(dragObject)
					pos = getPosition(frame)
					dragObject.style.height = pos.h*1 + 10 + "px"
				}
					
				if (dragObject.group!=undefined){
					var group = dragObject.group
	
					for (i=0;i<group.members.length;i++){
						var member = group.members[i];
	
						if (member != dragObject)
							stopPlaying(member,ev)
					}
				}
	
				// For sizing
				var pos = getPosition(dragObject)
				dragObject.j2eHeight = pos.h
				dragObject.j2eWidth = pos.w
				dragObject.mouseStart = mouseCoords(ev)
	
				var video = videoFrameFromSizer(dragObject)
	
				if (video!=undefined){
					pos = getPosition(video)
					video.j2eHeight = pos.h * 1	// Force numeric
					video.j2eWidth = pos.w * 1
	
					// Size the handle to cover the page, to stop clicks going the wrong place
					var handle = videoHandleFromSizer(dragObject)
					handle.style.height = video.j2eHeight + "px"
				}
	
				var s = getShadow(this)
	
				if (s!=undefined){
					pos = getPosition(s)
					s.j2eHeight = pos.h
					s.j2eWidth = pos.w
				}
			}
	
			dim()
		
			if (dragObject.style.zIndex!=lastLayer){
				dragObject.style.zIndex = ++lastLayer	// Bring to top
	
				var sizer = sizerFromHandle(dragObject)
	
				if (sizer!=undefined)
					sizer.style.zIndex = lastLayer
			}
	
			if (dragObject.shadow!=undefined){
				var shadow = getElementById(dragObject.shadow)
	
				if (shadow!=undefined){
					shadow.mouseOffset = getMouseOffset(shadow, ev)
					shadow.style.zIndex = lastLayer
	
					if (shadow.shadow!=undefined){
						var shadow1 = getElementById(shadow.shadow)
						shadow1.mouseOffset = getMouseOffset(shadow1, ev)
						shadow1.style.zIndex = lastLayer
					}
				}
			}
	
			if (dragObject.group!=undefined){
				var group = dragObject.group
	
				for (i=0;i<group.members.length;i++){
					var member = group.members[i];
	
					if (member != dragObject){
						member.mouseOffset = getMouseOffset(member, ev)
						member.style.zIndex = lastLayer
					}
				}
			}
	
			return false
		}

	document.onkeyup = processKey
}

function getShadow(o){
	var shadow = undefined

	if (o.shadow!=undefined)
		shadow = getElementById(o.shadow)

	if (shadow==undefined){
		var v = videoFromSizer(o)

		if (v!=undefined && v.shadow!=undefined)
			return getElementById(v.shadow)
	}

	return shadow
}

function clone(o){
	var c = document.createElement("div")
	var newId = "copy" + nextId++

	if (o.getAttribute("src")==undefined){
		c.setAttribute("id",newId)
		c.innerHTML = o.innerHTML
	}
	else
		c.innerHTML = '<img id="' + newId + '" src="' +o.getAttribute("src")+ '">'

	var base = getElementById("content")
	var pos = getPosition(o)
	var basePos = getPosition(base)
	var horizonPos = getPosition(getElementById("horizon"))

	base.appendChild(c)
	c = getElementById(newId)
	c.style.position = 'absolute'
	c.style.cursor = 'move'

	c.style.left = (pos.x - (basePos.x - horizonPos.x))+"px"
	c.style.top = (pos.y - (basePos.y - horizonPos.y))+"px"
	c.style.width = pos.w+"px"
	c.style.height = pos.h+"px"

	return c
}

function stopPlaying(o,ev){
	o.mouseOffset = getMouseOffset(o, ev)
	o.bounce = false
	o.fall = false
	o.balloon = false
}

function solid(){
	if (dragObject!=undefined){
		if (dragObject.j2eOpacity!=undefined)
			setO(dragObject,dragObject.j2eOpacity)
		else
			setO(dragObject,100.0)
	}
}

function dim(){
	if (dragObject.j2eOpacity!=undefined)
		setO(dragObject,Math.max(0,dragObject.j2eOpacity - 10))
	else
		setO(dragObject,80.0)
}

function onClick(item,cmd){
	var o = getElementById(item)

	if (cmd.indexOf("say(")!=-1)	// patch up speak marks within text.
		cmd = quotes(cmd,true)

	if (o!=undefined){
		if (o.group!=undefined){
			var g = o.group

			for (i=0;i<g.members.length;i++){
				g.members[i].onmousedown = function(ev){
					eval(cmd)
				}
			}
		}
		else
			o.onmousedown = function(ev){
				eval(cmd)
			}
	}
}

function quotes(txt,first){
	var i = txt.indexOf("'")

	if (i!=-1){
		var s = txt.substring(0,i)
		var e = txt.substring(i+1)

		if (e.indexOf("'")==-1)	// the end
			return txt

		e = quotes(e,false)

		if (!first)
			return s + "\\'" + e

		return s + "'" + e
	}

	return txt
}

function timeAfterClick(item,cmd,time){
	var o = getElementById(item)

	if (o != undefined){
		o.onmousedown = function(ev){
			setTimeout(cmd,time)
		}
	}
}

function onMouseOver(item,cmd){
	var o = getElementById(item)

	if (o != undefined){
		if (o.group!=undefined){
			var g = o.group

			for (i=0;i<g.members.length;i++){
				g.members[i].onmouseover = function(ev){
					groupOver(item,cmd)
				}
			}
		}
		else
			o.onmouseover = function(ev){
				eval(cmd)
			}
	}
}

function onMouseOut(item,cmd){
	var o = getElementById(item);

	if (o != undefined){
		if (o.group!=undefined){
			var g = o.group;

			for (i=0;i<g.members.length;i++){
				g.members[i].onmouseout = function(ev){
					groupOut(item,cmd);
				}
			}
		}
		else
			o.onmouseout = function(ev){
				eval(cmd);
			}
	}
}

function groupOver(item,cmd){
	var o = getElementById(item);

	if (o.group!=undefined){
		var g = o.group;
		for (i=0;i<g.members.length;i++){
			if (g.members[i].isOver==true){	// already running
				o.isOver = true;
				return;
			}
		}
	}

	o.isOver = true;
	eval(cmd)
}

function groupOut(item,cmd){
	var o = getElementById(item);
	o.isOver = false;

	if (o.group!=undefined){
		var g = o.group;
		for (i=0;i<g.members.length;i++){
			if (g.members[i].isOver==true)	// still over another
				return;
		}
	}

	eval(cmd);
}

function sound(object) {
	var s=document.getElementById(object);
	try { s.Play(); }
	catch(e){
		try{ s.DoPlay(); }	// For RealPlayer
		catch(e){}
	}
}

function jqsound(object) {
	var s=document.getElementById(object);
	s = s && s.firstChild ? s.firstChild : s;
	if (s){
		try { s.Play(); }
		catch(e){
			try{ s.DoPlay(); }	// For RealPlayer
			catch(e){}
		}
	}
}

function browserInfo( ){
	document.cookie = "screenWidth=" + screen.width + ";";
	document.cookie = "screenHeight=" + screen.height + ";";
	document.cookie = "platform=" + navigator.platform + ";";
}

function group(name,members){
	this.name=name     	// type of jigsaw
	this.members=members	// Array of members

	for (i=0;i<members.length;i++){
		members[i] = getElementById(members[i])

		if (members[i] != undefined)
			members[i].group = this
	}
}

function showLinks(o){
	var obj = getElementById(o)

	if (obj != undefined){
		obj.onclick = hiddenLinks
		obj.onmousemove = hiddenLinksPointer
	}
}

function hiddenLinks(ev){
	if ( links.length > 0 ){
		ev = ev || window.event
		var mousePos = mouseCoords(ev)

		for (i=0;i<links.length;i+=3){
			var o = getElementById(links[i])

			if (o != undefined ){
				var pos = getPosition(o)

				if (mousePos.x > pos.x && mousePos.x < pos.x+pos.w && mousePos.y > pos.y && mousePos.y < pos.y+pos.h){
					var url = links[i+1]
					var target = links[i+2]
					window.open( url, target )
				}	
			}
		}
	}
}

function hiddenLinksPointer(ev){
	if ( links.length > 0 ){
		ev = ev || window.event
		var mousePos = mouseCoords(ev)

		if (this.oldPointer == undefined)
			this.oldPointer = this.style.cursor

		for (i=0;i<links.length;i+=3){
			var o = getElementById(links[i])

			if (o != undefined ){
				var pos = getPosition(o)

				if (mousePos.x > pos.x && mousePos.x < pos.x+pos.w && mousePos.y > pos.y && mousePos.y < pos.y+pos.h){
					this.style.cursor = 'pointer'
					return
				}
			}
		}

		this.style.cursor = this.oldPointer;	//'default'
	}
}

function processKey(e){
	e = e || window.event

	if (selected!=undefined){
		for( i in selected ){
			var item = selected[i]

			if (e.keyCode==46){
				if (item.shadow!=undefined){
					shadow = getElementById(item.shadow)
					shadow.parentNode.removeChild(shadow)
				}

				item.parentNode.removeChild(item)
			}
		}

		selected = undefined
	}
}

