/*! @header
	Web workflow functions.  This header includes both
	editing support and drag and drop suport.

	@indexgroup Photo Gallery (JavaScript)
 */

/*! An object used for the drag and drop handler. */
var global_dragobj = null;

/*! Pads a number with zeroes. */
function zeroformat_photos(num, digits){
    var newnum = num + "";
    while (newnum.length < digits) {
	newnum = "0" + newnum;
    }
    return newnum;
}

/*! Generates a random number to work around bugs in some early browsers
    that would otherwise make it hard to disable caching of XMLHttpRequest
    requests.
 */
function randrequest()
{
    // Ensure that broken caching in old Safari versions doesn't
    // screw things up.
    var expdate = new Date();
    var exptime = expdate.getTime();
    expdate.setTime(exptime);
    var timestamp = expdate.toGMTString();

    year = timestamp.substring(0, 4);
    month = timestamp.substring(4, 6);
    day = timestamp.substring(6, 8);
    hour = timestamp.substring(8, 10);
    minute = timestamp.substring(10, 12);
    second = timestamp.substring(12, 14);
    return '&randomjunk='+zeroformat_photos(year,4)+"-"+zeroformat_photos(month, 2)+"-"+zeroformat_photos(day,2)+" "+zeroformat_photos(hour,2)+":"+zeroformat_photos(minute,2)+":"+zeroformat_photos(second,2);
}

/*! Allocates an XMLHttpRequest object and returns it. */
function getxmlhttpobj()
{
               /* This code block liberally lifted from the example code
                   at http://jibbering.com/2002/4/httprequest.html */
                var xmlhttp=false;
		var ie_is_broken = 1;
                /*@cc_on @*/
                /*@if (@_jscript_version >= 5)
                // JScript gives us Conditional compilation, we can cope with old IE versions.
                // and security blocked creation of the objects.
                 try {
                  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
                 } catch (e) {
                  try {
                   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                  } catch (E) {
                   xmlhttp = false;
                  }
                 }
                @end @*/
                if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
                  xmlhttp = new XMLHttpRequest();
		  ie_is_broken = 0; // real browsers work this way....
                }
                /* End lifted block */
		/* That page now suggests this addition: */
		if (!xmlhttp && window.createRequest) {
			try {
				xmlhttp = window.createRequest();
			} catch (e) {
				xmlhttp=false;
			}
		}
		/* End addition */

                if (xmlhttp && !ie_is_broken) {
                        xmlhttp.cachecontrol = "no-cache";
                }

                if (!xmlhttp) {
                        alert('Uploading content to this site requires xmlhttp support.  Please update your browser.');
			return false;
                } else {
                        /* Let's give this a shot. */
                        // start = parseInt(form.alterLabEntryStart.value, 10);
                        // setSpinner(eid, 1);
                }

	return xmlhttp;
}

/*! Clear an activity spinner.  Curretly just displays an alert. */
function clearspinner(elt)
{
	alert("done.\n");
}

/*! Starts an activity spinner.  Curretly just displays an alert. */
function setspinner(elt, changetype)
{
	alert("Changing "+changetype+".  Please be patient.\n");
}

/*! This works around FireFox's unbelievable suckage---a workaround
    for yet another brain-damaged FireFox bug that has been left
    unfixed for years and years....  And people wonder why I refuse
    to support anything but Safari....
 */
function getname(element)
{
	if (element.name !== undefined) { return element.name; }
	return element.getAttribute('name');
}

/*! Obtains the immediate child element of the specified element whose ID
    matches the specified ID.  Returns null if an element with matching ID
    is not an immediate child of the specified element.
 */
function getChildById(element, id)
{
	for (var i=0; i<element.childNodes.length; i++) {
		// alert('element '+element.childNodes[i]+' id: '+
			// element.childNodes[i].id);
		if (element.childNodes[i].id == id) {
			return element.childNodes[i];
		}
	}
	return null;
}

/*! Returns the filename portion of a path. */
function basename(path)
{
	var lastpos = -1;
	for (var i=0; i<path.length; i++) {
		if (path[i] == '/') { lastpos = i; }
	}
	return path.substring(lastpos+1, path.length);
}

/*! Returns the width of the current window. */
function getWinWidth()
{
var winH, winW;
if (parseInt(navigator.appVersion, 10)>3) {
 if (navigator.appName=="Netscape") {
  winW = window.innerWidth;
  winH = window.innerHeight;
 }
 if (navigator.appName.indexOf("Microsoft")!=-1) {
  winW = document.body.offsetWidth;
  winH = document.body.offsetHeight;
 }
}
return winW;
}

/*! Returns the height of the current window. */
function getWinHeight()
{
var winH, winW;
if (parseInt(navigator.appVersion, 10)>3) {
 if (navigator.appName=="Netscape") {
  winW = window.innerWidth;
  winH = window.innerHeight;
 }
 if (navigator.appName.indexOf("Microsoft")!=-1) {
  winW = document.body.offsetWidth;
  winH = document.body.offsetHeight;
 }
}
return winH;
}

/*! Returns true if position: relative is supported.  Maybe. */
function supports_position_relative()
{
    var debugging = 0;
    var elt;
    if (document.layers) {
	if (debugging) { alert('layers'); }
	elt = document.layers['trashlayer'];
        if (!elt) { return 2; } // No trash layer.  Bye.
    } else if (document.all) {
	if (debugging) { alert('all'); }
	elt = document.all['trashlayer'];
	if (!elt) { return 2; } // No trash layer.  Bye.
    } else if (document.getElementById) {
	if (debugging) { alert('getElementById'); }
	elt = document.getElementById('trashlayer');
	if (!elt) {
		return 2; // No trash layer.  Bye.
	}
    }
    pos = elt.style.position;
    if (elt.currentStyle) {
	pos = elt.currentStyle.position;
	// alert('cs: '+elt.currentstyle);
    }
    if (pos === "" && document.defaultView && document.defaultView.getComputedStyle) {
	pos = document.defaultView.getComputedStyle(elt, '').getPropertyValue('position');
    }
    if (pos === "") {
	/* If we don't have getComputedStyle, all we can do is
	   try to set the value and see if it sticks.
	 */
	elt.style.position = "fixed";
	pos = elt.style.position;
	if (elt.currentStyle) {
		pos = elt.currentStyle.position;
		// alert('cs: '+elt.currentstyle);
	}
    }

    // alert('pos: '+pos);
    if (pos != 'fixed') {
	elt.style.position = 'absolute'; 
	elt.style.bottom='80px';
	elt.style.right='20px';
	return 0;
    }
    return 1;
	// alert('left is '+document.body.scrollLeft);
	// alert('width is '+width);
}

/*! Returns the location of the top edge of an element. */
function getTop(elt)
{
	if (elt.tagName == 'BODY') { return 0; }
	return elt.offsetTop + getTop(elt.offsetParent);
}

/* From http://www.irt.org/script/875.htm (customized & fixed for DOM) */
/*! Moves the trash can (dumpster) around on the screen.
    From http://www.irt.org/script/875.htm (customized & fixed for DOM)
 */
function pageOffset() {
    var debugging = 0;
    var support = supports_position_relative();

	// alert('support is '+support);

    if (!support) {
	commentbox = document.getElementById('commentbox');
	if (!commentbox) {
		// alert('no commentbox');
		setTimeout(pageOffset,1000); // once a second
		return;
	}
	var height = getWinHeight();
	var width = getWinWidth();
	var top_of_comment_box = getTop(commentbox);
	// var height = getHeight(commentbox);;
	// var bottom = top + height;
		// alert('bottom: '+bottom+' top: '+top+' height: '+height);
	// if (bottom) {
		// alert('bottom: '+bottom);
	// }
		// alert('height:' + height);
	if (debugging) { alert('height: '+height+' width: '+width+' topofcomments: '+top_of_comment_box); }
	var vpos = 0;
	if (document.layers) {
		if (debugging) { alert('layers'); }
        	if (!document.layers['trashlayer']) { return; } // No trash layer.  Bye.
        	document.layers['trashlayer'].pageX = window.innerWidth - 20;
		vpos = window.innerHeight + height - 80; // Should this be 80?
		if (vpos > top_of_comment_box - 100) { vpos = top_of_comment_box - 100; }
        	document.layers['trashlayer'].pageY = vpos;
	} else if (document.all) {
		if (debugging) { alert('all'); }
		if (!document.all['trashlayer']) { return; } // No trash layer.  Bye.
        	document.all['trashlayer'].style.left = document.body.scrollLeft + width - 84;
		vpos = document.body.scrollTop + height - 80;
		if (vpos > top_of_comment_box - 100) { vpos = top_of_comment_box - 100; }
        	document.all['trashlayer'].style.top = vpos;
	} else if (document.getElementById) {
		if (debugging) { alert('getElementById'); }
		var elt = document.getElementById('trashlayer');
		if (!elt) {
			return; // No trash layer.  Bye.
		}
        	elt.style.left = document.body.scrollLeft + width - 84;
        	// elt.style.left = -80;
			// alert('elt is '+elt);
		vpos = document.body.scrollTop + height - 80; // height - 80;
		
		if (vpos > top_of_comment_box - 100) { vpos = top_of_comment_box - 100; }
        	elt.style.top = vpos;
		// alert('left is '+elt.style.left);
	}
	// alert('left is '+document.body.scrollLeft);
	// alert('width is '+width);
    }
 /*
    var elt = document.getElementById('trashcan');
    var trashcanheight = 20 + elt.offsetHeight;
    if (trashcanheight == 20) { trashcanheight = 100; } // overdo it initially.
    var height = getWinHeight();
    var spacerheight = 500;
    if (height) {
	spacerheight = height - trashcanheight;
    }
    elt = document.getElementById('trashspacer');
    elt.height = spacerheight; elt.width = 1;
	// alert('height = '+height);
	// alert('dl: '+document.layers+' da: '+document.all);
  */
    if (support != 1) {
	setTimeout(pageOffset,1000); // once a second
    }
}

pageOffset();

/*! Finds the IMG element whose name matches the specified value. */
function findImgByName(name)
{
	var elts = document.getElementsByName(name);
	if (!elts.length) {
		alert('Could not find any elements for name '+name+' [FIBN]');
	}
	for (var i=0; i< elts.length; i++) {
		if (elts[i].tagName == 'IMG') {
			return elts[i];
		// } else {
			// alert('name: '+elts[i].tagName);
		}
	}
	return null;
}

/*! Finds the DIV element whose name matches the specified value. */
function findDivByName(name)
{
	var elts = document.getElementsByName(name);
	if (!elts.length) {
		alert('Could not find any elements for name '+name+' [FDBN]');
	}
	for (var i=0; i< elts.length; i++) {
		if (elts[i].tagName == 'DIV') {
			return elts[i];
		// } else {
			// alert('name: '+elts[i].tagName);
		}
	}
	return null;
}

/*! Returns the immediate child whose name matches the specified name
    and whose tag name matches the specified tag name.
 */
function findChildByName(elt, name, tagname)
{
    if (!elt) { return null; }
    var fc = elt.firstChild;
    while (fc) {
	// alert('fc is '+fc+', fc.name is '+fc.name);
	if ((fc.tagName == tagname) && (fc.name == name)) { return fc; }
	var nested = findChildByName(fc, name, tagname);
	if (nested) { return nested; }
	fc = fc.nextSibling;
    }
}

/*! Makes a folder icon dark when the user drags something over it. */
function makedark(elt, setdark)
{
	var darksrc = elt.getAttribute("selectedpath");
	var lightsrc = elt.getAttribute("normalpath");
	var darkcountstr = elt.getAttribute("darkcount");
	var darkcount = 0;
	if (darkcountstr) { darkcount = parseInt(darkcountstr, 10); }

	// alert('makedark: '+darksrc+', '+lightsrc);
	// alert('makedark: '+setdark+' dc: '+darkcount);

	if (!darksrc || !lightsrc) { return; } // Don't do anything if we can't fix it.
	if (!darksrc.length || !lightsrc.length) { return; } // Don't do anything if we can't fix it.

	if (setdark == 1) { darkcount++; }
	else if (setdark == -1) { darkcount = 0; }
	else { darkcount--; }

	if (darkcount) { elt.src = darksrc; }
	else { elt.src = lightsrc; }
	elt.setAttribute("darkcount", darkcount);
}

/*! Called when an item begins hovering over a folder. */
function folderdrag_enter(elt)
{
        // alert('folder drag enter '+elt.id);
        if (window.event) { window.event.returnValue=false; }
	if (elt.tagName == "IMG") {
		makedark(elt, 1);
	} else if (elt.tagName == "DIV") {
		newelt = findImgByName(getname(elt));
		if (newelt) {
			makedark(newelt,1);
		}
	}
        return true;
}

/*! Sets the global drag object.  Called when the user drags something. */
function itemdrag_set(elt, event)
{
	global_dragobj = elt;
	// alert('itemdrag_set called (global_dragobj is now '+elt+')');
	// event.preventDefault();
	// setDragImage(
}

/*! Clears the global drag object.  Called when the user finishes
    dragging something.
 */
function itemdrag_clear(elt, event)
{
	global_dragobj = null;
	// setDragImage(
}

/*! Called when an item is no longer hovering over a folder. */
function folderdrag_exit(elt)
{
        // alert('folder drag exit '+elt.id);
	if (elt.tagName == "IMG") {
		makedark(elt, 0);
	} else if (elt.tagName == "DIV") {
		newelt = findImgByName(getname(elt));
		if (newelt) {
			makedark(newelt,0);
		}
	}
}

/*! Returns true if you can drop something on a folder. */
function folderdrag_candrop(elt)
{
	// alert("candrop called\n");
        return true;
}

/*! Checks a Safari version for a bug workaround.  Safari does not allow
    timer events to fire after a page load starts.  This Safari bug was
    fixed in 3.1.1.
 */
function safari_is_broken()
{
	for (var pos = 0; pos < navigator.userAgent.length; pos++) {
		if (navigator.userAgent.substring(pos, pos+7) == "Safari/") {
			for (var endpos = pos+7; endpos < navigator.userAgent.length; endpos++) {
				if (navigator.userAgent[endpos] == " " ||
				    navigator.userAgent[endpos] == "\r" ||
				    navigator.userAgent[endpos] == "\n") { break; }
			}
			var versionstr = navigator.userAgent.substring(pos+7, endpos);
			var version = parseFloat(versionstr);
			// alert('version is '+version);
			if (version < 525.18) { return 1; }
			return 0;
		}
	}
	return 0;
}

// alert('sib: '+safari_is_broken());

/*! Builds the contents of the progress bar. */
function buildbar(statusline, statusbar, data)
{
    var line;
    var rawval1, rawval2;
    var val1, val2;
    var name;
    var pos;
    var barstring = "";
    if (!data) { data = ""; }
    line = data;
	// alert('data: '+line);

    for (pos = 0; pos < data.length; pos++) {
	if (data[pos] == '\n') {
		line = data.substring(0, pos); // or substr.  either way.
		break;
	}
    }

    var colonpos = -1;
    for (pos = 0; pos < line.length; pos++) {
	if (line[pos] == ':') {
		colonpos = pos;
		break;
	}
    }
    var slashpos = -1;
    for (; pos < line.length; pos++) {
	if (line[pos] == '/') {
		slashpos = pos;
		break;
	}
    }
    name = line.substring(0, colonpos);
    rawval1 = line.substring(colonpos + 2, slashpos);
    rawval2 = line.substring(slashpos + 1, line.length);
    val1 = parseInt(rawval1, 10);
    val2 = parseInt(rawval2, 10);
    // alert('name: '+name+', val1: '+val1+', val2: '+val2);
    if (!rawval1.length) {
	val1 = 0;
	val2 = 0;
	bluewidth = 0;
	whitewidth = 200;
    } else {
	bluewidth = Math.floor((val1 / val2) * 200);
	whitewidth = 200 - bluewidth;
    }
    barstring += "<nobr>";
    barstring += "<img src='/icons/bigprogress_left.png' alt='' height='24' width='8'>";
    barstring += "<img src='/icons/bigprogress_blue.png' alt='' height='24' width='"+bluewidth+"'>";
    barstring += "<img src='/icons/bigprogress_white.png' alt='' height='24' width='"+whitewidth+"'>";
    barstring += "<img src='/icons/bigprogress_right.png' alt='' height='24' width='8'>";
    barstring += "</nobr>";

    statusline.innerHTML = ""+val1+"/"+val2+" bytes";
    got1 = statusline.getAttribute("got1");
    if (val1) {
	statusline.setAttribute("got1", "1"); // set it for next time
    }
    statusbar.innerHTML = barstring;
    if (safari_is_broken()) {
	if ((val1 || got1) && (val1 == val2)) {
		window.close();
	}
    }
}

/*! Draws the process bar for uploads. */
function drawbar(data)
{
	var textspan=document.getElementById("statusline");
	var barspan=document.getElementById("statusbar");

	if (!textspan) {
		alert('Could not find span statusline.');
		return;
	}
	if (!barspan) {
		alert('Could not find span statusbar.');
		return;
	}
	// textspan.visibility = "hidden";
	buildbar(textspan, barspan, data);
}

/*! Returns true if the filename is of a supported type. */
function valid_filename(file)
{
    var ext3 = file.substr(-4, 4).toLowerCase();
    var ext4 = file.substr(-5, 5).toLowerCase();
    if (ext3 == ".jpg" || ext3 == ".gif" ||
        ext3 == ".tif" || ext4 == ".tiff" ||
        ext4 == ".jpeg" || ext3 == ".png" ||
	ext3 == ".zip" || ext3 == ".cr2" ||
	ext3 == "crw") {
        return 1;
    }
    return 0;
}

/*! Enables the submit button after you have chosen a file to upload. */
function enable_sub(eltid)
{
    var uploadelt = document.getElementById("fileUpload");
    if (!uploadelt) {
	alert("couldn't find element with id fileUpload\n");
	return;
    }
    var form = uploadelt.form;
    var path = uploadelt.value;
    var filename = basename(uploadelt.value);

    if (!valid_filename(filename)) {
	alert("Not a recognized image file format.  Supported formats are GIF, JPEG, TIFF, and PNG.\n");
	form.reset();
	return;
    }

    var elt = document.getElementById(eltid);
	// alert('elt is '+elt);
    if (!elt) {
	alert("couldn't enable submit button.");
	return;
    }
    elt.disabled = false;
}

/*! Cleans up the filename of a file that you are uploading. */
function sanitize_filename(filename)
{
    var i;
    var ret = "";
    for (i=0; i<filename.length; i++) {
	var ch = filename.substring(i, i+1);
	
        // if (ch == ' ') ch='_';
        // if (ch == "\t") ch='_';
        if (ch == "\t") { ch=' '; }
        if (ch == '%') { ch='_'; }
        if (!(ch == '.' || ch == ',' || (ch >='0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_' || ch == '-' || ch == ' ' || ch == "'")) {
                ch='_'; 
        }
	ret = ret + ch;
    }
    return ret;
}

/*! Disables the submit button.  Called at page load time. */
function disable_sub(eltid)
{
    var elt = document.getElementById(eltid);
	// alert('elt is '+elt);
    if (!elt) {
	alert("couldn't disable submit button.");
	return;
    }
    elt.disabled = true;
}

/*! This is called by an anonymous function in {@link backendrename backendrename}
    when a file has just been renamed.  If the rename fails, this function displays
    an alert and resets the filename field to its previous value.
 */
function clearspinnerandtitle(response)
{
	// alert('response is '+response);
    var lines = response.split('\n');
    var eltname = lines[0];
    var status = lines[1];
    var redirecturl = "";

    var divelt = findDivByName(eltname);
    // alert('divelt: '+divelt+' for eltname '+eltname);
    var inputelt = findChildByName(divelt, eltname, "INPUT");
    var anchorelt = findChildByName(divelt, eltname, "A");
    var imageelt = findChildByName(divelt, eltname, "IMG");

    if (status == "Redirect.") {
	redirecturl = lines[2];
	document.location = redirecturl;
    } else if (status == "Success.") {
	clearspinner(inputelt);
	// alert('inputelt: '+inputelt);
	inputelt.setAttribute('name', inputelt.value);
	imageelt.setAttribute('name', inputelt.value);
	divelt.setAttribute('name', inputelt.value);
	anchorelt.setAttribute('name', inputelt.value);
	if (anchorelt.href.indexOf('/')) {
		anchorelt.href='index.php/'+inputelt.value;
	} else {
		anchorelt.href=inputelt.value;
	}
	// alert('Name is now '+inputelt.name+' (elt is '+inputelt+', eltname is '+eltname+').');
    } else {
	alert("Rename failed.  Response from server was: "+status);
	// alert("Rename failed.  Raw response from server was: "+response);
	inputelt.value = inputelt.name;
	// alert('inputelt: '+inputelt);
    }
}

function start_broken_safari_box()
{
	var elt = document.getElementById("fileUpload");
	if (!elt) {
		alert("couldn't find element with id fileUpload\n");
		return;
	}
	var path = elt.value;
	var filename = basename(elt.value);
	filename = escape(sanitize_filename(filename));
	var elt2 = document.getElementById("fileUploadID");
	var fileuploadid = parseInt(elt2.value, 10);

	var url = 'index.php?uploadmonitor='+filename+'&fileUploadID='+fileuploadid;

	window.open(url, "status", "width=250,height=180");
}

/*! Updates the contents of the progress bar once. */
function updatebar()
{
	var xmlhttp = getxmlhttpobj();
	var url;
	var elt = document.getElementById("fileUpload");
	if (!elt) {
		alert("couldn't find element with id fileUpload\n");
		return;
	}
	var path = elt.value;
	var filename = basename(elt.value);
	filename = escape(sanitize_filename(filename));
	var elt2 = document.getElementById("fileUploadID");
	var fileuploadid = parseInt(elt2.value, 10);

	url = '/savefilestatus.php?filename=' + filename + '&fileUploadID=' + fileuploadid;

	xmlhttp.open("GET", url+randrequest(), true);
	xmlhttp.onreadystatechange=function() {
		if (xmlhttp.readyState==4) {
			// alert(xmlhttp.responseText)
			drawbar(xmlhttp.responseText);
		}
	};
	xmlhttp.send(null);
}

/*! Updates the upload progress bar in a timeout loop. */
function autoupdatebar()
{
    updatebar();
    setTimeout(autoupdatebar, 2000);
}

/*! Starts the upload progress bar. */
function startbar()
{
    if (safari_is_broken()) {
	start_broken_safari_box();
	return true;
    }
    setTimeout(autoupdatebar, 2000);
    return true;
}

/*! Takes the current URL, strips off any current GET request,
    appends index.php to the end if necessary, and returns
    the resulting string after appending the value of
    <code>command</code>.
 */
function getindexlocation(command)
{
	var loc = document.location.href;

	var trunc = loc.indexOf('?');
	if (trunc != -1) {
		loc = loc.substring(0, trunc);
	}

	// alert('loc is '+typeof(loc)+": "+loc);

	if (loc.substring(loc.length-9, loc.length) == 'index.php') {
		loc = loc + '?' + command;
	} else if (loc.substring(loc.length-10, loc.length) == 'index.php/') {
		loc = loc.substring(0, loc.length-1) + '?' + command;
	} else {
		if (loc[loc.length-1] != '/') {
			loc = loc + '/';
		}
		loc = loc + 'index.php?' + command;
	}
	return loc;
}

/* Lifted from code example at irt.org. */
/*! Extracts the raw filename from a file selection input element.
    Lifted from code example at irt.org.
 */
function namefromfield(field) {
    if (field.indexOf('/') > -1) {
        answer = field.substring(field.lastIndexOf('/')+1,field.length);
    } else {
        answer = field.substring(field.lastIndexOf('\\')+1,field.length);
    }
    return answer;
}       

/*! Handles moving a file when the user drags and drops it on a folder. */
function handle_move(source, destination)
{
	var command = "moverename=1&file="+escape(source)+"&dest="+escape(destination);
	var loc = getindexlocation(command);

	// alert('new location will be '+loc);

	document.location = loc;
}

/*! Handles deletion of a file. */
function handle_delete(file)
{
	var command = "deleteimage=1&file="+escape(file);
	var loc = getindexlocation(command);

	// alert('new location will be '+loc);

	document.location = loc;
}

/* Junk function */
function handle_external_data(dt, cd)
{
return; // NOT IMPLEMENTED.
	// alert('dt is '+dt);
	// alert("Typelist: "+dt.types);
/*
	alert('Clipboard data: '+cd);
	for (var i=0; i<dt.types.length; i++) {
		// alert("Type "+dt.types[i]);
		var data = dt.getData(dt.types[i]); // "image/jpeg");
		if (data !== undefined) {
			alert("Type "+dt.types[i]+".  data is "+data+' length '+data.length);
		} else {
			alert("Type "+dt.types[i]+".  data is "+data);
		}
	}
 */
	var mybody=document.getElementsByTagName("body").item(0);
	var uri = dt.getData(dt.types[1]);
	// var fourbyte = dt.getData(dt.types[2]);
	// var sixteenbyte = dt.getData(dt.types[6]);

	var rawdata = dt.getData("NSStringPboardType");
	// alert('fourbyte length: '+fourbyte.length);
	// alert('sixteenbyte length: '+sixteenbyte.length);
	alert('uri is '+uri);
	alert('rawdata is '+rawdata);
	if (rawdata) { alert('rawdata length is '+rawdata.length); }
	var imgelt = document.createElement("img");
	var canvas = document.createElement("canvas");
	canvas.setAttribute("height", 3000);
	canvas.setAttribute("width", 3000);
	// canvas.width=500;
	// canvas.height=500;
	canvas.id="tempcanvas";
	imgelt.src = "http://www.gatwood.net/testphotos/MiniCache/IMG_4359.JPG";
	// imgelt.src = uri;
	mybody.appendChild(imgelt);
	mybody.appendChild(canvas);
	canvas = document.getElementById("tempcanvas");
	var context = canvas.getContext("2d");
	// context.fillRect(0,0,100,100);
	// context.fillRect(600,600,1000,1000);
	context.drawImage(imgelt, 0, 0);

/*
	var divelt = document.createElement("div");
	divelt.innerHTML="<input id='data' type='file' value='"+uri+"'>";
	mybody.appendChild(divelt);
	var inputelt = document.getElementById('data');
	var data = inputelt.data;
	alert('data is '+data);
*/

	return true;
}

/*! Handler called when a user starts to drag a file. */
function filedrag_start(elt)
{
        // alert('drag start of file '+elt.id);
}

/*! Handler called when a user finishes dragging a file. */
function filedrag_end(elt)
{
        // alert('drag end of file '+elt.id);
}

/*! Drop handler for folders.  Called when the user drops something on
    a folder.
 */
function folderdrag_drop(elt, event)
{
	var myevent = event;

	if (!event) { myevent = global_DAG_event; }

	// alert('bare event '+myevent);
	// alert('dragsource '+myevent.dragSource);
	// alert('event elt: '+elt.id);

	var elt2name = null;
	var dt = null;
	var cd = null;
	myevent.preventDefault();
	if (myevent.dragSource) {
		elt2name = myevent.dragSource.domNode.name;
	} else {
		// if (myevent.dataTransfer) {
			// dt = myevent.dataTransfer;
			// cd = myevent.clipboardData;
			if (global_dragobj) {
				elt2name = getname(global_dragobj);
				// alert('global_dragobj is '+global_dragobj+'name: '+name+' alt: '+elt2alt);
				dt = null;
				cd = null;
			} else {
				// Silently avoid double submit.
				// alert('make light'+elt);
				folderdrag_exit(elt);
				return;
			}
			// alert('TYPES: '+dt.types);
			// alert('ep:'+myevent.target);
			// for (var i=0; i<dt.types.length; i++) {
				// alert("Type "+dt.types[i]);
			// }
			// dt.getData()
			// elt2name = "3";
			// elt2name = myevent.srcElement.name;
			// alert('myevent.currentTarget = '+myevent.currentTarget.name);
			// alert('myevent.srcElement = '+myevent.srcElement.name);
		// } else {
			// alert("Can't get drag object info.");
			// itemdrag_clear();
			// return false;
		// }
	}

	// alert('search for source div with name '+elt2name);

	/* Don't bother submitting.  You'd jsut get a "permission denied"
	   error. */
	var ddstring = elt.getAttribute("dropDisabled");
	var dd = 0;
	if (ddstring) { dd = parseInt(ddstring, 10); }
	if (dd) {
		makedark(newelt,-1);	// Work around a FireFox
					// "stuck highlight" bug.
		return false;
	}

	var destination_folder = findDivByName(getname(elt));
	var source_object = null;
	if (elt2name) {
		source_object = findDivByName(elt2name);
	}

	if (!source_object && !dt) {
		alert('source object div could not be located.');
		itemdrag_clear();
		return false;
	}
	if (!destination_folder) {
		alert('destination folder div could not be located.');
		itemdrag_clear();
		return false;
	}

	if (source_object) {
		source_object_name = getname(source_object);
	} else {
		return false;
		// handle_external_data(dt, cd);
		// source_object_name = "external data";
	}

        // alert('dropped '+source_object_name+' on folder '+getname(destination_folder));
	// return;
	if (destination_folder.id == 'trashlayer') {
		handle_delete(source_object_name);
	} else {
		handle_move(source_object_name, getname(destination_folder));
	}

	itemdrag_clear();
	return true;
}

/*! Called when a file upload is submitted.  This sanitizes the arguments. */
function doupload(form, event)
{
	alert('doupload called: '+form);

	var pathelt = getChildById(form, "filename");
	if (!pathelt) {
		alert("code error: can't get filename element.");
		return false;
	}
	var path = namefromfield(pathelt.value);
	var filename = basename(path);
	filename = sanitize_filename(filename);

	alert('filename is '+filename);
	for (var j = 0 ; j < form.elements.length; j++) {
		alert('element '+j+' = '+form.elements[j].value);
	}

	var command = 'uploadfile=1&filename='+escape(filename);
	var indexloc = getindexlocation(command);

	var data = form.filename.value;
	alert('data length: '+data.length);
	// var httpobj = getxmlhttpobj()

	// alert('dataTransfer length:'+event.dataTransfer);
	// alert('form is '+form.filename.data);
	// Request.Form

	return false;
}

/*! Handles renaming of files by submitting with an XMLHttpRequest. */
function backendrename(elt)
{
	var source = elt.getAttribute('name'); // original name
	var destination = elt.value; // new name
	var command = "moverename=2&file="+escape(source)+"&dest="+escape(destination);
	var url = getindexlocation(command);

	// alert('elt was '+elt);
	if (!elt) {
		alert("Feature not implemented: trap close box.  Please file a bug.");
		return true;
	}
	var divelt = findDivByName(elt.name);
	setspinner(divelt, "name");
	xmlhttp = getxmlhttpobj();

	// alert('backend submission would be '+url); exit;

        xmlhttp.open("GET", url+randrequest(), true);
        xmlhttp.onreadystatechange=function() {
                if (xmlhttp.readyState==4) {
                        // alert(xmlhttp.responseText)
                        // drawbar(xmlhttp.responseText);
			clearspinnerandtitle(xmlhttp.responseText);
                }
        };
        xmlhttp.send(null);
}

/* In order of preference */
/*! Returns the height of an element. */
function getHeight(elt)
{
	if (elt.offsetHeight) {
		// alert('offset');
		return elt.offsetHeight;
	}
	if (elt.clientHeight) {
		// alert('client');
		return elt.clientHeight;
	}
	if (elt.innerHeight) {
		// alert('inner');
		return elt.innerHeight;
	}
	if (elt.style && elt.style.height) {
		// alert('style');
		return elt.style.height;
	}
	// alert('ouch');
	return elt.height;
}


/* Workarounds for Mozilla/Firefox's inferior Drag and drop implementation */
/*! Failed attempt to make drag and drop work on Mozilla/FireFox. */
function mozdragenter(elt)
{
	var countstring = elt.getAttribute("dragentercount");
	var count;

	// alert('dragenter: '+elt+' id: '+elt.id);

	if (!countstring) { count = 0; }
	else { count = parseInt(countstring, 10); }

	count++;

	elt.setAttribute("dragentercount", count);
}

/*! Failed attempt to make drag and drop work on Mozilla/FireFox. */
function mozdragexit(elt, event)
{
	var countstring = elt.getAttribute("dragentercount");
	var count;

	// alert('dragexit: '+elt+' id: '+elt.id+' event: '+event);

	if (!countstring) { count = 0; }
	else { count = parseInt(countstring, 10); }

	count--;

	if (count < 0) {
		var drophandler = elt.getAttribute("ondrop");
		if (drophandler) {
			// alert('drophandler: '+drophandler+' this: '+this+' elt: '+elt+' event: '+event);
			// drophandler
			elt._drophandler = function (event) {
				var drophandler = this.getAttribute("ondrop");
				// alert('dh: this is '+this+' event is '+event);
				global_DAG_event = event; // FireFox bug workaround
				return eval(drophandler);
			};
			return elt._drophandler(event);
		}
	} else {
		elt.setAttribute("dragentercount", count);
	}
}


/*! Failed attempt to make drag and drop work on Mozilla/FireFox. */
function setup_handlers(elt)
{
	var tmp;
	var partial_support = 0;
	// alert('elt is '+elt);

	// Work around Firefox not liking getAttribute on the document.
	if (!elt.getAttribute) { return; }

	// if (elt.getAttribute('ondrop')) {
		// if (elt.ondrop) {
			// alert('supported.');
		// }
	// }
	if ((tmp = elt.getAttribute('ondragenter'))) {
		// alert('ode: '+elt.id);
		if (elt.ondragenter) {
			// Yum.  It's supported.  We're done.
			partial_support = 1;
		} else {
			// alert('pre');
			if (elt.attachEvent) {
				elt.attachEvent('dragenter', function () { var tmp = this.getAttribute('ondragenter'); return eval(tmp); });
			} else {
				elt.addEventListener('dragenter', function () { var tmp = this.getAttribute('ondragenter'); var retval = eval(tmp); mozdragenter(this); return retval; }, false);
			}
			// alert('post');
		}
	}
	if ((tmp = elt.getAttribute('ondragleave'))) {
		if (elt.ondragleave) {
			// Yum.  It's supported.  We're done.
			partial_support = 1;
		} else {
			if (elt.attachEvent) {
				elt.attachEvent('dragexit', function () { var tmp = this.getAttribute('ondragleave'); return eval(tmp); });
			} else {
				elt.addEventListener('dragexit', function (event) { var tmp = this.getAttribute('ondragleave'); var retval = eval(tmp); mozdragexit(this, event); return retval; }, false);
			}
		}
	}
	if ((tmp = elt.getAttribute('ondragover'))) {
		if (elt.ondragover) {
			// Yum.  It's supported.  We're done.
			partial_support = 1;
		} else {
			if (elt.attachEvent) {
				elt.attachEvent('dragover', function () { var tmp = this.getAttribute('ondragover'); return eval(tmp); });
			} else {
				elt.addEventListener('dragover', function () { var tmp = this.getAttribute('ondragover'); return eval(tmp); }, false);
			}
		}
	}
	if ((tmp = elt.getAttribute('ondrop'))) {
		if (elt.ondrop) {
			// Yum.  It's supported.  We're done.
			partial_support = 1;
		} else {
			if (elt.attachEvent) {
				elt.attachEvent('ondrop', function () { var tmp = this.getAttribute('ondrop'); return eval(tmp); });
			// } else {
				/* FireFox handling is... um... magick. */
				// elt.addEventListener('dragdrop', function () { var tmp = this.getAttribute('ondrop'); return eval(tmp); }, false);
			}
		}
	}
	if ((tmp = elt.getAttribute('candrop'))) {
		if (elt.candrop) {
			// Yum.  It's supported.  We're done.
			partial_support = 1;
		} else {
			if (elt.attachEvent) {
				elt.attachEvent('ondragover', function () { var tmp = this.getAttribute('candrop'); return eval(tmp); });
				elt.attachEvent('ondragenter', function () { var tmp = this.getAttribute('candrop'); return eval(tmp); });
			 // } else {
				// elt.addEventListener('dragover', function () { var tmp = this.getAttribute('candrop'); var x = eval(tmp); var ds = Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nslDragService); var ses = ds.getCurrentSession(); if (ses) ses.canDrop = x;  }, false);
				// elt.addEventListener('dragenter', function () { var tmp = this.getAttribute('candrop'); var x = eval(tmp); var ds = Components.classes["component://netscape/widget/dragservice"].getService(Components.interfaces.nsIDragService); if (ds) { var ses = ds.getCurrentSession(); if (ses) {ses.canDrop = x; }}}, false);
				// elt.addEventListener('dragenter', function () { var tmp = this.getAttribute('candrop'); var x = eval(tmp); var ds = Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nslDragService); var ses = ds.getCurrentSession(); if (ses) ses.canDrop = x; }, false);
			}
		}
	}
	if ((tmp = elt.getAttribute('ondragstart'))) {
		if (elt.ondragstart) {
			// Yum.  It's supported.  We're done.
			partial_support = 1;
		} else {
			// alert ("dragstarthandler attaching.\n");
			if (elt.attachEvent) {
				elt.attachEvent('dragstart', function () { var tmp = this.getAttribute('ondragstart'); return eval(tmp); });
			} else {
				// elt.onDragStart = function () { var tmp = elt.getAttribute('ondragstart'); return eval(tmp); };
				elt.addEventListener('draggesture', function (event) { var tmp = this.getAttribute('ondragstart'); return eval(tmp); }, false);
			}
		}
	}
	if ((tmp = elt.getAttribute('ondragend'))) {
		if (elt.ondragend) {
			// Yum.  It's supported.  We're done.
			partial_support = 1;
		} else {
			if (elt.attachEvent) {
				elt.attachEvent('dragend', function () { var tmp = this.getAttribute('ondragend'); return eval(tmp); });
			} else {
				elt.addEventListener('dragend', function () { var tmp = this.getAttribute('ondragend'); return eval(tmp); }, false);
			}
		}
	}
}

/*! Failed attempt to make drag and drop work on Mozilla/FireFox. */
function setupdd_sub(elt)
{
	setup_handlers(elt);
	if (elt.nextSibling) {
		setupdd_sub(elt.nextSibling);
	}
	if (elt.firstChild) {
		setupdd_sub(elt.firstChild);
	}
}

/*! Failed attempt to make drag and drop work on Mozilla/FireFox. */
function setupdd()
{
	setupdd_sub(document);
}

/*! Called by an anonymous function in {@link changecomment changecomment} when a
    comment submission is complete.  If the change fails, the previous comment is
    restored and an error message is displayed.
 */
function clearspinnerandcomment(response)
{
    var lines = response.split('\n');
    var eltname = lines[0];
    var status = lines[1];
    var redirecturl = "";

    var divelt = findDivByName(eltname);
    // alert('divelt: '+divelt+' for eltname '+eltname);
    var inputelt = findChildByName(divelt, eltname, "TEXTAREA");
    var anchorelt = findChildByName(divelt, eltname, "A");
    var imageelt = findChildByName(divelt, eltname, "IMG");

    if (status == "Redirect.") {
	redirecturl = lines[2];
	document.location = redirecturl;
    } else if (status == "Success.") {
	clearspinner(inputelt);
	// alert('inputelt: '+inputelt);
	inputelt.setAttribute('name', inputelt.value);
	imageelt.setAttribute('name', inputelt.value);
	divelt.setAttribute('name', inputelt.value);
	anchorelt.setAttribute('name', inputelt.value);
	// alert('Name is now '+inputelt.name+' (elt is '+inputelt+', eltname is '+eltname+').');
    } else {
	alert("Comment change failed.  Response from server was: "+status);
	// alert("Comment change failed.  Raw response from server was: "+response);
	// alert('lines[2]'+lines[2]);
	// inputelt.value = lines[2];
	lines.shift(); // pop the filename off the front.
	lines.shift(); // pop the response off the front.
	inputelt.value = lines.join("\n");
	// alert('inputelt: '+inputelt);
    }
}

/*! Handler called when a user changes the comment field for an image. */
function changecomment(elt)
{
	var text = elt.value;
	var filename = elt.getAttribute('filename');
	// alert('change to '+text);

	var command = 'setcomment=1&file='+escape(filename)+'&comment='+escape(text);
	var url = getindexlocation(command);

	// alert('elt was '+elt);
	if (!elt) {
		alert("Feature not implemented: trap close box.  Please file a bug.");
		return true;
	}
	var divelt = findDivByName(elt.name);
	setspinner(divelt, "comment");
	xmlhttp = getxmlhttpobj();

	// alert('backend submission will be '+url);

        xmlhttp.open("GET", url+randrequest(), true);
        xmlhttp.onreadystatechange=function() {
                if (xmlhttp.readyState==4) {
                        // alert(xmlhttp.responseText)
                        // drawbar(xmlhttp.responseText);
			clearspinnerandcomment(xmlhttp.responseText);
                }
        };
        xmlhttp.send(null);
}

/*! Displays the photo gallery help alert. */
function photogal_help()
{
	string = "Photo Gallery Help\n\n";
	string += "* To rename files or folders, edit the name below it, then click outside the text box (not on a link, photo, or folder).\n";
	string += "* To move images or folderss into a subfolder or parent folder, drag them over the appropriate folder icon.\n";
	string += "* To upload files, use the upload box to the right.\n";
	string += "* To delete files, drag them to the dumpster of death.\n";
	string += "* To create new folders, or to recover recently deleted files, use the links to the left.\n";
	string += "\n";
	string += "If you do not have permission to complete a drag operation, the destination folder will turn red.\n";
	alert(string);
}

