// live
// ----------------------------------------
//
// Slide Async out-of-band RPC code
// Written by Donovan Preston
// Copyright 2005-2009, Slide Inc.
//
// ----------------------------------------


var disconnectListeners = []
var flashItemQueue = []

var createRequest = function() {
	if (window.XMLHttpRequest) {
		return new XMLHttpRequest();
	} else {
		return new ActiveXObject("Microsoft.XMLHTTP");
	}
}


// this code does the simplest thing that could possibly work right now;
// it doesn't try to be reusable in any way. If more code is added and
// reuse is desired, refactoring should occur.
// I'll second that motion.

// TODO use mochikit.async.deferred instead of whenDone callback

var remoteAction = function(method, action, params, whenDone, sendRequest) {
	if (action.charAt(0) == '/') {
		var theURL = action
	} else {
		var theURL = '/'+action
	}
	var postdata = '';
	if (params) {
		postdata = queryString(params);
		if (postdata && (method == "GET")) {
			theURL = theURL + "?" + postdata;
			postdata = "";
		}
	}

	var req = createRequest();
	req.onreadystatechange = function() {
		if (req.readyState == 4) {
			if (whenDone) whenDone(req.responseText);
		}
	}
	sendRequest(req, theURL, postdata);
}

var getViewName = function() {
	return window.location;
};

var asyncCommand = function(commandType) {
	return function(action, params, whenDone) {
		params.referrer = getViewName();
		remoteAction(commandType, action, params, whenDone,
					 function(req, theURL, theData) {
			req.open(commandType, theURL, true);
			req.setRequestHeader('HTTP-Command-Equiv', commandType);
			req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			req.send(theData);
		})
	}
}

var asyncAction = asyncCommand("POST");
var asyncPut = asyncCommand("PUT");

var asyncView = function(action, params, whenDone) {
	remoteAction("GET", action, params, whenDone,
				 function(req, theURL, theData) {
					 if (theData) {
						 var sep = ( theData.indexOf("?") > 0) ? "&" : "?";
						 req.open("GET", theURL + sep + theData, true);
					 } else {
						 req.open("GET", theURL, true);
					 }
					 req.send(null);
				 })
}

var asyncJson = function(method, action, params, whenDone) {
	remoteAction(method, action, params, whenDone,
				 function(req, theURL, theData) {
					 if (theURL.charAt(0) != '/') {
						 theURL = '/' + theURL;
					 }
					 theURL = '/accept/application/x-json' + theURL;
					 req.open(method, theURL, true);
					 req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
					 req.setRequestHeader('x-http-command-equiv', method);
					 req.send(theData);
				 });
}

function $(theId) {
	return document.getElementById(theId);
}

function isPass(theResponse) {
	return theResponse.substring(0,4) != 'FAIL';
}

function isUnauthenticated(theResponse) {
	return theResponse == "FAIL: Unauthenticated";
}


/* From Skins */
var fill = function(node, fillers) {
	if (node) {
		if (node.getAttribute) {
			var slot = getNodeAttribute(node, 'x:slot');
			if (slot) {
				var filler = fillers[slot];
				if (filler) {
					replaceChildNodes(node, filler);
				}
			}
			var visible = getNodeAttribute(node, 'x:visible');
			if (visible && (false == fillers[visible])) {
				// alert(visible);
				node.parentNode.removeChild(node);
				return;
			}

			var attrs = getNodeAttribute(node, 'x:attr');
			while (attrs) {
				var colonPos = attrs.indexOf(':');
				var key = attrs.substring(0, colonPos);
				key = key.replace("_", ":");
				var commaPos = attrs.indexOf(',');
				if (commaPos != -1) {
					var value = attrs.substring(colonPos+1, commaPos);
					attrs = attrs.substring(commaPos+1);
				} else {
					var value = attrs.substring(colonPos+1);
					attrs = '';
				}
				if (fillers[value]) {
					node.setAttribute(key, fillers[value]);
				}
			}
			var attrs = getNodeAttribute(node, 'x:text');
			if (attrs) {
				var text = fillers[attrs];
				if (undefined != text) {
					replaceChildNodes(node, text);
				}
			}
		}
		for (var i = 0; i < node.childNodes.length; i++) {
			fill(node.childNodes[i], fillers);
		}
	}
}

var AllObservers = {}
var AllModelData = {}
var obkeyIndex = 0;
var observe = function(key, observer, nostartup) {
	if (! AllObservers[key]) {
		AllObservers[key] = {};
	}
	var obkey = String(obkeyIndex++) + ":" + key;
	if (observer) {
		AllObservers[key][obkey] = observer;
	}
	if (AllModelData[key]) {
		if (observer) {
			observer(AllModelData[key]);
		}
	} else if (!nostartup) {
		execute(key);
	}
	return obkey;
}

var unobserve = function(obkey) {
	if (obkey) {
		var colonPos = obkey.indexOf(':');
		var key = obkey.substring(colonPos+1);
		delete AllObservers[key][obkey];
	}
}

var reobserve = function(key, observer) {
	delete AllModelData[key];
	observe(key, observer);
}

var _patterns = null;

var walk = function(node, prefix) {
	if (node.nodeType == 1) {
		try {
			var pattern = getNodeAttribute(node, 'x:pattern');
			if (pattern) {
				prefix += (prefix ? ':' : '') + pattern;
				_patterns[pattern] = node;
			}
			if (getNodeAttribute(node, 'x:dummy')) {
				node.parentNode.removeChild(node);
			}
		} catch (e) { }
	}
	for (var i = 0; i < node.childNodes.length; i++) {
		walk(node.childNodes[i], prefix);
	}
}
var getPatternMap = function() {
	if (_patterns == null) {
		_patterns = {};
		walk(document.documentElement, '');
	}
	return _patterns;
}

var getPattern = function(patternName) {
    var patterns = getPatternMap();
	return patterns[patternName].cloneNode(true);
}

var pattern = function(patternName, fillers) {
	var pat = getPattern(patternName);
	if (fillers) {
		fill(pat, fillers);
	}
	return pat;
}


var tkeys = function(d) {
	var r = [];
	for (var k in d) {
		if (k[d]) {
			r.push(k);
		}
	}
	return r;
}

var _pendingExecute = {}
var execute = function(key) {
	if ( ! _pendingExecute[key]) {
		_pendingExecute[key] = true;
		asyncJson("GET", key, {}, function(results) {
			delete _pendingExecute[key];
			if (results) {
				results = evalJSON(results);
			}
			if (results.length) {
				for (var i=0; i < results.length; i++) {
					var row = results[i];
					if (row.url && (row.url != key) ) {
						updateModel(row.url, row);
					}
				}
			}
			updateModel(key, results);
		});
	}
}

var updateModel = function(key, results) {
	AllModelData[key] = results;
	var key_observers = AllObservers[key];
	for (var i in key_observers) {
		var observer = key_observers[i];
		if (observer) {
			observer(results);
		}
	}
};


var postURL = function(command, params, observer) {
	asyncJson("POST", command, params, observer);
}

var logWebEvent = function(event_id, foreign_id) {
	// postURL("/event", { event_id : event_id ,foreign_id : foreign_id }, null);
};
// end live
// xml
var _xmlWrap = function(name, contents) {
    return "<" + name + ">" + contents + "</" + name + ">";
}

var _xmlDisplay = function() {
    return _xmlWrap(this.name, map(repr, this.children).join(""));
}

var xARRAY = function(children) {
    this.children = children;
	this.name = "array"
}
xARRAY.prototype.repr = _xmlDisplay;

var xDICT = function(children) {
    this.children = children
	this.name = "dict"
}
xDICT.prototype.repr = _xmlDisplay;

var xINTEGER = function(child) {
    this.child =  child ;
	this.name = "integer"
}
xINTEGER.prototype.repr = function() {
    return _xmlWrap(this.name, this.child || 0);
}

// replace these critical chars with entity encodings
var xmlEscape = function(x) {
	x = x || '';
    return x.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(qt, "&quot;").replace(/%/g, "&#37;")
}

// replace these critical chars with url encodings
var urlEscape = function(x) {
	x = x || '';
	return x.replace(/%/g, "%25").replace(/ /g, "%20").replace(/\"/g, '%22').replace(/#/g, "%23").replace(/&/g, "%26").replace(/\'/g, "%27").replace(/\+/g, "%2b").replace(/</g, "%3c").replace(/>/g, "%3e").replace(/\?/g, "%3f").replace(/\{/g, "%7b").replace(/\}/g, "%7d");
}

var xSTRING = function(child) {
    this.child = child;
	this.name = "string"
}
xSTRING.prototype.repr = function() {
    return _xmlWrap(this.name, xmlEscape(this.child));
}

var xURLSTRING = function(child) {
    this.child = child;
	this.name = "string"
}
xURLSTRING.prototype.repr = function() {
    return _xmlWrap(this.name, urlEscape(this.child));
}

var xKEY = function(child) {
    this.child = child;
	this.name = "key"
}

xKEY.prototype.repr = function() {
    return _xmlWrap(this.name, this.child);
}

// constructors for empty arrays/dictionaries
function ARRAY() {
	return new xARRAY(list(ARRAY.arguments));
}
function DICT() {
	return new xDICT(list(DICT.arguments));
}

// use these as constructors for XML dom tree pieces.
// eg KEY(blah") => "<key>blah</key>"
// use URLSTRING for strings that will be urls.  Othewise & < > ' " become
// &entities; instead of %encoded, and they don't work.
var KEY = function(c) { return new xKEY(c); } ;
var STRING = function(c) { return new xSTRING(c); } ;
var URLSTRING = function(c) { return new xURLSTRING(c); } ;
var INTEGER = function(c) { return new xINTEGER(c); } ;

var qt = /"/g
// end xml"

// basics
// store oft used objects to avoid re-getting overhead
function bothFunctions(a, b) {
	return function() {
		if (a != undefined) a()
		if (b != undefined) b()
	}
}

function addOnloadFunction(f) {
	window.onload = bothFunctions(window.onload, f)
		}

var objectKeeper = {}
var $$ = function(objId) {
	if (objectKeeper[objId] == undefined) {
		objectKeeper[objId] = $(objId)
	}
	return objectKeeper[objId]
}

var valueOf = function(field) {
	if (field) {
		return field.type == 'checkbox' ? (field.checked ? 1 : 0) : field.value
	} else return null
}

function getObject(name) {
    if ("object" == typeof(name)) {
		return name; // this is actually the object itself, not its id
    }
	if (document.getElementById) {
	   	return document.getElementById(name);
 	}
 	else if (document.all) {
	   	return document.all[name];
 	}
 	else if (document.layers) {
	   	if (document.layers[name])
		{
	   		return document.layers[name];
		}
		else
		{
	    	return document.layers.testP.layers[name];
	   	}
 	}
}

function clearChildren(d) {
	if(d != null){
		d = getObject(d);
		while (d.childNodes[0]) {
			d.removeChild(d.childNodes[0]);
		}
	}
}

function SetText(id, newtext) {
	$(id).firstChild.data = newtext;
}

function GetElementPosition(target) {
	if (typeof(target) == "string") {
		target = $(target)
			}
	if(target.offsetParent) {
		for(var posX = 0, posY = 0; target.offsetParent; target = target.offsetParent ) {
			posX += target.offsetLeft
				posY += target.offsetTop
				}
		return { left:posX, top:posY }
	}
	else {
		return { left:target.x, top:target.y }
	}
}

// because IE won't play nice. From Quirksmode
var findPosX = function (obj) {
	var curleft = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curleft += obj.offsetLeft
				obj = obj.offsetParent
				}
	}
	else if (obj.x)
	curleft += obj.x
	return curleft;
}

var findPosY = function (obj) {
	var curtop = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curtop += obj.offsetTop;
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
	curtop += obj.y;
	return curtop;
}

function getkey(e) {
	if (window.event)
		return window.event.keyCode
			else if (e)
				return e.which
					else
						return null
							}

// See duplicate in basics.js; effectively identical
var setActionCookie = function(view, link, domain) {
	document.cookie = "action." + domain + "=" + view + "|" + link + ";domain=" + domain + ";path=/";
	return true;
}

var setLanguage = function(language, domain) {
	document.cookie = "language." + domain + "=" + language + ";domain=" + domain + ";path=/";
	document.location.reload(true);
	return false;
}

function strtrim(s) {
    return s.replace(/^\s+/,'').replace(/\s+$/,'')
		}

function ShowUpdate(id, offsetl, offsett, text){
	if (text == undefined) text = "Updating..."
							   var newLocation;
	var target = $("highlight")
		target.firstChild.innerHTML = text
		newLocation = GetElementPosition(id)
		target.style.left = (newLocation.left-offsetl) + 'px'
		target.style.top = (newLocation.top-offsett) + 'px'
		startFadeInAndOut("highlight", 300 + text.length * 10)
		}

function showError(id, offsetl, offsett, text) {
	// stub for Sergio.  This behaves similar to ShowUpdate, but
	// should pop up a box that waits for the user to dismiss it
	// so they don't miss the error.
	// alert(text);
	return
		}

function createText(parent, msg) {
	var elem = document.createTextNode(msg);
	parent.appendChild(elem);
	return elem;
}

function setAttribute(node, name, value) {
	for (var i = 0; i < node.attributes.length; i++) {
		if (node.attributes[i].name == name) {
			node.attributes[i].value = value;
			return true;
		}
	}
	return false;
}

function clearFader(fadeTarget) {
	if (fadeTarget.fader) {
		fadeTarget.fader.stop()
			}
}

function MakeInvisible(target) {
	target.style.visibility = 'hidden'
		}

function MakeVisible(target) {
	target.style.visibility = 'visible'
		}

function SetOpacity(target, opacity) {
	/* the .001 fixes a glitch in the opacity calculation which normally
	 * results in a flash when reaching 1, but in a Mac absorbs 30% of the CPU */
	correction = navigator.userAgent.toLowerCase().indexOf('mac') ? 0 : .001;
	if (target.style.opacity!=null) {
		/* CSS3 compatible */
		target.style.opacity = (opacity/100)- correction;
	} else if (target.style.MozOpacity!=null) {
		/* Mozilla's pre-CSS3 proprietary rule */
		target.style.MozOpacity = (opacity/100)-correction;
	} else if (target.style.filter!=null) {
		/* IE's proprietary filter */
		if (opacity == 100)  {
			target.style.filter = "";
		} else  {
			target.style.filter = "alpha(opacity="+opacity+")";
		}
		/* worth noting: IE's opacity needs values in a range of 0-100, not 0.0 - 1.0 */
	}
}

function startFadeInAndOut(id, duration) {
	var fadeTarget = $(id);
	clearFader(fadeTarget);
	fadeTarget.fader = new FadeInOut(fadeTarget, duration);
}

function FadeInOut(target, duration) {
	this.opacity = 0
		this.max = duration / 4
		this.step = +10
		this.running = true;

	this.tick = function() {
		if (this.running) {
			opacity = Math.min(this.opacity, 100);
			opacity = Math.max(opacity, 0);
			SetOpacity(target, opacity);
			this.opacity += this.step;
			if (this.opacity > this.max) {
				this.step = -5;
			}
			if (this.opacity > 0) {
				this.setTimeout();
			}
			else {
				MakeInvisible(target);
			}
		}
	}

	this.setTimeout = function() {
		var t = this;
		var f = function () { t.tick(); }
		setTimeout( f, 40);
	}

	this.stop = function() {
		this.running = false;
	}

	this.setTimeout();
	SetOpacity(target, 0);
	MakeVisible(target);
}

function createInput(frm, itype) {
	// because lame, lame IE won't let me set a type directly
	// or at all, if it has already been added to the parent
	var inputElement = (itype == "textarea") ? document.createElement("textarea") : document.createElement("input")
		if (!setAttribute(inputElement, "type", itype)) inputElement.type = itype
															frm.appendChild(inputElement)
															return inputElement
															}

function createElement(parent, tagname) {
	var elem = document.createElement(tagname)
		if (parent) {
			parent.appendChild(elem);
		}
	return elem;
}
// end basics
// dialog
var editDiv = null;
var handleSignout = doReload;
var handleSignin = doReload;

// this function can be overriden on a per-page basis
function doReload() {
	document.location.reload(true);
}

function displayResponse(serverAnswer) {
	var serverResponse = $("serverResponse");
	var serverMessage = createElement(serverResponse, "p");
	var theAnswer = createText(serverMessage, cl.Signin.Invalid_Username_or_Pw);
	serverMessage.className = "status";
}

var makeEditPopup =  function(location, label, imageURL) {  // [offsetX], [offsetY]

	var offsetX = arguments[3] ? -arguments[3] + 50 : 50;
	var offsetY = arguments[4] ? -arguments[4] + 50 : 50;

	var body = document.getElementsByTagName('body')[0];
	var newLocation;
	if (location) {
		newLocation = GetElementPosition(location);
	}
	else {
		var win = windowSize();
		newLocation = { left : win.width / 2,
						top : win.height / 4 } ;
	}
	containerDiv = createElement(body, 'div');
	containerDiv.id = "popupbg";
	if(document.all) {
		containerDiv.style.background = "none";
		containerDiv.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://static.slide.com/images/popup_prompt.png', sizingMethod='crop');";
	}
	containerDiv.style.left = (newLocation.left - offsetX) + 'px';
	containerDiv.style.top = (newLocation.top - offsetY) + 'px';
	containerDiv.style.width = '300px';
	containerDiv.style.height = '221px';
	containerDiv.style.zIndex = "1000";

	editDiv = createElement(body, 'div');
	editDiv.className = "editpopup";
	editDiv.id = "popupcontainer";
	editDiv.style.left = (newLocation.left - offsetX) + 'px';
	editDiv.style.top = (newLocation.top - offsetY) + 'px';
	editDiv.style.zIndex = "1000";

	var closeButton = createElement(editDiv, 'a');
	closeButton.href = '#';
	closeButton.className = 'closeButton';
	closeButton.onclick = dismissEditPopup;

	var h = createElement(editDiv, 'p');
	createText(h, label);
	if (imageURL != null) {
		var img = createElement(editDiv, "img");
		img.src = imageURL;
		img.className = "popupimg";
	}
	var frm = createElement(editDiv, "form");

	return frm;
}

function dismissEditPopup() {
	if (editDiv) {
		editDiv.style.visibility = "hidden";
		containerDiv.style.visibility = "hidden";
		// this is to work around a safari bug - we need to find a better way
		editDiv = null;
	}
	return false;
}


var signoutInProgress = false
function signout(location) {
	if (location) ShowUpdate(location, 10, 0, cl.Signin.Signing_Out);
	if (!signoutInProgress) {
		signoutInProgress = true
			asyncAction('userajax', { 'action' : 'signout' },
						function(theResponse){
							if (theResponse == 'PASS') {
								handleSignout();
							}
							else {
								alert(theResponse);
							}
						});
	}
	return false;
}

function signin(location, offsetX, offsetY, callback) {
	dismissEditPopup()

		// Sorry, Safari not supported at the moment
		if (navigator.vendor == "Apple Computer, Inc.") {
			document.location = "/mssignin"
				return false
				}

	var frm = makeEditPopup(location, cl.Signin.Sign_In, null, offsetX || 0, offsetY || 60)

		var serverResponse = createElement(frm, "div")
		serverResponse.id = "serverResponse"

		var signinForm = createElement(frm, 'form')
		signinForm.id = 'signinfrm'
		signinForm.name = 'signinfrm'
		signinForm.style.margin = '0'

		// Username
		var usernameDiv = createElement(signinForm, 'div')
		usernameDiv.id = "usernameDiv"

		var usernameLabel = createElement(usernameDiv, 'label')
		usernameLabel.style.width = '130px'
	usernameLabel.style.textAlign = 'right'
	createText(usernameLabel, cl.Signin.Slide_ID_or_Email)

	var username = createInput(usernameDiv, 'text')
	username.id = 'username'
	username.style.width = '115px'
	username.tabIndex = '101'

	// Password
	var passwordDiv = createElement(signinForm, 'div')
	passwordDiv.style.clear = "both"

	var passwordLabel = createElement(passwordDiv, 'label')
	passwordLabel.style.width = '130px'
	passwordLabel.style.textAlign = 'right'
	createText(passwordLabel, cl.Signin.Password)

	var password = createInput(passwordDiv, 'password')
	password.style.width = '115px'
	password.tabIndex = '102'

	// Remember Me / Submit
	var rememberDiv = createElement(signinForm, 'div')
	rememberDiv.style.marginTop = '10px'

	var submit = createInput(rememberDiv, 'submit')
	submit.className = 'buttonInput'
	submit.value = cl.Signin.Sign_In
	submit.tabIndex = '104'

	var remember = createInput(rememberDiv, 'checkbox')
	remember.className = 'checkboxInput'
	remember.checked = true
	remember.id = 'rememberme'
	remember.tabIndex = '103'
	createText(createElement(rememberDiv, 'label'), cl.Signin.Remember_Me)

	var forgotDiv = createElement(signinForm, 'div')
	forgotDiv.style.textAlign = 'right'
	var forgotLink = createElement(forgotDiv, 'a')
	forgotLink.href = '/forgot'
	forgotLink.target = '_blank'
	createText(forgotLink, cl.Signin.Lost_Username_or_Pw);

 	username.focus();

	submit.onclick = function () {
		clearChildren("serverResponse");

		asyncAction('userajax', { 'action' : 'signin',
									  'username' : username.value,
									  'password' : password.value ,
									  'remember' : remember.checked ? "on" : "off" },
					function(theResponse){
						pieces = theResponse.split(' ');
						if (pieces[0] == 'PASS') {
							ShowUpdate(location, -50, -50, cl.Signin.Signing_In);
							(callback || handleSignin)(pieces[1]);
						}
						else {
							displayResponse(theResponse);
						}
		 			});
		return false;
	};
	return false;
}
// end dialog
// colorpicker
var hidePalette = false
var paletteExists = false

var showPalette = function(obj, target, inputname, showTransparent, buildingSkin) {
	if (!paletteExists) fillColorPalette()
	$('paletteTransparency').style.display = showTransparent ? 'block' : 'none'
	palette = new PaletteObj(target, inputname, buildingSkin)
	palettePos = GetElementPosition(obj)
	pal.style.left = (palettePos.left - 94) + "px"
	pal.style.top = (palettePos.top + 22) + "px"
	pal.style.zIndex = "1000"
	pal.style.display = "block"

	hidePalette = false
	document.onclick = function() { paletteClick(target) }

	return false;
}

var paletteClick = function(target) {
	if (hidePalette) {
		pal.style.display = "none"
		document.onclick = ""
		hidePalette = false
	} else {
		hidePalette = true
	}
}

var PaletteObj = function(target, inputname, buildingSkin) {
	this.targetObj = $(target)
	this.previewObj = $$('colorPreview')
	this.inputName = $(inputname)

	this.updateColor = function(rgb) {
		this.previewObj.style.backgroundColor = rgb
	}

	this.pickedColor = function(rgb) {
		//this.targetObj.style.background = ''
		//this.targetObj.style.backgroundColor = rgb
		pal.style.display = "none"

		this.inputName.value = fromRgb(rgb)

		if(buildingSkin){
			$('thmColor').style.backgroundColor = rgb
			update_c_skinstyle(fromRgb(rgb));
		} else {
			readSettingsControl()
		}
	}

	this.setTransparent = function() {
		pal.style.display = "none"
		this.inputName.value = -1
		readSettingsControl()
	}
}

var update_c_skinstyle = function(colorvalue) {
	var current_source = $('skinImage2').src;
	var rExp = /c[0-9]+:/gi;
	if (current_source.match(rExp)) {
		$('skinImage2').src = current_source.replace(rExp, 'c' + colorvalue + ':');
	}
}

var update_c_skintext = function(originalskinurl, text, colorvalue) {
	text=text.replace(':','');
	var rExp = /c[0-9]+:/gi;
	if (originalskinurl.match(rExp)) {
		originalskinurl = originalskinurl.replace(rExp, 'c' + colorvalue + ':');
	}
	var withouttextlength = originalskinurl.length - $('originalbordertext').value.length;
	$('skinImage2').src = originalskinurl.substr(0, withouttextlength) + text;
}

var fromRgb = function(rgb) {
	if (rgb.substr && (rgb.substr(0,3) == "rgb")) {
		var rgbvalues = rgb.substr(4, (rgb.length - 5)).split(',')
		return (0x10000 * Number(rgbvalues[0])) + (0x100 * Number(rgbvalues[1])) + Number(rgbvalues[2])
	}
	return rgb;
}

var padHex = function(n) {
	return (n.length == 1 ? "0" + n : n)
}

var hD="0123456789ABCDEF";
var d2h = function(d) {
	var h = hD.substr(d&15,1);
	while(d > 15) {d >>= 4;h = hD.substr(d&15,1) + h;}
	return h;
}

var fillColorPalette = function() {
	paletteExists = true
	var cpContainer = $$('colorPalette')
	var cpTable = createElement(cpContainer, "table")
	cpTable.cellSpacing = '0'
	cpTable.cellPadding = '0'
	var cpTableBody = createElement(cpTable, "tbody")

	cpTable.style.border = "1px solid #ccc"

	var mynumbers = new Array(0,5,10,16)

	var gpTable = createElement(cpContainer, "table")
	gpTable.cellSpacing = '0'
	gpTable.cellPadding = '0'
	gpTable.style.marginTop = '3px'
	var gpTableBody = createElement(gpTable, "tbody")
	var gpRow = createElement(gpTableBody, "tr")
	var gpTd1 = createElement(gpRow, "td")
	var gpTd2 = createElement(gpRow, "td")

	var prevBlock = createElement(gpTd2, "div")
	prevBlock.id = "colorPreview"
	prevBlock.style.border = "1px solid #ccc"
	prevBlock.style.height = "20px"
	prevBlock.style.width = "40px"
	prevBlock.style.margin = "0 0 0 54px"

	/* Colors */
	for (j = 1; j <= 15; j++) {
		var cpRow = createElement(cpTableBody, "tr")
		for (i = 0; i < mynumbers.length; i++) {
			for (k = 2; k <= 16; k+=2) {
				var cell = createElement(cpRow, "td")
				var clink = createElement(cell, "a")
				clink.style.display = "block"
				clink.style.backgroundColor = rgbOf(parseInt(mynumbers[i]), j, k)

				/* this is a hack to remove a color from our palette
				** that in the database is being treated as a default color
				**
				** colors that must be avoided
				**        -1 |  Transparent | used to indicate tranparent background
				**  11197951 |  Light Blue  | config default for facebook slideshows
				**  16750899 |  Orange      | database default for hover color column
				**  16776960 |  Yellow      | config default for normal slideshows
				**         0 |  Black       | default
				*/
				if ( i == 2 && j == 13 && k == 16) {
					clink.style.backgroundColor = "rgb(170, 222, 255)"
				}

				clink.style.height = "8px"
				clink.style.width = "8px"
				clink.style.fontSize = "1px"
				clink.style.lineHeight = "1px"
				clink.onmouseover = function() { palette.updateColor(this.style.backgroundColor) }
				clink.onclick = function() { palette.pickedColor(this.style.backgroundColor) }
			}
		}
	}

	/* Grey */
	var cpTable2 = createElement(gpTd1, "table")
	cpTable2.style.border = "1px solid #ccc"
	cpTable2.cellSpacing = '0';
	cpTable2.cellPadding = '0';
	var cpTableBody2 = createElement(cpTable2, "tbody");
	var cpRow2 = createElement(cpTableBody2, "tr")
	for (i = 0; i < 16; i++) {
		var cell = createElement(cpRow2, "td")
		var clink = createElement(cell, "a")
		clink.style.display = "block"
		clink.style.backgroundColor = rgbOf(i, i, (!i) ? 1 : i)
		clink.style.height = "10px"
		clink.style.width = "10px"
		clink.style.fontSize = "1px"
		clink.style.lineHeight = "1px"
		clink.onmouseover = function() { palette.updateColor(this.style.backgroundColor) }
		clink.onclick = function() { palette.pickedColor(this.style.backgroundColor) }
	}

	/* Transparent */
	var cpTrans = createElement(gpTd1, "a")
	cpTrans.id = "paletteTransparency"
	cpTrans.style.display = "none"
	cpTrans.style.fontSize = "8pt"
	cpTrans.style.textDecoration = "underline"
	cpTrans.style.cursor = "pointer"
	createText(cpTrans, "Transparent")
	cpTrans.onmouseover = function() { palette.updateColor(rgbOf(15, 15, 15)) }
	cpTrans.onclick = function() { palette.pickedColor(rgbOf(15, 15, 15)); palette.setTransparent() }
}

var rgbOf = function(r, g, b) {
	return "rgb(" + (17 * r) +  "," + (17 * g) + "," + (17 * b) + ")"
}

var d2rgb = function (n) {
	var rgbn = "rgb(" + ((n & 0xFF0000) >> 16) + "," + ((n & 0xFF00) >> 8) + "," + (n & 0xFF) + ")"
	return rgbn
}
// end colorpicker
// flash loading
var writeFlash = function(url, objId, width, height) {
	var fl = '<embed swliveconnect="true" allowScriptAccess="always" src="' + url
		+ '" quality="high" bgcolor="transparent" width="' + width + '" height="' + height + '" align="middle" wmode="transparent"'
		+ '" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"/>';
	$(objId).innerHTML = fl
}

// end flash loading
ieAttrBug = / data[a-zA-Z]+="null"/g
var performedChanges = 0
var addedItems = false;
var lastColors = 0
var lastState = new Array()

var defaultCaptionMsg = cl.Arrange.Enter_Photo_Cap
var localID = 0
var Items = []
var Ticker = {}
var currentPxcid = '';
var hasPxciid = false;
var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
var numbers = "0123456789"
var name_chars = letters + numbers + " @-+:'&!*,.;";

// Regular Expressions
var cookieRE = /(arrange_etag(.[^=]+))=/;
var imageshackRE = new RegExp("^(http|https)://.*imageshack.us/.*")
var myspaceRE = new RegExp("^(http|https)://.*myspace.com/?.*")
var photobucketRE = new RegExp("^(http|https)://.*photobucket.com/.*")
var yahooRE = new RegExp("^(http|https)://.*yahoo.com/.*")
var flickrRE = new RegExp("^(http|https)://.*flickr.com/.*")
var rockyouRE = new RegExp("^(http|https)://.*rockyou.com/.*")
var wretchUserRE = new RegExp("^[A-Za-z0-9]+$")
var wretchRE = new RegExp("^http?://.*wretch.cc/[a-z]+/([A-Za-z0-9]+)$")
var friendsterRE = new RegExp("^(http|https)://.*friendster.com/.*")
var youtubeRE = new RegExp("^http://.*youtube.com/watch\\?v=.*?$")
var youtubeprofileRE = new RegExp("^http://.*youtube.com/profile\\?user=.*?$")
var youtubegroupRE = new RegExp("^http://.*youtube.com/group")
var myspacevideoRE = new RegExp("^http://vids.myspace.com/.*")
var tagged_url_with_authRE = new RegExp("^tagged:.*")
var genericRE = new RegExp("^(http|https):\\/\\/.*\\.([^/]+\\.[A-Za-z]{2,4})(\\/.*)?/")
var urlRE = /^https?:\/\/[a-z0-9-.]+\.[a-z]{2,4}\/.+/i

var minSizeValue = 75

// seems like they ran out of ideas on how to encode an ampersand to get
// it into a flash thru the flashvars.  The swf decodes on the other end.
// Wont work for urls so make sure to encodeURI() beforehand.
// jerobi said this is pretty old.
var jerobiEscape = function(s) {
    return s.replace(ieAttrBug, '').replace(/&/g, '-|-|-');
}

var getSkinUrl = function(skid) {
	return "http://"+widget_domain+"/skin/"+skininfo_version+"/"+skid+"/info";
}

var getSiteUrl = function() {
	return widget_domain;
}

// see also version in pic_arrange
var notifyFlash = function() {

	performedChanges++
	var tickerdiv = $$("tickerdiv");

	if (tickerdiv) {
		tickerdiv.style.height = (parseInt(Ticker.height) + 10) + "px"

		var cform = $('custform')
		cform.width.value = Ticker.width
		cform.height.value = Ticker.height

		if (Ticker.transition > 0) {
			$$('slidesize').style.display = "none"; $$('transsize').style.display = "block";
		} else {
			$$('slidesize').style.display = "block"; $$('transsize').style.display = "none";
		}

		var _newSong = 0
		if (typeof(newSong) != 'undefined' && newSong) {
			_newSong = 1
			// reset the flag
			newSong = false
		}

		var flashvars = GetDefaultFlashVars() + Ticker.transition;

		if (Items.length != 0) {
			fv_map = GetMapFlashVar();
			flashvars = 'arrange=true&s=1&internal=1&connect=' + getConnectorID() + '&map=' + fv_map + '&help_url=' + help_url + '&myConfig=' + jerobiEscape(getStandardTickerXML()) + '&myItems=' + jerobiEscape(itemsAsXML());
		} else {
			flashvars += '&mySongs=' + jerobiEscape(repr(readSongInfo()))
		}

		var ih = '<embed swliveconnect="true" allowScriptAccess="always" id="aticker" name="aticker" src="' + GetSWFFile()
			+ '" quality="high" width="' + Ticker.width + '" height="' + Ticker.height + '" align="middle" wmode="transparent" flashvars="'
			+ flashvars
			+ '&th='
			+ cform.theme.value
			+ '&thc='
			+ cform.themeColor.value
			+ '&ft='
			+ cform.font.value
			+ '&tfx='
			+ cform.textFX.value
			+ '&chc='
			+ cform.chromeColor.value
			+ '&sc='
			+ cform.stageColor.value
			+ '&fx='
			+ cform.effects.value
			+ '&sk='
			+ cform.skin.value
			+ '&sp='
			+ cform.speed.value
			+ '&ns='
			+ _newSong
			+ '&scarcity='
			+ cform.scarcity.value
			+ '" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"/>';
		tickerdiv.innerHTML = ih;
	}

	updateColors()
}

var updateColors = function() {
	newColors = Ticker.textColor + Ticker.backgroundColor
	if (lastColors != newColors) setAllCaptionsColor()
	lastColors = newColors
}

var doScrape = function(source, url, done, username, password, auth) {
	url = strtrim(url);
	done = done || standardScrapeResult;
	var parms = { action : 'scrape',
				  url : url,
				  source : source || '',
				  auth : auth || ''};
	if (username) {
		parms['username'] = username;
		parms['password'] = password;
	}
	asyncAction('scrapeajax',
				parms ,
				function(ans) {
					if (ans.substring(0, 4) == "PASS" ) {
						var newItems = evalJSON(ans.substring(4))
						if (newItems.length > 0) {
							addArrangeItems(newItems)
						} else {
							alert(cl.Arrange.This_Set_has_No_Photos);
							cancelAlbums(source);
						}
					}
					done(ans, url);
				});
	return false;
}

var nextLocalID = function() {
	return localID++;
}

var showChannelItems = function () {
	$$('gridandbuttonarea').style.display = Items.length > 0 ? 'block' : 'none';
	$$('edit_photos_link').style.display = Items.length > 0 ? 'inline' : 'none';
	var presetSaveCtrl = $$('presetSave');
	if (presetSaveCtrl){
		presetSaveCtrl.style.display = Items.length > 0 ? 'block' : 'none' // save button under the presets
	}
	var shuffleControlCtrl = $$('shuffleControl');
	if (shuffleControlCtrl){
		shuffleControlCtrl.style.visibility = Items.length > 0 ? 'visible' : 'hidden'
	}
}

var isChannelChanged = function () {
	return Items.length > 0;
};

var numberAllItems = function() {
	for (var i=0; i<Items.length;i++) {
		var nitem = Items[i];
		nitem.local_id = nextLocalID();
	}
}

var drawAllItems = function() {
	for (var i=0; i<Items.length;i++) {
		var nitem = Items[i];
		drawArrangeItem(nitem, i);
	}
}

// this function is redefined... Everywhere.  Go grep in templates.
// this incarnation happens to run for arrange (ss)
var addArrangeItems = function(nitems, suppressNotification, callback) {
	var errorItems = [];
	var count = 0;
	for (var i=0; i<nitems.length;i++) {
		var nitem = nitems[i];
		if (!nitem.error_status) {
			nitem.item_img_url = nitem.item_img_url || nitem.img_url;
			nitem.local_id = nextLocalID();
			drawArrangeItem(nitem, Items.length);
			Items.push(nitem);
			count++;
		} else {
			errorItems.push(nitem);
		}
	}

	if (typeof(tagger) != 'undefined') {
	    tagger.check(Items, count);
		suppressNotification = true;
	}

	if (!suppressNotification) {
		var frm = $('arrangeArea')
		if (errorItems.length > 0) {
			showError(frm, -200, 5, makeUploadErrorString(errorItems));
		} else if (nitems.length == 1) {
			ShowUpdate(frm, -200, 5, cl.Arrange.One_Item_Added);
		} else if (nitems.length > 1) {
			// internationalization glitch
			ShowUpdate(frm, -200, 5, nitems.length + cl.Arrange.Many_Items_Added);
		}
	}

	setArrangeList();

	var list = $('grid');
	dragsort.makeListSortable(list, saveOrder);
	lastState = junkdrawer.serializeList(list);
	if (typeof(logUpload) != 'undefined') logUpload()
	if ($('uploadCallout')) {
		$('uploadCallout').style.display = 'none'
	}
	if (callback) {
		setTimeout(function() { callback(); }, 500)
	}
}

var makeUploadErrorString = function(errorItems) {
	var nitem;
	var result = "";
	var errorTypes = new Object();
	if (errorItems.length == 1) {
		nitem = errorItems[0];
		result = cl.Arrange.Upload_Error_Reasons[nitem.error_status] + nitem.filename;
	} else {
		result += errorItems.length + cl.Arrange.Upload_Error_Many_Items + "<br />";
		for (var i in errorItems) {
			nitem = errorItems[i];
			if (errorTypes[nitem.error_status]) {
				errorTypes[nitem.error_status].push(nitem.filename);
			} else {
				errorTypes[nitem.error_status] = new Array(nitem.filename);
			}
		}

		for (var type in errorTypes) {
			result += cl.Arrange.Upload_Error_Reasons[type] + errorTypes[type].join(", ") + "<br />";
		}
	}

	return result;
}

var photobucket_complete = function(inurl) {
	addArrangeItems([{ description:"",
					   url:inurl, img_url:inurl,
					   item_img_url:inurl,
					   source : "photobucket"
	}]);
}

var rollList = function(iid0, iid1) {
	setTimeout(function() {
		rollItems(iid0, iid1);
		setArrangeList(false, true);}, 0);
	return false;
}

var itemIdToNodeId = function(itemId) {
	return "chdiv_" + itemId;
}

var itemIdToTxtNodeId = function(itemId) {
	return "txtnode_" + itemId;
};

var nodeIdToItemId = function(nodeId) {
	return Number(nodeId.substring(6));
}

var deleteItem = function(itemId) {
	var gridChild = $(itemIdToNodeId(itemId));
	var grid = gridChild.parentNode;
	grid.removeChild(gridChild);
	updateTabindex(grid, itemId)
	exciseItem(itemId);
	setArrangeList();
	return false;
}

var rollItems = function(iid0, iid1) {
	Items = rollEntry(Items, indexOfItem(iid0), indexOfItem(iid1));
}

var exciseItem = function(itemId) {
	Items = exciseEntry(Items, indexOfItem(itemId));
}

var itemsAsXML = function() {
	var pl = ARRAY();
	for (var i in Items) {
		var nitem = Items[i];
		pl.children.push(DICT(KEY("detail_url"), URLSTRING(nitem.url),
						 KEY("target_url"), URLSTRING(nitem.url),
						 KEY("uid"), INTEGER(i),
						 KEY("id"), STRING((nitem.id && nitem.id.toString()) || '0'),
						 KEY("media_url"), URLSTRING(nitem.url),
						 KEY("item_img_url"), URLSTRING(nitem.item_img_url),
						 KEY("filename"), STRING(nitem.filename),
						 KEY("content_type"), STRING(nitem.content_type),
						 KEY("description"), STRING(nitem.description)));

	};
	pl = DICT(KEY("items"), pl);
	return repr(pl);
}

var tickerAsXML = function(globalconf) {
	var pl = DICT(
		KEY("friend_url"), STRING(Ticker.friend_url),
		KEY("textSize"), INTEGER(Ticker.textSize),
		KEY("ticker_id"), INTEGER(Ticker.ticker_id),
		KEY("transition"), INTEGER(Ticker.transition),
		KEY("theme"), INTEGER(Ticker.theme),
		KEY("themeColor"), INTEGER(Ticker.themeColor),
		KEY("height"), INTEGER(Ticker.height),
		KEY("width"), INTEGER(Ticker.width),
		KEY("backgroundColor"), INTEGER(Ticker.backgroundColor),
		KEY("stageColor"), INTEGER(Ticker.stageColor),
		KEY("chromeColor"), INTEGER(Ticker.chromeColor),
		KEY("hoverColor"), INTEGER(Ticker.hoverColor),
		KEY("textColor"), INTEGER(Ticker.textColor),
		KEY("speed"), INTEGER(Ticker.speed),
		KEY("shuffle"), INTEGER(Ticker.shuffle),
		KEY("befriend_url"), STRING(Ticker.befriend_url),
		KEY("backup_show"), INTEGER(globalconf.backup_show),
		KEY("ad_click"), STRING(globalconf.ad_click),
		KEY("ad_align"), STRING(globalconf.ad_align),
		KEY("ad_type"), INTEGER(globalconf.ad_type),
		KEY('font'), INTEGER(Ticker.font),
		KEY('textFX'), INTEGER(Ticker.textFX),
		KEY("skin"), STRING(Ticker.skin),
		KEY('soundFX'), INTEGER(Ticker.soundFX),
		KEY('channel_name'), STRING(Ticker.channel_name),
		KEY('filter'), INTEGER(Ticker.effect),
		KEY('effects'), INTEGER(Ticker.effects),
		KEY('songs'), readSongInfo());
	return repr(pl);
}

var exciseEntry = function(s, n) {
	if ((n < 0) || (n >= s.length)) {
		return s;
	}
	return s.slice(0,n).concat(s.slice(n+1));
}

var insertEntry = function(s, e, n) {
    e = [ e ];
    if (n <= 0) {
	    return e.concat(s);
    }
    if (n >= s.length) {
	    return s.concat(e);
    }
	return s.slice(0,n).concat(e).concat(s.slice(n));
}


var rollEntry = function(s, a, b) {
   var e = s[b];
   s = exciseEntry(s, b);
   return insertEntry(s, e, a);
}

var setArrangeList = function(suppressFlashUpdate, suppressDnD) {
	var list = $('grid');
	if (!suppressDnD) {
		dragsort.makeListSortable(list, saveOrder);
		lastState = junkdrawer.serializeList(list);
	}
	writeArrangeStorageArea();
	if (!suppressFlashUpdate) {
		setTimeout(notifyFlash, 30);
	}
	showChannelItems();
}

var writeArrangeStorageArea = function() {
	$$('storageArea').value = serializeJSON({ pxcid : currentPxcid,
												 ticker : Ticker,
												 items : Items } );
}

var updateSaveButtons = function(fcn) {
	var saveButtons = ['donetop','donebot','donepre'];

	for (i = 0; i < saveButtons.length; i++) {
		var button=$(saveButtons[i])
		if (button) {
			fcn(button)
		}
	}
};

var curRgb = 143
var rgbDown = true
var savingFeedback = function(btn) {
	btn.innerHTML = "<strong>" + cl.Arrange.Saving + "</strong>";

	// switch between pulsing increments/decrements between 50/250
	if (curRgb < 50 && rgbDown) {
		rgbDown = false
	} else if (curRgb > 250 && !rgbDown) {
		rgbDown = true
	}
	curRgb += rgbDown ? -1 : 1

	btn.style.backgroundColor = 'rgb(255,' + curRgb + ',0)'
	btn.disabled = true;
};

var enableButton = function(btn) {
	btn.innerHTML = "<strong>" + cl.Arrange.SAVE + "</strong>";
	btn.style.backgroundColor = "#008f00";
	btn.style.color = "#ffffff";
	btn.disabled = false;
	btn.style.display = "block";
};


var buttonBlinker = 0;
var enableSaveButtons = function() {
	if (buttonBlinker) {
		clearInterval(buttonBlinker);
		buttonBlinker = 0;
	}
	updateSaveButtons(enableButton);
};

var disableSaveButtons =  function() {
	f = function() { updateSaveButtons(savingFeedback) };
	f();
	if (!buttonBlinker) {
		buttonBlinker = setInterval(f, 50);
	}
};

// TODO: {parse,make}_query_string should move into basics.js, but,
// for speed reasons, the arrange page does not include basics.js.
// Look toward the glorious future of static generation!
var parse_query_string = function(query) {
    if ((query.charAt(0) == '?') || (query.charAt(0) == '#')) {
	    query = query.substring(1);
	}
	query = query.split("&");
	var rv = {};
	for (var i=0; i<query.length; i++) {
	    var a = query[i].split("=");
		if (a.length == 2) {
		    rv[a[0]] = a[1];
		}
	}
	return rv;
};

var make_query_string = function(parms) {
    var query = [];
	for (var key in parms) {
	    query.push( key + "=" + parms[key]);
	}
	if (query.length) {
	    return "?" + query.join("&");
	}
	return "";
};

var premium_skins = {};
var doSubmitArrangedChannel = function(oldPxcid, channel_type, basefrm, destination, additional_parms, parent) {
	disableSaveButtons();
	updateName();

	clearArrangeEtagCookie();

	this.has_premium = (Ticker.transition in premium_styles)
	this.premium_skin = 0;
	if (Ticker.skin in premium_skins) {
		this.premium_skin = Ticker.skin;
	}

	var frm = {
		"xaction" : "arrange",
		"textSize" : Ticker.textSize || 0,
		"transition" : Ticker.transition || 0,
		"theme" : Ticker.theme || 0,
		"themeColor" : Ticker.themeColor || 0,
		"height" : Ticker.height || 0,
		"width" : Ticker.width || 0,
		"backgroundColor" : Ticker.backgroundColor || 0,
		"stageColor" : Ticker.stageColor || 0,
		"effects" : Ticker.effects || 0,
		"chromeColor" : Ticker.chromeColor || 0,
		"hoverColor" : Ticker.hoverColor || 0,
		"textColor" : Ticker.textColor || 0,
		"speed" : Ticker.speed || 0,
		"shuffle" : Ticker.shuffle,
		"friend_url" : Ticker.friend_url  || '',
		"befriend_url" : Ticker.befriend_url || '',
		"font" : Ticker.font || 0,
		"textFX" : Ticker.textFX || 0,
		"soundFX" : Ticker.soundFX || 0,
		"skin" : Ticker.skin || 0,
		"pxcid" : oldPxcid || '',
		"channel_name" : ($$("custform").channel_name && $$("custform").channel_name.value) || '',
		"description" : ($$("custform").slidedescription && $$("custform").slidedescription.value) || '',
		"channel_type" : channel_type,
		"privacy" : Ticker.privacy,
		"publish" : Ticker.publish,
		"notifyfans" : $$("notifyfans").value,
		"receipt" : self.receipt || ""
	};

	if (!oldPxcid) {
		this.is_new_channel = true
	}

	if(typeof(readStickerStorage) == 'function'){
		var stickers = readStickerStorage()
		if (stickers.length) {
			// Cancel auto play if video is added
			if (stickers[0]['media_type'] == "1") {
				stickers[0]['data'] = "false"
			}
		}
		frm["stickers"] = serializeJSON(stickers);
	}

	for (var i in Items) {
		var nitem = Items[i];

		frm["ciid_" + i] = nitem.id || 0;
		frm["old_sequence_id_" + i] =  nitem.sequence_id || 0;
		frm["url_" + i] =  !nitem.id && nitem.url || "" ;
		frm["img_url_changed_" + i] = (nitem.img_url_changed && 1) || 0;
		frm["img_url_" + i] =  (!nitem.id || nitem.img_url_changed) && nitem.img_url || "";
		frm["filename_" + i] =  !nitem.id && nitem.filename || "";
		frm["content_type_" + i] =  !nitem.id && nitem.content_type || "";
		frm["desc_changed_" + i] =  (nitem.desc_changed && 1) || 0;
		frm["description_" + i] = (!nitem.id || nitem.desc_changed) && nitem.description || "";
		frm["source_" + i] =  nitem.source || "";
	}

	asyncAction(
		'channelajax',
		frm,
		function(ans) {
			if (ans.substring(0, 4) == "PASS" ) {
				var parms = parse_query_string(window.location.search);
				parms.pxcid=ans.substring(5);
				parms.notifyfans= $$("notifyfans").value;
				// the nc parameter is checked in mscd for channel newness
				if (this.is_new_channel) {
					parms.nc = "1"
				}
				// the ps parameter means that a premium style was applied
				if (this.has_premium) {
					parms.ps = "1"
				}
				if (this.premium_skin > 0) {
					parms.premium_skin = this.premium_skin
				}

				parms.bnc="bnc";
				if (additional_parms) {
					for (var key in additional_parms) {
						parms[key] = additional_parms[key];
					}
				}
				if (!destination) {
					window.location = add_to_url("/arrange",  parms)
				} else if (oldPxcid) {
					destination = secure_check(destination);
					if (parent) {
						window.parent.location = add_to_url(destination, parms)
					} else {
						window.location = add_to_url(destination,  parms)
					}
				} else  {
					destination = secure_check(destination);
					if (destination.match('slide.com/lmf_')){
						bounceArrange(add_to_url("/lmf_arrange", parms),
								  add_to_url(destination, parms),
								  parent);
					} else {
						bounceArrange(add_to_url("/arrange", parms),
								  add_to_url(destination, parms),
								  parent);
					}
				}
			}
		}
	);
	return false;
}

var add_to_url = function(url, parms) {
    var url = url.split("?");
    var oldparms = parms;
    if (url[1]) {
	    oldparms = parse_query_string(url[1]);
	    updateDict(oldparms, parms);
    }
    return url[0] + make_query_string(oldparms);
}

var updateDict = function(d, s) {
   for (var k in s) {
       d[k] = s[k];
   }
};

var premium_styles = {}
var premium_effects = {}

var submitArrangedChannel = function(oldPxcid, channel_type, basefrm, destination, additional_parms, parent, premium_destination) {
	try {
		if (Ticker.transition in premium_styles) {
			if (premium_destination) {
				destination = premium_destination
			}
			logPremiumSave()
		}

		if (Ticker.skin in premium_skins) {
			if (premium_destination) {
				destination = premium_destination
			}
		}else if( do_offer_opening_credits ){
			destination = GLOBAL_HACKS['credits_destination'];
		}

		return doSubmitArrangedChannel(oldPxcid, channel_type, basefrm, destination, additional_parms, parent);
	} catch(e) {
		enableSaveButtons();
		alert("Problem submitting Slide Show: " + e.message + "\nIf this problem persists, please contact Slide Customer Support at feedback@slide.com");
	}
	return false;
};

var secure_domain = 'https://secure.slide.com'

var secure_check = function(destination) {
	if(destination.match(/^premium/) != null) {
		destination = secure_domain+'/'+destination;
	};
	return destination;
}

var bounceArrange = function(interimDestination, finalDestination, parent) {
	document.cookie = "arrangejump." + base_base_domain + "=" + finalDestination;
	if (parent) {
		window.parent.location.replace(interimDestination);
	} else {
		window.location.replace(interimDestination);
	}
}

var clearArrangeEtagCookie = function() {
	var s = String(document.cookie);
	var ck;
	while (ck = cookieRE.exec(s)) {
		document.cookie=ck[1] + "=;domain=" + ck[2];
		s=s.substring(ck.index+ck[1].length);
	}
}

var checkFinalDestination = function() {
	var ck = RegExp("arrangejump\\." + base_base_domain + "=([^;]+)").exec(document.cookie);
	if (ck) {
		addLoadEvent(setTimeout(function () {
			document.cookie = "arrangejump." + base_base_domain + "=";
			resetActionCookie(12, 126);
			window.location = ck[1];
		}, 0));
		return true;
	}
	return false;
}

var resetActionCookie = function(viewID, actionID) {
	var ck = /action(\.[^=;]+)(=?[^;]*)/.exec(document.cookie);
	if (ck) {
		document.cookie = "action" + ck[1] + "=" + viewID + "|" + actionID + ";domain=" + ck[1] + ";path=/";
	}
}

var checkAutoscrape = function() {
	var ck = /arrangescrape(\.[^=]+)=([^;]+)/.exec(document.cookie);
	if (ck && ck[2] != 'none') {
		addLoadEvent(function () {
			// setting the value to none because for some reason IE clears the = while firefox does not
			document.cookie = "arrangescrape" + ck[1] + "=none;domain=" + ck[1];
			url = unescape(ck[2]);
			comm = getScrapeType(url).toLowerCase();
			doScrapeAll(comm,
				url,
				null,
				null,
				true);
		});
		return true;
	}
	return false;
}

var checkPartnerScrape = function() {
	var ck = /partnerscrape(\.[^=]+)=([^;]+)/.exec(document.cookie);
	if (ck && ck[2] != 'none') {
		addLoadEvent(function () {
			// setting the value to none because for some reason IE clears the = while firefox does not
			document.cookie = "partnerscrape" + ck[1] + "=none;domain=" + ck[1];
			url = unescape(ck[2]);
			doScrape(	'partner',
							url,
							function(){},
							'',
							'',
							'');
		});
		return true;
	}
	return false;
}

var checkBeboAuth = function() {
	var ck = /beboscrape(\.[^=]+)=([^;]+)/.exec(document.cookie);
	var frm = $('beboform');
	if (ck && ck[2] != 'none') {
		addLoadEvent(function () {
			// setting the value to none because for some reason IE clears the = while firefox does not
			document.cookie = "beboscrape" + ck[1] + "=none;domain=" + ck[1];
			var pieces = ck[2].split('|');
			frm.auth.value = pieces[0];
			submitbebo(frm, beboAutoScrapeResult );
			if (pieces[1]) {
				doScrape(	'bebo',
							unescape(pieces[1]),
							function(){},
							'',
							'',
							frm.auth.value);
			}
		});
		return true;
	}
	return false;
}

var readStorageArea = function(pxcid, dbItems, dbTicker) {
	var v = $$('storageArea').value;
	Items = dbItems;
	Ticker = dbTicker;
	currentPxcid = pxcid || "";
	if (v) {
		var dir = evalJSON(v);
		if (dir.pxcid == currentPxcid) {
			if (dir.items) {
				Items = dir.items;
			}
			if (dir.ticker) {
				Ticker = dir.ticker;
			}
		}
	}
	writeArrangeStorageArea();
}

var resetArrange = function() {
	$$('storageArea').value = "";
}

var saveOrder =  function(item) {
	var group = item.toolManDragGroup;
	var list = group.element.parentNode;
	var id = list.getAttribute("id");
	if (id == null) return;
	group.register('dragstart', function() {
		try {
			$$('captionEditField').blur();
		} catch(e) {}
	});
	group.register('dragend', function() {

		var fid = updateTabindex(list, item.id);

		if (fid != '') rollList(nodeIdToItemId(fid),
								nodeIdToItemId(item.id));
	});
}

var updateTabindex = function(list, id) {
	var lid = '';
	var pid = '';
	var fid = '';
	var foundItem = false;

	var currentState = junkdrawer.serializeList(list);

	for (i = 0; i < lastState.length; i++) {
		if (lastState[i] != currentState[i]) {
			lid = currentState[i];

			if (!foundItem) {
				if (lid == id && pid == '') {
					fid = currentState[i + 1]
					foundItem = true
				} else if (lid == id && pid != '') {
					fid = pid
					foundItem = true
				}
			}
			if(lid) {
				setTabIndex($('desc' + lid.substring(6)), i)
			}
			pid = lid
		}
	}
	lastState = currentState;

	return fid;
}

var getTabIndex = function(obj) {
	return (document.all) ? obj.tabindex : obj.tabIndex
}

var setTabIndex = function(obj, value) {
	value = value + 1	// tabindex of 0 is not accessible in some browsers
	if (document.all) {
		obj.tabindex = value
	} else {
		obj.tabIndex = value
	}
}

var elementPos = function(iid) {
	for (var i = 0; i < Items.length; i++) {
		if (Items[i].local_id == iid) return i
	}
}

var getNthInputElement = function(i) {
	if (Items[i]) return $('desc' + Items[i].local_id);
}

var autoTab = function(e, inp, iid) {
	if (document.all) e = window.event

	var keyPressed = getkey(e)
	if (keyPressed == 13) {
		$$('captionEditField').blur()
		return false;
	} else if (keyPressed == 9) {
		$$('captionEditField').blur()
		currentIndex = elementPos(iid)
		nextItem = getNthInputElement(currentIndex + 1)
		if (nextItem) {
			// using settimeout to make sure this executes after the previous chunk of code
			setTimeout(function() {
				drawEditCaption(nextItem, Number(nextItem.id.substring(4)))
				}, 0)
		}
		return false;
	}
}

var indexOfItem = function(itemId) {
	for (var n in Items) {
		if (Items[n].local_id == itemId) {
			return Number(n);
		}
	}
	return -1;
}

var isSafari = function() {
	return navigator.userAgent.indexOf('WebKit') != -1
}

// refreshes ticker to reflect changes
var updateTicker = function() {
	var tw = $$('tickerWrapper')
		var html = tw.innerHTML
		tw.innerHTML = ''
		tw.innerHTML = html
		return false;
}

var deleteAllCaptions = function() {
	for(var i in Items) {
		var nitem = Items[i];
		if (nitem.img_url) {
			var caption = getNthInputElement(i);
			caption.value = ''
			caption.innerHTML = ''
			if (nitem.description) {
				nitem.description = "";
				nitem.desc_changed = true;
			}
			setAppearance(caption);
		}
	}
	readSettingsControl()
	return false;
}

var highlightCaption = function(caption) {
	caption.style.backgroundColor = '#87c0e3'
	caption.style.color = '#fff'
}

var setCaptionColor = function(caption) {
	if (caption) {
		caption.style.color = (Ticker.textColor >= 0) ? d2rgb(Ticker.textColor) : '#fff'
		caption.style.backgroundColor = (Ticker.backgroundColor >= 0) ? d2rgb(Ticker.backgroundColor) : '#000'
	}
}

var setAllCaptionsColor = function() {
	for(var i in Items) {
		setCaptionColor(getNthInputElement(i));
		var textNode = $(itemIdToTxtNodeId(Items[i].local_id));
		if (textNode) {
			setCaptionColor(textNode.parentNode);
		}
	}
}

var updateDescriptionElement = function(description, iid) {
	var element_id = 'desc'+iid;
	var caption = getObject(element_id);
	caption.value = description;
	caption.innerHTML = description;
	updateDescription(caption, iid);
}

var updateDescription = function(caption, iid) {
	desc = caption.value;
	setAppearance(caption);

	// if the description is the same as before leave
	// otherwise update the description for next time
	var i = indexOfItem(iid);
	if (i >= 0){
		var nitem = Items[i];
		nitem.desc_changed |= (nitem.description != desc);
		if (nitem.description != desc) {
			nitem.description = desc;
			readSettingsControl();
			if (!nitem.img_url) {
				var txt_id = itemIdToTxtNodeId(nitem.local_id);
				replaceChildNodes($(txt_id), desc);
				$(txt_id).style.fontSize = "12px";
				fillTextBlock(txt_id);
			}
			return true;
		}
	}
	return false;
}

var drawEditCaption = function(caption, iid) {
	var ce = $$('captionEditField')
	ce.blur()
	var captionX = findPosX(caption)
	var captionY = findPosY(caption)
	ce.style.left = captionX + 'px'
	ce.style.top = (captionY + (isSafari() ? 5 : 0)) + 'px'
	ce.style.display = 'block'
	ce.value = (caption.innerHTML == defaultCaptionMsg) ? '' : caption.innerHTML
	ce.focus()
	ce.select()
	ce.onblur = function() {
			ce.onblur = ''
			caption.value = ce.value.substr(0,255) // upper limit for caption length is 255
			caption.innerHTML = caption.value
			ce.style.display = 'none'
			updateDescription(caption, iid)
		}
	ce.onkeydown = function(e) {
			return autoTab(e, caption, iid)
		}
}

var drawArrangeItem = function(nitem, tabindex) {
	addedItems = true;
	var input_attributes = {
		rows : 2,
		cols : 20,
		id : "desc" + nitem.local_id,
		onclick : "drawEditCaption(this, " + nitem.local_id + ")" ,
		onfocus : "drawEditCaption(this, " + nitem.local_id + ")" ,
		readonly : "true" ,
		maxlength : 255,
		onmouseover : "highlightCaption(this)",
		onmouseout : "setCaptionColor(this)"
	};

	var delete_element;
	var illustration;
	appendChildNodes(
		$$('grid'),
		LI({ id : itemIdToNodeId(nitem.local_id) },
		   TABLE({ "class" : "gridDelTable", cellspacing : "0", style : "position: absolute; z-index: 999; width: 110px !important; width: 112px; margin: 2px 0 0 0 !important; margin: 0;", align : "center" },
				 TBODY(null,
					   TR(null,
						  TD({ "class" : "gridDelTableData" },
							 A({ href : "#",
									 "class" : "arrangeDel",
									 onclick : "return confirm('" + cl.Arrange.Confirm_Delete_Picture + "') && deleteItem(" + nitem.local_id + ")" },
							   delete_element = IMG({alt : "delete", title : "delete image" } )))))),
		   DIV({ "class" : "pic drag drop" },
			   DIV({ "class" : "gridImg",
						 style : "width: 100px; height: 100px; overflow: hidden;" },
				   TABLE({ cellspacing : "0", cellpadding : "0", border : "0", width : "100", height : "100", style : "background-color: #fff;" },
						 TBODY(null,
							   TR(null,
								  illustration = TD({ align : "center", valign : "middle" }))))),
			   DIV({ "class" : "captionDiv" },
				   input_element = TEXTAREA(input_attributes, nitem.description)))));


	setAppearance(input_element);
	setTabIndex(input_element, Number(tabindex))
	setCaptionColor(input_element)
	delete_element.src = 'http://' + widget_domain + "/images/grid/delete.gif";

	if (nitem.item_img_url) {
	var img_element = IMG({ id : "image"+nitem.local_id, width : "100" , onerror : "this.style.display='none'"});
		replaceChildNodes(illustration, img_element);
		img_element.src = nitem.item_img_url;
	} else {
		var txt_id = itemIdToTxtNodeId(nitem.local_id);
		var txt_element = DIV({ style : "width: 100px; height: 100px; overflow: hidden;text-align:center;" }, SPAN({ id : txt_id } , nitem.description));
		replaceChildNodes(illustration, txt_element);
		setCaptionColor(txt_element);
		fillTextBlock(txt_id);
	}
}

var updateImageControl = function(url, local_id) {
	var img_element = getObject('image'+local_id);
	img_element.src = url;
	readSettingsControl();
}

var setAppearance = function(inp) {
	if (inp.value == '') {
		inp.value = defaultCaptionMsg
		inp.className = 'emptyCaption'
	} else {
		inp.className = 'captionInput'
	}
}

var getKeyCode = function(e) {
	if (window.event) {
		return window.event.keyCode;
	}
	else if (e) {
		return e.which;
	} else {
		return null;
	}
}

var isSpecialKeyCode = function(key) {
    return (key==null) || (key==0) || (key==8) || (key==9) || (key==13) || (key==27);
}

var restrictTo = function(e, chars) {
	if (chars != null) {
		var key = getKeyCode(e);
		if (isSpecialKeyCode(key)) {
		  return true;
		}
		var keychar = String.fromCharCode(key).toLowerCase();
		return chars.indexOf(keychar) > -1;
	} else {
		return true;
	}
}

// in these functions we need to use visibility
// rather than display because otherwise
// we lose the form context
var writeframe = function(num) {
	var aFrame = $$('frameme' + num)
	if (aFrame) aFrame.innerHTML = '<iframe id="iframe_uploader' + num + '" src="/iframe_uploader" frameborder="0" scrolling="no" style="width:285px; height:25px;background-color:#ffc266"></iframe>';
}


var hideLoading = function() {
	$$('msloading').style.visibility = 'hidden';
	$$('formContainer').style.visibility = '';
	// writing the url of the iframe did not work in safari - so we are going to write the ticker each time
	writeframe();
}

var getScrapeType = function(url) {
	var scrape_type = "";
	if ((url == "imageshack") || imageshackRE.exec(url)) {
		scrape_type = "ImageShack";
	} else if ((url == "myspace") || myspaceRE.exec(url)) {
		scrape_type = "MySpace";
	} else if ((url == "photobucket") || photobucketRE.exec(url)) {
		scrape_type = "Photobucket";
	} else if ((url == "yahoo") || yahooRE.exec(url)) {
		scrape_type = "Yahoo";
	} else if ((url == "flickr") || flickrRE.exec(url)) {
		scrape_type = "Flickr";
	} else if ((url == "rockyou") || rockyouRE.exec(url)) {
		scrape_type = "RockYou";
	} else if ((url == "facebook")) {
		scrape_type = "Facebook";
	} else if ((url == "friendster") || friendsterRE.exec(url)){
		scrape_type = "Friendster";
	} else if (url == "slide"){
		scrape_type = "Slide";
	} else if ((url == "youtube") || youtubeRE.exec(url)){
		scrape_type = "YouTube";
	} else if ((url == "tagged") || tagged_url_with_authRE.exec(url)) {
		scrape_type = "Tagged";
	} else {
		var v = genericRE.exec(url);
		scrape_type = v ? v[2] : "the site";
	}
	return scrape_type;
};

var showMsloading = function(url) {
	url = strtrim(url);
	var scrape_type = getScrapeType(url);
	var span = $$("scrape_type")
	if (span) {
		span.innerHTML = scrape_type;
	}
	$$('formContainer').style.visibility = 'hidden';
	$$('msloading').style.visibility = 'visible';
	return true;
}

var dismissMSLogin = function() {
	if ($$('myspacelogin') != null) {
		$$('myspacelogin').style.display = "none"
	}
	return false;
}

var displayMSLogin = function() {
	if ($$('myspacelogin') != null) {
		$$('myspacelogin').style.display = "block"
	}
}

var addUploadedItems = function(nitems) {
    addArrangeItems(nitems)
	hideLoading()
}

var beboAutoScrapeResult = function(ans, url, numAlbums) {
	hideLoading()
	dismissMSLogin()

	if (ans.substr(0,4) == "PASS" && numAlbums > 0) {
		myo.switchTabs("bebobutton");
	}
}

var standardScrapeResult = function(ans, url) {
	hideLoading()
	if (ans.substring(0,4) == "PASS") {
		dismissMSLogin();
	}
	if (ans == "FAIL:PRIVATEPROFILE") {
		if (url == 'myspace') {
			displayMSLogin();
		} else {
			alert(cl.Arrange.Protected_profile + cl.Arrange.Please_try_another);
		}
	} else if (ans == "FAIL:NOLOGIN" && url == 'flickr') {
		alert(cl.Arrange.Enter_valid_screen_name)
	} else if (ans == "FAIL:NOLOGIN") {
		// if the un & pw were bad, dont use them again
		this.frm.username.value = this.frm.password.value = '';
		alert(cl.Arrange.Incorrect_email_or_password);
	} else if (ans == "FAIL:NOSUCHPROFILE") {
		alert(cl.Arrange.No_such_user_in + getScrapeType(url) + cl.Arrange.Please_try_another);
	} else if (ans == "FAIL:INVALIDURL") {
		alert(cl.Arrange.Input_not_understood + cl.Arrange.Please_try_another);
	} else if (ans == "FAIL:TIMEOUT") {
		alert(getScrapeType(url) + cl.Arrange.Not_responding + cl.Arrange.Try_again_later);
	} else if (ans.substring(0,4) != "PASS") {
		alert(cl.Arrange.Problem_reading_page + cl.Arrange.Please_try_another);
	}
};

// always the callback for all image retrieval panels, ss/fp and all their tabs
var link_process = function(link_url, source) {
	var url = link_url.value;
	if (url.substr(url.length-3) == 'gif') {
		alert(cl.Arrange.Gif_not_supported)
		link_url.value = ''
		return false;
	}
	if (!source){
		source = "link";
	}
	if (urlRE.exec(url)) {
		// download im into temp img tag (which is then tossed).
		// To make sure it loads, and to precache it.
		var img = new Image();
		img.onerror = function(e) {
			alert(cl.Arrange.Cannot_load_image + cl.Arrange.Please_try_again);
		};
		img.onload = function() {
			// yay it loaded.  now add to acumulating list.
			img.onload = null;
			addArrangeItems([{
				description :  '',
				url : url,
				item_img_url : url,
				img_url : url,
				source : source } ]);

			// if its not myspace/photobucket/slide (?) then reset the url blank in the form
			if (!link_url.id){
				link_url.value = "http://";
			}
		};
		img.src = url;

	} else {
		alert(cl.Arrange.Not_valid_URL + cl.Arrange.Please_try_again);
	}
	return false;
}

var url_to_link_process = function(id, title){
	link_process($(id), 'fp_background');
}


var text_process = function(text_field) {
	var text = text_field.value;
	text = strtrim(text);
	if (text) {
		addArrangeItems([{
			description :  text,
			url : '',
			item_img_url : '',
			img_url : '',
			source : "text" } ]);
		text_field.value = "";
	} else {
		alert(cl.Arrange.Please_enter_text);
	}
	return false;
}

var setTickerSize = function(width, height) {
	var cForm = $$('custform')
	cForm.width.value = width;
	cForm.height.value = height;
}

var sizeSuggestion = function(height, width) {
	setTickerSize(width, height)
	window.scrollTo(0,0)
	return readSettingsControl()
}

// transition / theme related
var highlightSelection = function(obj) {
	if (obj) {
		obj.style.backgroundColor = "#ffff99"
		obj.style.border = "1px solid #ffe57c"
	}
}

var clearOutSelection = function(obj) {
	if (obj) {
		obj.style.border="1px solid white"
		obj.style.backgroundColor="transparent"
	}
}

var selectTheme = function(themeIndex, themeName, supressRefresh) {
	setThemeStatus(themeIndex, themeName)
	return selectAspect('theme', themeIndex, supressRefresh);
}

var original_premium_skin = -1;
var selectSkin = function(skinIndex, skinName, supressRefresh) {
	if(original_premium_skin < 0) {
		setSkinStatus(skinIndex, skinName)
		return selectAspect('skin', skinIndex, supressRefresh);
	};

	if(skinIndex != original_premium_skin) {
		answer = confirm("Are you sure you want to remove your premium skin? You will lose it forever!");
		if(answer) {
			original_premium_skin = -1;
			setSkinStatus(skinIndex, skinName)
			return selectAspect('skin', skinIndex, supressRefresh);
		};
	};
}

var selectFilter = function(filterIndex, filterName, supressRefresh) {
	var hasBevel = ((Number(Ticker.effects) & 4) == 4)
	var currentEff = Number(Ticker.effects)
	clearOutSelection($$('effects' + (currentEff - (currentEff & 4))))
	highlightSelection($$('effects' + filterIndex))
	setEffectStatus(filterIndex)
	if (hasBevel) {
		filterIndex = Number(filterIndex) + 4
	}

	var cForm = $$('custform')
	cForm['effects'].value = filterIndex;
	if (!supressRefresh) {
		window.scrollTo(0,0)
		return readSettingsControl();
	}
}

var selectToggle = function(toggleObj, toggleIndex, toggleName) {
	var cForm = $$('custform')
	$$('check_' + toggleIndex).checked = !$$('check_' + toggleIndex).checked
	if ($$('check_' + toggleIndex).checked) {
		highlightSelection(toggleObj)
		cForm['effects'].value = Number(Ticker.effects) + 4;
		setEffectStatus(Number(Ticker.effects) || 4)
	} else {
		clearOutSelection(toggleObj)
		cForm['effects'].value = Number(Ticker.effects) - 4;
		setEffectStatus(cForm['effects'].value)
	}
	return readSettingsControl();
}

var selectAspect = function(aspect, aspectIndex, supressRefresh, supressScroll) {
	var cForm = $$('custform')
	clearOutSelection($$(aspect + cForm[aspect].value))
	highlightSelection($$(aspect + aspectIndex))
	cForm[aspect].value = aspectIndex;
	if (!supressRefresh) {
		if (!supressScroll) {
			window.scrollTo(0,0)
		}
		return readSettingsControl();
	}
}

// overridden in template(s)
var setPreset = function(transitionNum, theme, skin, effects, stageColor, song, sticker) {
	removeSong(true);

	var cForm = $$('custform')

	if (song){
		addSong(song, (valueOf($('autoplay')) ? "true" : "false"), true);
	}

	selectTransition(transitionNum, true)
	selectTheme(theme.id || 0, theme.title || '', true)
	selectSkin(skin.id || 0, skin.title || '', true)
	selectFilter(effects || 0, '', true)

	if (stageColor) {
		$('stgColor').style.backgroundColor = (stageColor == -1) ? "black" : stageColor;
		cForm.stageColor.value = fromRgb(stageColor)
	}

	window.scrollTo(0,0)
	return readSettingsControl()
}

var setStyleStatus = function(transitionNum) {
	var actionLink = (transitionNum == 16) ? '(default)' : '(<a href="#" onclick="return selectTransition(16)">' + cl.Arrange.Remove + '</a>)'
	$('styleStatus').innerHTML = cl.Arrange.Your_pick + ': <b>' + current_styles[transitionNum] + '</b> ' + actionLink
	updateCart('style', transitionNum, current_styles[transitionNum], actionLink)
}

var gup = function(name) {
	name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regexS = "[\\?&]"+name+"=([^&#]*)";
	var regex = new RegExp( regexS );
	var results = regex.exec( window.location.href );
	if( results == null )
		return "";
	else
		return results[1];
}

var setSkinStatus = function(skinNum, skinTitle) {
	var actionLink = '(<a href="#" onclick="return selectSkin(0)">' + cl.Arrange.Remove + '</a>)'
	var skin_displays = appendCampaigns('skinStatus')
	for (var i = 0; i < skin_displays.length; i++) {
		if ($(skin_displays[i])) $(skin_displays[i]).innerHTML = (skinNum == 0) ? cl.Arrange.No_skin_selected : cl.Arrange.Your_pick + ': <b>' + (skinTitle || gup("skinname") || 'custom') + '</b> ' + actionLink
	}
	updateCart('skin', skinNum, skinTitle, actionLink)
}

var setThemeStatus = function(themeNum, themeTitle) {
	var actionLink = '(<a href="#" onclick="return selectTheme(0)">' + cl.Arrange.Remove + '</a>)'
	var theme_displays = appendCampaigns('themeStatus')
	for (var i = 0; i < theme_displays.length; i++) {
		if ($(theme_displays[i])) $(theme_displays[i]).innerHTML = (themeNum == 0) ? cl.Arrange.No_theme_selected : cl.Arrange.Your_pick + ': <b>' + (themeTitle || 'custom')  + '</b> ' + actionLink
	}
	updateCart('theme', themeNum, themeTitle, actionLink)
}

var setEffectStatus = function(effectNum) {
	var actionLink = '(<a href="#" onclick="return clearFilters()">' + cl.Arrange.Remove + '</a>)'
	var addedEffect = ($$('check_4').checked && effectNum != 4) ? '+Bevel' : ''
	var effectTxt = current_effects[effectNum]  + addedEffect
	$('effectStatus').innerHTML = (effectNum == 0) ? cl.Arrange.No_effect_selected : cl.Arrange.Your_pick + ': <b>' + effectTxt + '</b> ' + actionLink
	updateCart('effect', effectNum, effectTxt, actionLink)
}

var setMusicStatus = function(song) {
	if (song) {
		var actionLink = '<span class="small">(<a href="#" onclick="return removeSong()">' + cl.Arrange.Remove + '</a>)</span>'
		$('songStatus').innerHTML = cl.Music.Your_current_pick
		$('cSongTitle').innerHTML = song.title
		$('cSongArtist').innerHTML = song.artist
		$('cSongArt').src = song.album_url
		$('currentSong').style.display = 'block'
		updateCart('song', song.id, song.title, actionLink)
	} else {
		$('songStatus').innerHTML = cl.Music.No_song_selected
		$('currentSong').style.display = 'none'
		updateCart('song', 0, 0, 0)
	}
}

var updateCart = function(feature, feature_id, feature_title, actionLink) {
	if (typeof(addToCart) != 'undefined') addToCart(feature, feature_id, feature_title, actionLink)
	return false;
}

var clearFilters = function() {
	var currentEff = Number(Ticker.effects)
	clearOutSelection($$('effects' + (currentEff - (currentEff & 4))))

	$$('check_4').checked = false
	clearOutSelection($$('effects4'))

	var cForm = $$('custform')
	cForm['effects'].value = 0;
	setEffectStatus(0)
	window.scrollTo(0,0)

	return readSettingsControl();
}

var selectTransition = function(transitionNum, supressRefresh) {
	var cForm = $$('custform')
	clearOutSelection($$('trans' + cForm.transition.value))
	highlightSelection($$('trans' + transitionNum))
	setStyleStatus(transitionNum)
	cForm.transition.value = transitionNum;
	if (!supressRefresh) {
		window.scrollTo(0,0)
		return readSettingsControl()
	}
}

var selectSecTransition = function(transitionNum, supressRefresh) {
	hideDimmedPopup('morestyles')
	return selectTransition(transitionNum, supressRefresh)
}

var selectSecTheme = function(themeIndex, themeName, supressRefresh) {
	hideDimmedPopup('morethemes')
	return selectTheme(themeIndex, themeName, supressRefresh)
}

var hlTrans = function(obj) {
	obj.style.backgroundColor = "#c5d7da"
}

var llTrans = function(obj) {
	obj.style.backgroundColor = "#fff"
}

var onEnter = function(e, chars, fnc) {
   var key = getKeyCode(e);
   if (key == 13) {
   		fnc()
   		return false;
   } else {
		return restrictTo(e, chars);
   }
}

// overridden in template(s)
var restrictSize = function() {
	fHeight = $$('custform').height
	fWidth = $$('custform').width
	if (fHeight.value < minSizeValue) fHeight.value = minSizeValue
	if (fWidth.value < minSizeValue) fWidth.value = minSizeValue

	return readSettingsControl()
}

var restrictValue = function(obj) {
   	if (obj.value < minSizeValue) obj.value = minSizeValue
}

var getAlbumName = function(album, username) {
	var maxSize = 30
	return (album.name == null) ? username.substr(0, maxSize) : album.name.substr(0, maxSize)
}

var selectAlbum = function(source, container) {
	var cForm = $(source + 'form')
	cForm.url.value = container.id.substr(1)
	cForm.onsubmit()
	return false
}

var createPreview = function(album, source, albumsArea, username) {
	appendChildNodes(
		albumsArea,
		A({	id 		: 'a' + album.url,
			href 	: '#',
			'class' : 'albumSel',
			onclick	: 'return selectAlbum("' + source + '", this)' },
				TABLE({ cellSpacing	: '0', cellPadding : '0', border : '0', width : '90%', style : 'height: 60px;' },
					TBODY(null,
						TR(null,
							TD({align :	'center',
								valign:	'middle',
								style : 'width: 60px; border: 1px solid #ccc; background-color: #fff;'},
								DIV({ style :	'width: 60px; height: 60px; overflow: hidden; text-align: center;'},
									TABLE({ cellSpacing	: '0',
											cellPadding : '0',
											style		: 'width: 60px; height: 60px; background-color: #fff;' },
										TBODY(null,
											TR(null,
												TD({align : 'center', valign: 'middle'},
													album_preview = IMG({ style : 'width: 60px;', onerror : "this.style.display='none'" }))))))),
							TD({align :	'left',
								valign:	'middle',
								style : 'padding-left: 5px;' },
								DIV(null, getAlbumName(album, username)),
									SPAN({ style : 'font-size: 8pt;' }, (album.n_images) ? '(' + album.n_images + ' photos)' : '')))))))

	album_preview.src = album.preview_url || '/images/interface/all_images.jpg'

}

var previewAlbums = function(source, albumList, username) {
	albumPreview = $(source + 'preview')
	albumsArea = $(source + 'albums')

	for (i = 0; i < albumList.length; i++) {
		var album = albumList[i]
		createPreview(albumList[i], source, albumsArea, username)
	}

	$(source + 'login').style.display = 'none'
	$(source + 'submit').style.display = 'none'
	$(source + 'cancel').style.display = 'block'
	if ($(source + 'form').scrapealbums) {
		$(source + 'form').scrapealbums.value="";
	}
	albumPreview.style.display = 'block'
}

var getEntityName = function(entity, username) {
	var maxSize = 30;
	var name = entity.name || entity.description || username;
	return name.substr(0, maxSize);
}

var createEntityPreview = function(entity, source, entityArea, username, selectCallback) {
	appendChildNodes(
		entityArea,
		A({	id 		: 'a' + entity.url,
			href 	: '#',
			'class' : 'entitySel',
			onclick	: function (){ return selectCallback(entity)}},
				TABLE({ cellSpacing	: '0', cellPadding : '0', border : '0', width : '90%', style : 'height: 60px;' },
					TBODY(null,
						TR(null,
							TD({align :	'center',
								valign:	'middle',
								style : 'width: 60px; border: 1px solid #ccc; background-color: #fff;'},
								DIV({ style :	'width: 60px; height: 60px; overflow: hidden; text-align: center;'},
									TABLE({ cellSpacing	: '0',
											cellPadding : '0',
											style		: 'width: 60px; height: 60px; background-color: #fff;' },
										TBODY(null,
											TR(null,
												TD({align : 'center', valign: 'middle'},
													entity_preview = IMG({ style : 'width: 60px;', onerror : "this.style.display='none'" }))))))),
							TD({align :	'left',
								valign:	'middle',
								style : 'padding-left: 5px;' },
								SPAN(null, getEntityName(entity, username))))))))

	entity_preview.src = entity.preview_url || entity.img_url || '/images/interface/all_images.jpg'
}

var createSearchEntityPreview = function(entity, source, entityArea, username, selectCallback) {
	appendChildNodes(
		entityArea,
		A({	id 		: 'a' + entity.url,
				href 	: '#',
				'class' : 'searchEntitySel',
				onclick	: function (){ return selectCallback(entity)}},
		  TABLE({ cellSpacing	: '0', cellPadding : '0', border : '0',  style : 'height: 60px;' },
				TBODY(null,
					  TR(null,
						 TD({align :	'center',
								 valign:	'middle',
								 style : 'width: 60px; border: 1px solid #ccc; background-color: #fff;'},
							DIV({ style :	'width: 60px; height: 60px; overflow: hidden; text-align: center;'},
								TABLE({ cellSpacing	: '0',
											cellPadding : '0',
											style		: 'width: 60px; height: 60px; background-color: #fff;' },
									  TBODY(null,
											TR(null,
											   TD({align : 'center', valign: 'middle'},
												  entity_preview = IMG({ style : 'width: 60px;', onerror : "this.style.display='none'" }))))))))))));

	entity_preview.src = entity.preview_url || entity.img_url || '/images/interface/all_images.jpg'
};



var previewEntitySet = function(source, entityList, username, selectCallback, previewFunction) {
	entityPreview = $(source + 'preview');
	entityArea = $(source + 'entity');

	previewFunction = previewFunction || createEntityPreview;
	for (i = 0; i < entityList.length; i++) {
		previewFunction(entityList[i], source, entityArea, username, selectCallback)
	}

	$(source + 'login').style.display = 'none'
	$(source + 'submit').style.display = 'none'
	$(source + 'cancel').style.display = 'block'
	entityPreview.style.display = 'block'
}

var cancelEntitySet = function(source, frm) {
	$(source + 'login').style.display ='block'
	$(source + 'cancel').style.display = 'none'
	$(source + 'submit').style.display = 'block'
	$(source + 'preview').style.display = 'none'
	$(source + 'entity').innerHTML = ''

	if (frm && frm.url){
		frm.url.value = '';
		frm.url.focus();
	}
}

var cancelAlbums = function(source) {
	var frm = $(source + 'form');
	if (source == 'myspace')
	{
		frm.username.value = ''
		frm.password.value = ''
		frm.scrapealbums.value = 'true'
		frm.url.value = 'http://www.myspace.com/'
		$(source + 'login').style.display ='none'
	}
	else
	{
		frm.url.value = ''
		$(source + 'login').style.display ='block'
	}
	$(source + 'cancel').style.display = 'none'
	$(source + 'submit').style.display = 'block'
	$(source + 'preview').style.display = 'none'
	$(source + 'albums').innerHTML = ''
}

var _callasync = function(parms, alertmsg, success, failure, isPartner){
	alertmsg = alertmsg || cl.Arrange.This_acct_has_no_photos;
	asyncAction('scrapeajax',
				parms ,
				function(ans) {
					hideLoading()
					if (ans.substring(0, 4) == "PASS" ) {
						dismissMSLogin()
						var newItems = evalJSON(ans.substring(4))
						if (success) {
							success(newItems)
							return false;
						}
						if (newItems.length > 0) {
							addArrangeItems(newItems)
						} else {
							if (!(isPartner)){
								alert(alertmsg);
							}
						}
					} else {
						if (failure) {
							failure(ans)
						} else {
							standardScrapeResult(ans, parms['url']);
						}
					}
				});
}

var grabAllPhotos = function(frm, source) {
	var parms = { username : frm.username && frm.username.value,
				  password : (frm.password && frm.password.value) || '',
				  url : frm.url.value,
				  auth : (frm.auth && frm.auth.value) || '' ,
				  source : source,
				  xaction : 'scrape_all' };
	_callasync (parms);
}

// for use with when you do not have a form object
// eg.  checkAutoscrape()
var doScrapeAll = function(source, url, username, password, isPartner) {
	var parms = {url : url,
				username : username || '',
				password : password || '',
				source : source,
				xaction : 'scrape_all'};
	_callasync(parms, null, null, null, isPartner);
}


// for use with video scraping
var doScrapeVideo = function(frm, source) {
	var parms = { username : (frm.username && frm.username.value) || '',
				password : (frm.password && frm.password.value) || '',
				auth: (frm.auth && frm.auth.value) || '',
				source : source,
				xaction : 'scrape_video_url',
				url : strtrim(frm.url.value) };
	_callasync(parms, cl.Arrange.This_acct_has_no_videos, initVideo);
}

var submitmyspace = function(frm) {
	fragment = "myspace.com";
	frm.url.value = strtrim(frm.url.value)
	if (frm.url.value == 'http://www.myspace.com/' || frm.url.value == '') {
		alert(cl.Arrange.Enter_MySpace_URL);
		return false;
	} else if (!(frm.url.value.match(fragment))){
		frm.url.value = "http://www.myspace.com/" + frm.url.value.replace(/ /, '');
	}

	showMsloading(frm.url.value)
	submitAlbum(frm, 'myspace');
	return false;
}

var submitfriendster = function(frm) {
	if (frm.url.value == 'http://www.friendster.com/' || frm.url.value == '') {
		alert(cl.Arrange.Enter_Friendster_URL)
		return false;
	}
	showMsloading(frm.url.value) && grabAllPhotos(frm, "friendster");
}

var submitflickr = function(frm) {
	if (frm.username.value == '') {
		alert(cl.Arrange.Enter_valid_screen_name)
		return false;
	}
	showMsloading('http://flickr.com/')
	submitAlbum(frm, 'flickr');
	return false;
}

var submitwretch = function(frm) {
	var username = frm.username.value;
	var v = wretchRE.exec(username);
	if (v) {
		username = v[1];
	} else 	if (! wretchUserRE.exec(username)) {
		alert(cl.Arrange.Enter_valid_Wretch_ID);
		return false;
	}

	showMsloading(frm.url.value)
	submitAlbum(frm, 'wretch', username);
	return false;
}


var submitfacebook = function(auth, username, callback) {
	return submitPopup("facebook", auth, "", callback);
}

var submitphotobucket = function(auth, username, callback) {
	return submitPopup("photobucket", auth, username, callback);
}

var popupWindow = null;

var closePopupWindow = function(ans, source, albumlength) {
	setTimeout(function() { popupWindow.close() }, 0)
	if (!albumlength){
		alert(cl.Arrange.This_acct_has_no_photos);
	}
}


var submitPopup = function(communityName, auth, username, callback) {
	var frm = $$(communityName + "form")
	frm.auth.value = auth;
	frm.username.value = username;
	showMsloading(communityName);
	submitAlbum(frm, communityName, '', null, closePopupWindow);
	return false;
}

var submitbebo = function(frm, callback) {
	if (frm.auth.value == "" && frm.url.value == "") {
		if (frm.username.value == '') {
			alert(cl.Arrange.Enter_valid_email)
			frm.username.focus()
			return false;
		}
		if (frm.password.value == '') {
			alert(cl.Arrange.Enter_valid_password)
			frm.password.focus()
			return false;
		}
	}
	showMsloading('http://bebo.com/')
	submitAlbum(frm, 'bebo', frm.username.value, frm.password.value, callback);
	return false;
}

var submitkodak = function(frm, callback) {
	if (frm.auth.value == "" && frm.url.value == "") {
		if (frm.username.value == '') {
			alert(cl.Arrange.Enter_valid_email)
			frm.username.focus()
			return false;
		}
		if (frm.password.value == '') {
			alert(cl.Arrange.Enter_valid_password)
			frm.password.focus()
			return false;
		}
	}

	var to_enc = frm.password.value;
	var the_res= "";
	for(i=0;i<to_enc.length;++i){
		the_res += String.fromCharCode(frm.auth_key.value ^ to_enc.charCodeAt(i));
	}
	frm.auth.value = frm.auth_key_c.value;

	showMsloading('partner');
	submitAlbum(frm, 'kodak', frm.username.value, the_res, callback);
	return false;
}

var submitpartner = function(frm) {
	showMsloading('partner')
	submitAlbum(frm, frm.source.value);
	return false;
}

var submitslide = function(frm) {
	showMsloading('Slide')
	submitAlbum(frm, 'slide');
	return false;
}

var submitorkut = function(frm) {
	showMsloading('Orkut');
	frm.username.value = stv.getProfileUID(stv.viewer);
	submitAlbum(frm , 'orkut');
	return false;
}

var submittagged = function(frm) {
	if (frm.username.value == '') {
		alert(cl.Arrange.Enter_valid_email)
		return false;
	}
	showMsloading('tagged')
	grabAllPhotos(frm, "tagged");
	return false;
}

var initVideoSelected = function (entity) {
	initVideo([entity]);
	if ($('donepre')) {
		$('donepre').disabled = false;
	}
	$('submission').disabled = false;
	$('submission').style.display = 'block'
	if ($('donepresets')) {
		$('donepresets').style.display = 'block'
	}
}
var submityoutube = function (frm) {
	if (frm.url.value == ''){
		alert(cl.Arrange.Enter_valid_youtube_url);
		frm.url.focus();
		return false;
	}

	if ((youtubegroupRE.exec(frm.url.value))){
		alert(cl.Arrange.Must_be_valid_video_url);
		frm.url.focus();
		return false;
	}
	showMsloading('YouTube');
	if ($('donepre')) {
		$('donepre').disabled = true;
	}
	$('submission').disabled = true;
	if ((youtubeRE.exec(frm.url.value))){
		doScrapeVideo(frm, 'youtube');
		if ($('youtubeprofilecancel')){
			$('youtubeprofilecancel').style.display = 'block';
		}
	} else if ((youtubeprofileRE.exec(frm.url.value))){
		submitEntitySet(frm, 'youtubeprofile', 'scrape_video_profile', cl.Arrange.No_videos_found, initVideoSelected);
		return false;
	} else {
		submitEntitySet(frm, 'youtubeprofile', 'scrape_video_profile', cl.Arrange.No_videos_found, initVideoSelected);
		return false;
	}
	if ($('donepre')) {
		$('donepre').disabled = false;
	}
	$('submission').disabled = false;
	$('submission').style.display = 'block'
	if ($('donepresets')) {
		$('donepresets').style.display = 'block'
	}
	return false;
}


var submitslideintsearch = function (frm) {
	frm.url.value = strtrim(frm.url.value);
	if (frm.url.value == ''){
		alert(cl.Arrange.Enter_valid_search_word);
		frm.url.focus();
		return false;
	}

	showMsloading('Slide');
	submitInternalSearch(frm.url.value);
	return false;
}

var searchedImageSelected = function(item) {
	addArrangeItems( [ item ] );
	return false;
};

var submitInternalSearch = function(qry) {
    asyncAction("/searchajax",
		{ "xaction" : "search",
		  qry : qry },
				function(ans) {
					hideLoading();
					if (ans.substr(0,4) == "PASS") {
						var entity = evalJSON(ans.substr(5));
						if (entity.length == 0){
							alert(cl.Arrange.No_images_found);
						}else {
							previewEntitySet("slideintsearch", entity, "", searchedImageSelected, createSearchEntityPreview);
						}
					}
				});
};

var submityoutubesearch = function (frm, callback) {
	if (!callback){
		callback = initVideoSelected;
	}
	frm.url.value = strtrim(frm.url.value);
	if (frm.url.value == ""){
		alert(cl.Arrange.Enter_valid_search_word);
		frm.url.focus();
		return false;
	}
	showMsloading('YouTubeSearch');
	if ($('donepre')) {
		$('donepre').disabled = true;
	}
	$('submission').disabled = true;
	submitEntitySet(frm, 'youtubesearch', 'scrape_video_search', cl.Arrange.No_videos_found, callback)
	return false;
}

var submitmyspacevideo = function (frm) {
	if (frm.url.value == ''){
		alert(cl.Arrange.Enter_valid_myspacevideo_url);
		frm.url.focus();
		return false;
	}
	showMsloading('MySpace');
	if ((myspacevideoRE.exec(frm.url.value))){
		doScrapeVideo(frm, 'myspace');
	}else {
		submitEntitySet(frm, 'myspacevideo', 'scrape_video_search', cl.Arrange.No_videos_found, initVideoSelected);
		return false;
	}
	$('donepre').disabled = true;
	$('submission').disabled = true;
	$('donepre').disabled = false;
	$('submission').disabled = false;
	$('submission').style.display = 'block'
	if ($('donepresets')) {
		$('donepresets').style.display = 'block'
	}
	return false;
}

var submitEntitySet = function(frm, source, func, alertmsg, selectCallback, previewRenderer ){
	this.frm = frm;
	community = source;
	//special cases
	if (source == 'youtubesearch'){
		community = 'youtube';
	} else if (source == 'youtubeprofile'){
		community = 'youtube';
	} else if (source == 'myspacevideo'){
		community = 'myspace';
	}
	asyncAction('scrapeajax',
		{'xaction' : func,
		'source' : community,
		'auth'   : (this.frm.auth && this.frm.auth.value) || '',
		'password' : (this.frm.password && this.frm.password.value) || '',
		'username' : (this.frm.username &&this.frm.username.value) || '',
		'url' : (this.frm.url && this.frm.url.value) || ''},
		function(ans){
			hideLoading();
			if (ans.substr(0,4) == "PASS") {
				var entity = evalJSON(ans.substr(5));
				if (entity.length == 0){
					alert(alertmsg);
				}else {
					previewEntitySet(source, entity, (this.frm.username && this.frm.username.value) || '', selectCallback, previewRenderer)
				}
			}
			standardScrapeResult(ans, source);
		}
	);
	return false;
}

var submitAlbum = function(frm, source, username, password, submitAlbumCallback) {
	if (valueOf(frm.url) == '-1') { // Grabbing All
		grabAllPhotos(frm, source);
	} else if (valueOf(frm.scrapealbums) || !valueOf(frm.url)) { // Fill in the drop-down with albums
			this.frm = frm
			asyncAction('scrapeajax',
			{	'action'		: 'getalbums',
				'source'		: source,
				'url'			: (frm.url && frm.url.value) || '',
				'auth'			: (frm.auth && frm.auth.value) || '',
				'partner'		: (frm.partner && frm.partner.value) || '',
				'password'		: password || (frm.password && frm.password.value) || '',
				'username' 		: username || frm.username.value } ,
						function(ans) {
							hideLoading()
							if (ans.substr(0,4) == "PASS") {
								if (source == 'myspace')
								{
									document.cookie = 'msurl.'+ base_base_domain +'='+ frm.url.value
										+ "; expires=Fri, 18 Jul 2036 00:00:00 GMT; path=/; domain=."
										+ base_base_domain;
									if (logCreateMySpaceURLCookie)
										logCreateMySpaceURLCookie();
								}

								var currentAlbum = evalJSON(ans.substr(5));
								if (currentAlbum.length == 0) {
									if (source == "flickr") {
										grabAllPhotos(frm, source);
									} else if (submitAlbumCallback) {
										// this is a hack a blank response should probably also be handled by the callback below
									} else {
										alert(cl.Arrange.This_acct_has_no_photos);
										cancelAlbums(source);
									}
								} else {
									previewAlbums(source, currentAlbum, this.frm.username.value)
								}
							} else if (source != 'myspace') {
								cancelAlbums(source);
							}
							if (submitAlbumCallback) {
								submitAlbumCallback(ans, source, currentAlbum && currentAlbum.length);
							} else {
								standardScrapeResult(ans, source);
							}
						});
			return false;
	} else { // Grabbing a set
		doScrape(source,
				 frm.url.value,
				 null,
				 frm.username.value,
				 password || (frm.password && frm.password.value) || '',
				 (frm.auth && frm.auth.value) || '');
		return false;
	}
	return false;
}

function clearSelectChildren(d) {
	while (d.childNodes[0]) {
		d.removeChild(d.childNodes[0]);
	}
}

var updateForm = function(ticker) {
    var frm = $$("custform");

	var setColorBlock = function(blockName, color) {
		if ($$(blockName) && (color != -1)) {
		    $$(blockName).style.backgroundColor = d2rgb(color);
		}
	}

	setColorBlock('txtColor', ticker.textColor);
	setColorBlock('bgColor', ticker.backgroundColor);
	setColorBlock('stgColor', ticker.stageColor);
	setColorBlock('txtFrmColor', ticker.textColor);
	setColorBlock('chrColor', ticker.chromeColor);
	setColorBlock('hovColor', ticker.hoverColor);
	setColorBlock('thmColor', ticker.themeColor);

	if (frm.transition) frm.transition.value = ticker.transition
	if (frm.tcolor) frm.tcolor.value = ticker.textColor
	if (frm.theme) frm.theme.value = ticker.theme
	if (frm.bcolor) frm.bcolor.value = ticker.backgroundColor
	if (frm.stageColor) frm.stageColor.value = ticker.stageColor
	if (frm.hoverColor) frm.hoverColor.value = ticker.hoverColor
	if (frm.chromeColor) frm.chromeColor.value = ticker.chromeColor
	if (frm.themeColor) frm.themeColor.value = ticker.themeColor
	if (frm.textsize) frm.textsize.value = ticker.textSize
	if (frm.speed) frm.speed.value = ticker.speed
	if (frm.shuffle) {
		if (frm.shuffle.type == "checkbox") {
			frm.shuffle.checked = ticker.shuffle;
		} else {
			frm.shuffle.value = ticker.shuffle;
		}
	}

	if (frm.height) frm.height.value = ticker.height
	if (frm.width) frm.width.value = ticker.width
	if (frm.textFX) frm.textFX.value = ticker.textFX
	if (frm.soundFX) frm.soundFX.value = ticker.soundFX
	if (frm.font) frm.font.value = ticker.font
	if (frm.effects) frm.effects.value = ticker.effects
	if (frm.skin) frm.skin.value = ticker.skin
	if (frm.channelPrivacy) frm.channelPrivacy.value = ticker.privacy
	setSlideShowName(frm, ticker.channel_name)
}

var defaultNameMsg = '(Optional)'

var updateName = function() {
	var newVal = $$('slideshow_name').value
	if (newVal && newVal != $$('channel_name').value && newVal != defaultNameMsg) {
		$$('channel_name').value = newVal
	}
}

var setSlideShowName = function(frm, val) {
	if (frm.channel_name) {
		frm.channel_name.value = val
		$$('slideshow_name').value = val || defaultNameMsg
	}
}

// create a (ss or funpix?) Ticker object by getting values out of the customize form
var initializeTickerFromForm = function() {

	// Form may or may not contain all fields.
	var frm = $$('custform');
	var ticker = {
		transition 		: valueOf(frm.transition),
		textColor 		: valueOf(frm.tcolor),
		backgroundColor : valueOf(frm.bcolor),
		stageColor		: valueOf(frm.stageColor),
		effects		    : valueOf(frm.effects),
		theme	 		: valueOf(frm.theme),
		themeColor		: valueOf(frm.themeColor),
		hoverColor 		: valueOf(frm.hoverColor),
		chromeColor 	: valueOf(frm.chromeColor),
		textSize 		: valueOf(frm.textsize),
		speed 			: valueOf(frm.speed),
		shuffle			: valueOf(frm.shuffle),
		height 			: valueOf(frm.height),
		width 			: valueOf(frm.width),
		font 			: valueOf(frm.font),
		skin 			: valueOf(frm.skin),
		textFX 			: valueOf(frm.textFX),
		soundFX			: valueOf(frm.soundFX),
		privacy 		: valueOf(frm.channelPrivacy),
		publish     : valueOf(frm.channelPublish),
		channel_name	: valueOf(frm.channel_name)
	}
	return ticker;
}

var confirmSave = function(next) {
	if ((currentPxcid != '' || hasPxciid != '' || addedItems) && performedChanges > 1) {
		if (confirm(cl.Arrange.Save_the_guestbook)){
			submitShow(next);
			return false;
		}
	}
	return true;
}

var confirmEdit = function() {
	if ((currentPxcid != '' || hasPxciid != '' || addedItems) && performedChanges > 1) {
		return confirm(cl.Arrange.Unsaved_Changes)
	} else {
		return true;
	}
}

var resetTitle = function() {
	var currentTitle = document.title.toString()
	if (currentTitle.charAt(currentTitle.length - 1) == "#") {
		document.title = currentTitle.substr(0, (currentTitle.length - 1))
	}
}

// see also same function in pic_arrange
var readSettingsControl = function() {
	Ticker = initializeTickerFromForm()
	updateSettingsView(Ticker);
	writeArrangeStorageArea();
	return false;
}

var updateSettingsView = function(ticker) {
	updateForm(ticker);
	notifyFlash();
	if (document.all) resetTitle()
}

//Upload
var uploadProg = function(obj, totaltime) {
	totalcount = Math.ceil(298 * (1.0 - (8 / (totaltime + 8))))
	obj.style.width =  totalcount + 'px'
	currentCounter = setTimeout(function() { uploadProg(obj, ++totaltime) }, 100)
}

var cleanUpload = function(num) {
	var doc = $('iframe_uploader' + num).contentDocument || document.frames['iframe_uploader' + num].document;
	var frm = doc.getElementById('upload_form');
	var fileinput = doc.getElementById('file_element')

	if (fileinput && fileinput.value != '') {
		showUploadProgress(num, true)
		frm.submit();
	} else {
		showUploadProgress(num, false)
		nextUpload()
	}
}

var showUploadProgress = function(num, doCount) {
	$('uploadprog' + num).style.display = 'block'
	if (doCount) startCount(num)
}

var startCount = function(num) {
	clearTimeout(currentCounter)
	if (uploadInProgress != null) {
		var progressBar = $('progress' + (uploadInProgress))
		progressBar.style.background = 'white url(/images/myspace/upload_static.gif) repeat-x top left'
		progressBar.style.width = '298px'
	}
	uploadInProgress = num
	var curProgressBar = $('progress' + num)
	curProgressBar.style.background = 'transparent url(/images/myspace/upload_anim.gif) repeat-x top left'
	uploadProg(curProgressBar, 1)
}

var minFontSize = 18;
var maxFontSize = 70;

var fillTextBlock = function(nodeID) {
	var block = $(nodeID);
	block.parentNode.style.paddingTop = "0px"
	block.style.fontSize = Math.floor((maxFontSize + minFontSize) / 2) + "px";
	expandFontSize(nodeID);
};

var expandFontSize = function(nodeID) {
   setTimeout("doExpandFontSize('" + nodeID + "')", 0);
}

var doExpandFontSize = function(nodeID) {
   var block = $(nodeID);
   var fs = Number(block.style.fontSize.substring(0,2));
   if (fs <= maxFontSize) {
	   var sr = sizeRatio(block);
	   if ( (sr < .80) || (sr > 1.0)) {
		   var nfs = Math.floor(2 * fs / (1 + sr));
		   if (nfs == fs) {
			   nfs = fs-1;
		   }
		   expandFontSize(nodeID);
		   block.style.fontSize = nfs + "px";
	   } else {
		   block.parentNode.style.paddingTop = Math.floor((block.parentNode.offsetHeight - block.offsetHeight) / 2) + "px";
	   }
   }
};


var sizeRatio = function(block) {
	var hr = block.offsetHeight / block.parentNode.offsetHeight;
	var wr = block.offsetWidth / block.parentNode.offsetWidth;
	return (hr > wr) ? hr : wr;
};


function SetOpacityById(id, opacity) {
	SetOpacity(getObject(id), opacity)
}

function windowSize() {
	if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
		return { width : window.innerWidth ,
					 height : window.innerHeight };
	} else if( document.documentElement &&
			   ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		//IE 6+ in 'standards compliant mode'
		return { width : document.documentElement.clientWidth ,
					 height : document.documentElement.clientHeight };
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		//IE 4 compatible
		return { width : document.body.clientWidth ,
					 height : document.body.clientHeight };
	}
	return { width : 0, height : 0  };

}

// called by displayDimmed() to show or hide all the Select menus on msie to avoid that bug
// duplicated also in dialog.js
var displaySelects = function(show) {
	this._toggleFields = function(fields, visibility) {
		for(var i = 0; i < fields.length; i++) {
			fields[i].style.visibility = (visibility) ? 'visible' : 'hidden'
		}
	}
	if (document.all) {
		// This part is a hack because IE 6 doesn't respect z-index for 'select' type inputs
		this._toggleFields(document.getElementsByTagName('select'), show)

		if (document.frames.length) {
			for (var i = 0; i < frames.length; i++) {
				try {
					this._toggleFields(document.frames[i].document.getElementsByTagName('select'), show)
				} catch(e) { }
			}
		}
	}
}

// see also same name in dialog.js and iframe_embed.tmpl
var displayDimmed = function(id, fnc, showSelects, suppressTransparency) {
	var currentWindow = windowSize();
	currentWindow.height = Math.max(currentWindow.height, document.body.offsetHeight)
	currentWindow.width = Math.max(currentWindow.width, document.body.offsetWidth)
	if (!suppressTransparency) {
		$('blackout').style.height = currentWindow.height + 200 + "px";
		$('blackout').style.width = currentWindow.width + "px";
		$('blackout').style.display = 'block'
		SetOpacityById('blackout', 50)
	}
	$(id).style.display = 'block'

	// Hack alert: this is because Firefox ignores z-index with overflow:auto
	var tabBoxElement = $('tabBox')
	if (tabBoxElement) { tabBoxElement.style.display = 'none' }

	//if (!showSelects) displaySelects(false)
	if (fnc) fnc();
	return false;
}

var dismissDimmed = function(id, fnc) {
	$('blackout').style.display = 'none'
	$(id).style.display = 'none'

	// Hack alert: this is because Firefox ignores z-index with overflow:auto
	var tabBoxElement = $('tabBox')
	if (tabBoxElement) { tabBoxElement.style.display = 'block' }

	displaySelects(true)
	if (fnc) fnc()
	return false;
}

// for writing flash out without hitting eolas snag
var writeHtml = function(objId, htmlCode) {
        $(objId).innerHTML = htmlCode
}

var flashLowVersion = false;

var flashTooLow = function() {
	if (!flashLowVersion) {
		flashLowVersion = true;
		var isIE = document.all
		var isVista = navigator.userAgent.indexOf("Windows NT 6.0") >= 0
		var bulkInstalled = isIE && ImageUploaderInstalled()

		if ( isIE && !isVista) {
			ShowRegularUploader()
			showBulkLink('switchup1')
			showSingleLink('switchup2')
			$$('switchup1').style.display = 'block'
			$$('switchup2').style.display = 'none'

		} else { // not ie, flash too low
			ShowRegularUploader()
			$$('switchup1').style.display = 'none'
			$$('switchup2').style.display = 'none'
		}
	}
}

var flashStartUploading = function() {
	updateSaveButtons(function(btn) { btn.disabled = true; btn.style.backgroundColor = '#999' })
	return true;
}

var flashDoneUploading = function() {
	if (flashItemQueue.length > 0) {
		var dispItems = [];
		var item;
		while(item = flashItemQueue.shift()) {
			dispItems.push(item);
		}
		addArrangeItems(dispItems, true);
	}
	updateSaveButtons(function(btn) { btn.disabled = false; btn.style.backgroundColor = '#008f00' })
	return true;
}

var flashFailed = function(fileList) {
	//alert('flashFailed() called with ' + fileList.length + ' items' );
	return true;
}

var flashAddItem = function(items) {
	var item;
	while(item = items.shift()) {
		flashItemQueue.push(item);
	}
	if (flashItemQueue.length%5 == 0) {
		var dispItems = [];
		for(var i=0;i<5;i++) {
			dispItems.push(flashItemQueue.shift());
		}
		addArrangeItems(dispItems);
	}
	return true;
}

var jogObj = false
var jogObject = function(objId) {
	var obj = $(objId)
	if (obj) obj.style.marginBottom = (jogObj) ? '0' : '0px'
	jogObj = !jogObj
}

// logging
// used to translog a hit internal to the page or
var internalTransLog = function(actionID, view_id, action_type, user_id, transaction_details, channel_id) {
	asyncAction('userajax',
				{
					xaction: 'dotranslog',
					actionID: actionID,
					view_id: view_id,
					action_type: action_type,
					user_id: user_id,
					transaction_details:transaction_details && serializeJSON(transaction_details),
					channel_id: channel_id
				});
}

// campaign handling
var active_campaigns = {};

var addCampaign = function(campaign_id, asset_dir, has_toe) {
	active_campaigns[campaign_id] = { id : campaign_id,
									  asset_dir : asset_dir,
									  has_toe : has_toe
	}
}

var appendCampaigns = function(str) {
	var result = [ str ]

	for (var campaign in active_campaigns) {
		result.push(str + campaign)
	}
	return result
}

// overridden in templates
var replacedPresets = 1
var updatePresetNumber = function() {
	return replacedPresets += 2
}

var addCampaignPreset = function(campaign_id, preset, style, theme, skin, sticker, effect, bg_color, song) {
	var presetCampaign = active_campaigns[campaign_id] || ''
	if (presetCampaign) {
		addLoadEvent(function() {
			clearChildren($('preset_' + replacedPresets))
			appendChildNodes(
				$('preset_' + replacedPresets),
					A({ href : "#",
						"class" : "presetContainer",
						onclick : function() {
						if (presetCampaign.has_toe) {
								$('campaign_toe' + campaign_id).style.display = 'block';
								customize.switchTabs('c' + campaign_id + 'button');
						}
								return setPreset(style.id, theme, skin, effect, bg_color, song, sticker); }},
							// FIX: This is hitting the wrong server, and needs to be templated.
							SPAN({  "class" : "presetImage",
									"style" : "background: transparent url(/images/campaigns/" + presetCampaign.asset_dir + "/" + preset.img + ") no-repeat 0 " + (preset.img_offset * -1) + "px;" })))
			updatePresetNumber()
		});
	}
}


var TabSwitcher = function(tabs, maxLargeTabs, enabledClassName, disabledClassName) {
	this.tabs = tabs;
	this.maxLargeTabs = maxLargeTabs;	// no longer useful -- will remove when no longer referenced - S
	this.enabledClassName = enabledClassName;
	this.disabledClassName = disabledClassName;
};

TabSwitcher.prototype.switchTabs = function(tab_id, callback) {
	for (var i = 0; i < this.tabs.length; i++) {
		var tab = this.tabs[i];
		var isCurrent = (tab.button == tab_id);
		var curTab = $(tab.button) || document.createElement('div');
		var curBox = $(tab.container) || document.createElement('div');

		curTab.className = isCurrent ? this.enabledClassName : this.disabledClassName;
		curBox.style.display = isCurrent ? 'block' : 'none';
	}

	if (callback) callback(tab_id)

	return false;
}

// This fixes a weird display issue in Firefox where the customize area resizes independently of the rest of the stuff - S
var changec = false
var jogCustomize = function() {
	$('custFrmArea').style.marginBottom = (changec) ? '0' : '1px'
	changec = !changec
}

music_frame_url = "/music_frame?featured=true&genre=0"

var musicLoaded = false;

var loadMusic = function() {
	jogCustomize()
	if (!musicLoaded) {
		$('musicFrame').innerHTML = '<iframe name="featuredFrame" id="featuredFrame" height="225" width="200" frameborder="0" scrolling="auto" src="' + music_frame_url + '"></iframe>'
		musicLoaded = true;
		if (document.all) {
			$('connector').style.marginTop = '-10px'
			$('musicPreview').style.marginTop = '-10px'
		}
	}
}

var allMusicLoaded = false
var currentPrev = null
var currentPrevOwner = null

var stopPreview = function() {
	$('musicPreview').innerHTML = ''
}

var previewSong = function(song_url, cb) {
	stopMusic()
	stopPreview()
	writeHtml("musicPreview", "<embed wmode='transparent' allowScriptAccess='always' width='1' height='1' src='http://"+widget_domain+"/widgets/musicplayer.swf?rn=" + Math.floor(Math.random()*100000) + "' flashvars='url=" + song_url + "&cb=" + cb + "' />")
}

var stopCurrentPreview = function() {
	if (currentPrev) {
		stopPreview()
		currentPrevOwner.setListen(currentPrev)
	}
}

var hideFlashDivs = function() {
	var tickerdiv = $("tickerdiv");
	if (tickerdiv) {
		tickerdiv.style.visibility = "hidden"
			}

	var arrangeArea = $("arrangeArea");
	if (arrangeArea) {
		arrangeArea.style.visibility = "hidden"
			}
}
var showFlashDivs = function() {
	var tickerdiv = $("tickerdiv");
	if (tickerdiv) {
		tickerdiv.style.visibility = "visible"
			}

	var arrangeArea = $("arrangeArea");
	if (arrangeArea) {
		arrangeArea.style.visibility = "visible"
			}
}

var _music_qry = '';
var showAllMusic = function(qry) {
	hideFlashDivs();
	hideBulkUploader();
	if (qry){
		_music_qry = qry;
	}
	return displayDimmed('allmusic', showAllMusicFrame, false);
}

var showAllMusicFrame = function() {
	stopCurrentPreview()
	$('songsArea').innerHTML = '<iframe name="allMusicFrame" id="allMusicFrame" style="width:100%; height:100%" src="/music_frame?large=true&genre=0&qry=' + _music_qry + '" frameborder="0"></iframe>';
	return false;
}

var dismissAllMusic = function() {
	showFlashDivs();
	stopCurrentPreview()
	return dismissDimmed('allmusic', redisplayBulkUploader);
}

var readStickerStorage = function(initData){
	if (initData){
		return initData;
	}
	var storageArea = $('songStorageArea');
	var data = [];
	if (storageArea){
		data = storageArea.value || '[]' ;
		data = evalJSON(data);
	}
	return data;
}

var readSongInfo = function() {
	var jsonSong = $('songStorageArea').value
	if (jsonSong) {
		var psongs = evalJSON(jsonSong)
		if (psongs && psongs.length > 0) {
			return songAsXML(psongs[0])
		}
	}
	return null
}

var songAsXML = function(song) {

	var songXML = ARRAY(
		DICT(
			KEY("cid"), STRING(song.cid),
			KEY("type"), INTEGER(song.type),
			KEY("sid"), INTEGER(song.sid),
			KEY("data"), STRING(song.data),
			KEY("id"), STRING(song.id),
			KEY("metadata"), DICT(
				KEY("music_url"), STRING(song.metadata.music_url),
				KEY("artist"), STRING(song.metadata.artist),
				KEY("url"), STRING(song.metadata.url),
				KEY("alphaas"), STRING(song.metadata.alphaas),
				KEY("label"), STRING(song.metadata.label),
				KEY("album_url"), STRING(song.metadata.album_url),
				KEY("title"), STRING(song.metadata.title),
				KEY("media_type"), INTEGER(song.metadata.media_type),
				KEY("id"), INTEGER(song.metadata.id)
				)));

	return songXML;
}

var connectCall = function(command) {
	if (command){
		var fl = '<embed swliveconnect="true" src="http://' + widget_domain + '/widgets/connect.swf"'
		+ ' quality="high" bgcolor="transparent" width="1" height="1" align="middle" wmode="transparent"'
		+ ' flashvars="' + command + '" allowScriptAccess="always"'
		+ ' type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"/>';
		$('connector').innerHTML = fl;
	}
	return false;
}

var stopMusic = function() {
	command = 'c=slide_connect&connect=${timestamp}&m=connectEvent&e=stopMusic';
	connectCall(command);
	return false;
}

var removeSong = function(supressRefresh) {
	$('songStorageArea').value = '[]'
	setMusicStatus(0)
	currentSongObj = null
	if (!supressRefresh) {
		readSettingsControl()
	}
	return false;
}

var currentSongObj = null

var resetPreviews = function() {
	stopCurrentPreview()
	jogCustomize()
}

var setAutoplay = function(playSong) {
	if (currentSongObj) {
		addSong(currentSongObj, playSong ? "true" : "false")
		readSettingsControl()
	}
}

var toggleSwitch = function() {
	sw1 = $('switchup1')
	sw2 = $('switchup2')

	sw1.style.display = sw1.style.display == 'block' ? 'none' : 'block'
	sw2.style.display = sw2.style.display == 'block' ? 'none' : 'block'
}


var ShowRegularUploader = function(toggle) {
	$('flashuploader').style.display = 'none'
	$('batchuploader').style.display = 'none'
	$('regupload').style.display = 'block'
	$('oldschoolupload').style.display = 'block'

	if (toggle) toggleSwitch()
	return false;
}


var ShowFlashUploader = function(toggle) {
	$('regupload').style.display = 'none'
	$('batchuploader').style.display = 'none'
	$('oldschoolupload').style.display = 'none'

	$('flashuploader').style.display = 'block'

	writeFlashUploader()

	if (toggle) toggleSwitch()
	return false;
}


var ShowBulkUploader = function(toggle, thin) {
	$('regupload').style.display = 'none'
	$('flashuploader').style.display = 'none'
	$('oldschoolupload').style.display = 'none'

	$('batchuploader').style.display = 'block'
	if (thin) {
		ImageUploader_GetObject(upload_activex_url, "batchuploader", 260, 220, "Drop files here or click the 'Select Images' button");
	} else {
		ImageUploader_GetObject(upload_activex_url, "batchuploader", 336, 220, "Drop files here or click the 'Select Images' button below");
	}

	if (toggle) toggleSwitch()
	return true;
}

var setScarcity = function(scarce) {
	var cForm = $$('custform')
	cForm.scarcity.value = scarce
}
