// Copyright (2005) David Ritchie. All rights reserved.

// hacked on way of keeping track of editable images
var currentImage = undefined;
var imageParams = undefined;

/* a function to check for a particular class */
function elementHasClass(elem, n) {
    var c = elem.className.split(" ");
    // alert("has? " + elem + ", " + n);
    for (var i = 0; i < c.length; i++)
	if (c[i] == n)
	    return 1;
    return 0;
}

// load in another external JS file
function loadJS(s) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = s;
    document.getElementsByTagName('head')[0].appendChild(script);  
}

/* switch to edit mode... */
function editMode2() {

    // Lines by Stephen
    loadJS('/scripts/s-mouse.js');
    loadJS('/scripts/s-editable-image.js');

    // alert('edit mode 2');
    var e = document.body.getElementsByTagName('span');
    var s = '';
    // I'm not going to rely on editHandlers to make all text and pictures editable any more.
    for (var i=0; i<e.length; i++)
	if (elementHasClass(e.item(i), "editHandler") ||
	    elementHasClass(e.item(i), "saveEditHandler")) {
	    s = s + e.item(i).firstChild.id + ';';
	}
	    //	if (e.item(i).className == 'editHandler' ||
	    //	    e.item(i).className == 'saveEditHandler')

    rcall('editMode.xml',s);

    // *** This is WRONG - it means image scaling works even if you don't login. It doesn't matter much because you can't save
	e=document.body.getElementsByTagName('img');
	for(var i=0; i<e.length; i++) {
	    var elem = e.item(i);
	    if(elem.src.match(/userimages/)) {
		// add in the thingy to switch to dragging mode...
		elem.onmouseover=function(ev) {
		    appendThingy(this);
		};
	    }
	}
}

function normalModeAdditions() {
    
    e=document.body.getElementsByTagName('img');
    for(var i=0; i<e.length; i++) {
	var elem = e.item(i);
	if(elem.src.match(/userimages/)) {
	    // add in the thingy to switch to dragging mode...
	    elem.onmouseover=undefined;
	}
    }
}

var editingScaleOf = undefined;

function disableActiveScaleEditing() {
    if (editingScaleOf != undefined) {
	// stop editing the scale of the previous image and do this one instead...
	try {disableScaleEditing(editingScaleOf);} catch(e) {};
	editingScaleOf = undefined;
    }
}

function toggleImageScaleEditing(img) {
    // alert('ouch');
    return function (ev) { 
	// alert('ouch');
	if(editingScaleOf == img) {
	    try {disableScaleEditing(img);} catch(e) {};
	    editingScaleOf = undefined;
	} else {
	    disableActiveScaleEditing();
	    enableScaleEditing(img);
	    editingScaleOf = img;
	}
    }
}

/*

I've got to figure out what offset to use from the image filename (if it's compound - otherwise use zero)
I've also got to disable scaled editing and switch to the scaled image.
Furthermore, I must clean out the mouse over handler and purge the thingy when we switch back to normal mode.

*/
function enableScaleEditing(img) {

    // alert("enable: " + img.parentNode.innerHTML);
    img.style.position='relative';

    // undef the widths and heights so we can get the images natural dimensions
    img.parentNode.style.width=img.width+'px';
    img.parentNode.style.height=img.height+'px';
    img.parentNode.style.display='block';
    img.parentNode.style.position='relative';
    img.parentNode.style.overflow='hidden';

    img.removeAttribute('width');
    img.removeAttribute('height');

    // *** We should set its offset really

    img.onload = function(ev) {
	// alert('yo!');
	var w = img.offsetWidth;
	var h = img.offsetHeight;
	
	var tw = img.parentNode.offsetWidth;
	var th = img.parentNode.offsetHeight;
	
	var scale;
	if (tw/w > th/h) 
	    scale = tw/w; else scale = th/h;
	
	var constrain;
	if (tw/w > th/h) 
	    constrain='vertical'; else constrain='horizontal';


      // Lines by Stephen
      initialiseMouse();
      // Display width and height
      dw=img.parentNode.style.width;
      dh=img.parentNode.style.height;
      dw=dw.substr(0,dw.length-2);
      dh=dh.substr(0,dh.length-2);
      // Other parameters
      if (imageParams.length == 0 || imageParams[0] != 's'){
        imageParams[1]=Math.max(dw/w,dh/h);
        imageParams[2]=0;
        imageParams[3]=0;
      }
      // Create editing element
      var editingDiv=document.createElement('div');
      editingDiv.setAttribute('id','editingDiv');
      img.parentNode.appendChild(editingDiv);
      currentImage=new EditableImage(
          'editingDiv',
          img.src,
          w,
          h,
          dw,
          dh,
          parseFloat(imageParams[1]),
          parseInt(imageParams[2]),
          parseInt(imageParams[3])
      );
      // Hide image
      img.style.display='none';

	
    }
        // now load the source image (not the scaled version)...
    if (img.src.indexOf('/') == -1){
      imageParams=img.src.split('_');
    }else{
      imageParams=img.src.substr(1+img.src.lastIndexOf('/')).split('_');
    }

    //img.src = img.src.replace(/userimages\/o\d+_\d+_\d+___/,"userimages/").replace(/userimages\/s_(\.|\d)+_\d+_\d+_\d+_\d+___/,"userimages/");
    img.src = img.src.replace(/\/o\d+_\d+_\d+___/,"/").replace(/\/s_(\.|\d)+_\d+_\d+_\d+_\d+___/,"/");

}

function disableScaleEditing(img) {
    // img.style.border='none';

    // alert(img);

    // Many of lines (commented out or marked // ***) changed by Stephen

    // replace the image with the scaled version
    // these are the parameters we need:-
    var src = img.src;
    var left = currentImage.getOffsetX(); // ***
    var top = currentImage.getOffsetY(); // ***
    var scale = currentImage.getScaleFactor(); // ***
    var height = img.parentNode.style.height;
    var width = img.parentNode.style.width;
    
    // turn them into integers...
    //top = parseInt(top.replace(/px/,''));
    //left = parseInt(left.replace(/px/,''));
    width = parseInt(width.replace(/px/,''));
    height = parseInt(height.replace(/px/,''));

    // the offset will be passed to the image scaling script. Which one is the offset?
    // (they might both be zero but that's ok)
    // (the offsets sign is inverted. this is understood by the serverside scaling script. this means it will always be positive)
    //var offset = 0 - ((top==0) ? left : top);

    // now take out any scale parameters from the image src

    // generate the final image src
    src = src.replace(/\/([^\/]+)$/, "/s_" + scale + '_' + left + '_' + top + '_' + width + "_" + height + "___$1"); // ***

    // if the image is referenced locally then changed it to a spotonnet.com reference so the auto scaler will work...
    src = src.replace(/http:\/\/([^\/]+)\/userimages\//, "http://www.spotonnet.com/test/$1/userimages/");

    // *** INCOMPLETE...

    //try {
	//img.parentNode.removeChild(img.previousSibling); 
	//img.parentNode.removeChild(img.previousSibling); 
    //} catch(e) {};

    img.onload = function(ev) {
	editMode2();
	// alert("disable: " + img.parentNode.innerHTML);
    }

    //img.style.top=0;
    //img.style.left=0;
    //img.style.width=undefined;
    //img.style.height=undefined;

    img.width=width;
    img.height=height;

    // Lines by Stephen
    img.style.display='inline';
    img.parentNode.removeChild(document.getElementById('editingDiv'));

    // set the image back to normal mode...
    img.src=src; 
    // img.onmouseover=function(ev) {alert('aaa')};
    // img.onmouseover=function(ev) {appendThingy(this)}; 
    // alert("disable: " + img.parentNode.innerHTML);

}

function appendThingy(img) {
    // remove the thingy first if there is one...
    try {
	removeThingy(img);
    } catch(e) {};

    var newNode = document.createElement('a');
    newNode.href="javascript:void(0)";
    newNode.style.display='block';
    newNode.style.width='20px';
    newNode.style.height='20px';
    // newNode.style.height=0;
    newNode.style.marginBottom='-20px';
    // newNode.style.top=-20;
    newNode.style.top='-2px';
    // newNode.style.color='black';
    // newNode.style.backgroundColor='white';
    newNode.style.position='relative';
    newNode.style.textAlign='right';
    newNode.style.color='white';
    newNode.innerHTML='<div style="" ><span style="background-color:black;color:white;border:1px solid white ">[+]</span></div>';
    newNode.id='imageHandle';
    newNode.style.zIndex=999;
    // img.parentNode.appendChild(newNode);
    newNode.style.left=(img.width-20)+'px';
    img.parentNode.insertBefore(newNode, img);
    // newNode.onmouseover=function(ev) {appendThingy(img)};
    // newNode.onmouseout=function(ev) {removeThingy(img)};
    // newNode.firstChild.onmouseover=function(ev) {appendThingy(img)};
    // newNode.firstChild.onmouseout=function(ev) {removeThingy(img)};
    //img.style.position='relative';
    //img.style.left=0; img.style.top=0; 
    // newNode.firstChild.onmousedown=function(ev) {startDrag(ev, img, function() {}, true)}
    newNode.firstChild.firstChild.onclick=toggleImageScaleEditing(img); // function(ev) {alert('ouch!')};
}

function removeThingy(img) {
    // img.style.border="none";
    //if(thingy(img) != undefined)
    // img.parentNode.removeChild(img.previousSibling);
    var e = document.getElementById('imageHandle');
    e.parentNode.removeChild(e);
}

/* switch to edit mode... */
function editMode() {
    return editMode2();
    var e = document.body.getElementsByTagName('span');
    var s = '';
    // I'm not going to rely on editHandlers to make all text and pictures editable any more.
    for (var i=0; i<e.length; i++)
	if (elementHasClass(e.item(i), "editHandler") ||
	    elementHasClass(e.item(i), "saveEditHandler")) {
	    s = s + e.item(i).firstChild.id + ';';
	}
	    //	if (e.item(i).className == 'editHandler' ||
	    //	    e.item(i).className == 'saveEditHandler')

    rcall('editMode.xml',s);
}

/* switch out of edit mode... */
function normalMode() {
    var e = document.body.getElementsByTagName('span');
    var s = '';
    for (var i=0; i<e.length; i++)
	if (elementHasClass(e.item(i), 'editHandler') ||
	    elementHasClass(e.item(i), 'saveEditHandler'))
	    s = s + e.item(i).firstChild.id + ';';

    rcall('normalMode.xml',s);
    normalModeAdditions();
}

// I have changed this a bit now since I've changed the way things are saved.
function savePage() {

    try {disableScaleEditing(editingScaleOf);}
    catch(e) {}

    var e = document.body.getElementsByTagName('span');
    var s = '';
    var s2 = '';

    for (var i=0; i<e.length; i++) {
	if (elementHasClass(e.item(i), 'saveHandler') ||
	    elementHasClass(e.item(i), 'saveEditHandler')) {
	    // I'm going to clump these all together with nulls. That'll be much gooderer and make it easy for perl to parse. Trivially so.
	    s = s + e.item(i).firstChild.id + String.fromCharCode(1) + e.item(i).innerHTML + String.fromCharCode(1);
	    // rcall('savePage.pl?' + e.item(i).firstChild.id, e.item(i).innerHTML);
	    // We could do with a notification. We'll have to make a
	    // list of elements that need saving and have the save.pl
	    // script tell us when each is done. that wouldn't be too
	    // hard.
	}
	// This is for the new way of saving...
	// basically we send a stream of (id, method, data) to the server. This is how we'll do other changes too.
	if (elementHasClass(e.item(i), 'save')) {
	    var h = e.item(i).innerHTML;

	    // if it's an image then strip out the img style attribute
	    h=h.replace(/<img\s+(.*?)style=[\'\"][^\'\"]*[\'\"]/, "<img $1");

	    // strip out left over guff from the image. This a bit of a kludge - there shouldn't be any
	    h=h.replace(/.*<img/,"<img");

	    // strip out all named anchors
	    h = h.replace(/<a\s+name\=.*?\/a>/g, "");

	    // now generate named anchors for all <h1>...
	    h = h.replace(/<h(\d).*?>(.*?)<\/h\1>/mg, function(a) {
			      return("<a name=\"" + a.replace(/<.*?>/g, "").replace(/ /g,"_").replace(/[^a-zA-Z_]/g,"") +
				     "\"></a>" + a)})

	    // then insert the text into the element again so that they work straight away (well, on saving anyway).
	    e.item(i).innerHTML = h;

	    // strip out any 1s if there are any...
	    s2 += e.item(i).id + String.fromCharCode(1) + e.item(i).className + String.fromCharCode(1) + h + String.fromCharCode(1);
	}
    }

    // display the 'saving' thing
    if (s!='' || s2 != '')
	document.getElementById('appArea').innerHTML+='<div id="saveNotify" style="text-align:center;"><div style="background-color: black; opacity:0.5;position:fixed;top:0;left:0;height:100%;width:100%;text-align:center;">&nbsp;</div><div style="position:fixed; top:50%;width:100%;text-align:center;background-color: white; border: solid black 1px;"><h1>Saving. One moment please.</h1></h1></div>';

    // alert(s.indexOf(String.fromCharCode(0)));
    // now send the whole job lot
    if (s != '') 
	rcall('savePage.xml', s);

    if (s2 != '') 
	rcall('update.xml', s2);
}

