/*
 * Patches for InPlaceEditor 
 * So it doesn;t strip < and >
 */
Object.extend(Ajax.InPlaceEditor.prototype, {
    onLoadedExternalText: function(transport) {
        Element.removeClassName(this.form, this.options.loadingClassName);
        this.editField.disabled = false;
        this.editField.value = transport.responseText;
        Field.scrollFreeActivate(this.editField);
    }
});

Object.extend(Ajax.InPlaceEditor.prototype, {
    getText: function() {
        return this.element.childNodes[0] ? this.element.childNodes[0].nodeValue : '';
    }
});


/* Activate a media player 
 */
function activate_player(name) {
    __e = $('player_' + name);
    __b = $('playbut_' + name);
     
    if (__e.visible()) {
	// it is visible, so the button must say hide
	 // toggle hide to play
	newValue = "PLAY";
	Element.hide(__e);
    } else {
	// it's not visible, so the button must say play
	 // toggle play to hide
	 newValue = "RESET";
	Element.show(__e);
    }

    // patch the button
    __b.innerHTML = newValue;
}

/* Make a tiddler visible as quick as possibile.
 * There are no special effects.
 */
function popout(name) {
    __e = $(name);

    style = Element.getStyle(name, 'display');

    if (style == 'none' || style == null) {    // need to check for null in Safari
	Element.show(name);
	Element.removeClassName(__e, "noshow");
	Element.removeClassName(__e, "hidden");
	__m = $('menu_' + name);
	if (__m) Element.addClassName(__m, "activated");
	// set control to X
	__c = $('control_' + name);
	if (__c) {
	    __c.innerHTML = "<span class='close_x'>X</span>";
	    __c.parentNode.removeClassName('highlight_bullet');
	}
    }
	
}

/* Make a tiddler visible
 */
function show(name) {
    __e = $(name);

    Effect.Appear(__e, {duration: 0.3 });

    Element.removeClassName(__e, "noshow");
    Element.removeClassName(__e, "hidden");

    __m = $('menu_' + name);
    if (__m) Element.addClassName(__m, "activated");

    __c = $('control_' + name);
    if (__c) {
	__c.innerHTML = "<span class='close_x'>X</span>";
	__c.parentNode.removeClassName('highlight_bullet');
    }

    scrollto(name);
}

/* Make a tiddler invisible
 */
function hide(name) {
    __e = $(name);

    Effect.DropOut(__e, { duration: 0.4});
    Element.addClassName(__e, "hidden");

    // if this tiddler is the currently marked tiddler
    // we clear it 
    if (__e == currentMarked) {
	Element.removeClassName(currentMarked, 'marked'); 
	currentMarked = null;
    }

    __m = $('menu_' + name);
    if (__m) Element.removeClassName(__m, "activated");	

    __c = $('control_' + name);
    if (__c) {
	__c.innerHTML = "<span class='bullet'>&bull;</span>";
	Element.addClassName(__c.parentNode, 'highlight_bullet');
	Element.removeClassName(__c.parentNode, 'closemenu_focus');
    }


}    

/* top fn */
function top(name) {
    // construct tiddler name and find tiddler
    tname = "tid_"+name
    tiddler = $(tname);

    // fetch the innerHTML and construct the new content 
    blurring(name);
    theHTML = tiddler.innerHTML;
    content = "<div id=\"tid_" + name  + "\">" + theHTML + "</div>";

    // Find descendants of contentArea.
    // These are the headers and tiddlers
    descendants = Element.descendants("contentArea");

    var first;
    for (var i = 0; i < descendants.length; i++) {
	first = descendants[i];

	if (first.id.match(/^tid_/)) {
	    /* found a tiddler */
	    break;
	}
    }

    // remove the original tiddler
    Element.remove(tiddler);

    // and move it to the top
    new Insertion.Before(first, content);
}
           
/* bottom fn */
function bottom(name) {
    // construct tiddler name and find tiddler
    tname = "tid_"+name
    tiddler = $(tname);

    // fetch the innerHTML and construct the new content 
    blurring(name);
    theHTML = tiddler.innerHTML;
    content = "<div id=\"tid_" + name  + "\">" + theHTML + "</div>";

    // remove the original tiddler
    Element.remove(tiddler);

    // and move it to the bottom
    new Insertion.Bottom("contentArea", content);

}


/* Toggle the visiblity and invisiblity of a tiddler.
 */
function toggle(name) {
    if (Element.hasClassName(name, "hidden")) {
	show(name);
    } else {
	hide(name);
    }
}

/* Jump to a tiddler
 */
function jumpto(name) {
    __e = $(name);

    if (Element.hasClassName(name, "hidden")) {
	show(name);
    } else {
	scrollto(name);

	// add a marker to say it is selected
	// but first we clear a currently marked tiddler
	if (currentMarked != null) {
	    Element.removeClassName(currentMarked, 'marked'); 
	}
	Element.addClassName(__e, 'marked'); 
	currentMarked = __e;
    }
}

function scrollto(name) {
    __e = $(name);

    // determine some positions
    Position.prepare();
    // where the element is
    var offsets = Position.cumulativeOffset(__e);
    var elementY = offsets[1];
    // where the scroll bar is
    var scrollY = Position.deltaY;
    // how big the viewport is
    var viewportY = self.screen.availHeight - document.body.clientHeight

    // determine if the element is more than 3/4
    // of the way down the viewport
    // if it is, we scroll to it
    if (((elementY - scrollY) > (viewportY * 3 / 4)) || elementY < scrollY) {
	// try an line up the element near the middle of the screen
	// the offset is the position of __e relative to the
	// top of the view
	var scrollOffset = viewportY * 1 / 4

	//alert("elementY = " + elementY + " scrollY = " + scrollY + " viewportY = " + viewportY + " elementY - scrollY = " + (elementY - scrollY) + " viewportY * 3 / 4 = " + (viewportY * 3 / 4) + " scrollto = " +  scrollOffset );

	new Effect.ScrollTo(__e, {offset: -scrollOffset} );
    } else {
	//alert("elementY = " + elementY + " scrollY = " + scrollY + " viewportY = " + viewportY);
	
    }
}


/*  Mark a LHS menu item to say it has mouse gained mouse focus.
 */
function focussing(name) {
    __e = $(name); 
    Element.addClassName(__e.parentNode, 'selected'); 
    Element.removeClassName(__e, 'marked'); 

    __c = $('control_' + name);
    if (__c) Element.addClassName(__c.parentNode, 'closemenu_focus');
}

/*  Mark a LHS menu item to say it has mouse lost mouse focus.
 */
function blurring(name) { 
    __e = $(name); 
    Element.removeClassName(__e.parentNode, 'selected'); 

    __c = $('control_' + name);
    if (__c) Element.removeClassName(__c.parentNode, 'closemenu_focus');
}

/* Mark a LHS menu item to allow overflow of text.
 */
function overflow(e) {
    __e = $(e)
    Element.removeClassName(__e, "noverflow");
    Element.addClassName(__e, "overflow");

    Element.addClassName(__e, 'closemenu_hover');
}

/* Mark a LHS menu item so as to not allow the overflow of text,
 * but to truncate it.
 */
function noverflow(e) {
    __e = $(e)
    Element.removeClassName(__e, "overflow");    
    Element.addClassName(__e, "noverflow");

    Element.removeClassName(__e, 'closemenu_hover');
}

/* Display a spinner
 */
function spinner(name) {
    __e = $(name);

    Element.update(name, '<img src="/clipweaver/images/spinner.gif">');
}


/* Display a spinner
 */
function spinner(name, msg) {
    __e = $(name);

    if (msg) {
	message = msg;
    } else {
	message = "";
    }

    Element.update(name, '<img src="/clipweaver/images/spinner.gif">' +
		   '<span class="spinner-message">' + message + '</span>');
}


/* Make a story element full size or a nominated size
 */
function resize_story(name) {
    __e = $('editable_story_' + name);

    if (Element.hasClassName(__e, "squished")) {
	Element.removeClassName(__e, "squished");

	fullsize(name);
    } else {
	squish(name);
    }
}

/* make sure a story is not squished */
function nosquish(name) {
    __e = $('editable_story_' + name);

    if (Element.hasClassName(__e, "squished")) {
	Element.removeClassName(__e, "squished");

	fullsize(name);
    }
}

function collapse_story(name) {
    __e = $('editable_story_' + name);

    if (Element.hasClassName(__e, "collapsed")) {
	Element.removeClassName(__e, "collapsed");

	fullsize(name);
    } else {
	collapse(name);
    }
}

function fullsize(name) {
    __e = $('editable_story_' + name);
    __b = $('viewall_' + name);

    var origHeight = Element.getHeight(__e);

    // mark the element as full height
    Element.addClassName(__e, "full-size");
    var newHeight = Element.getHeight(__e);

    // if it got bigger, there was more text to see
    if (newHeight >= origHeight) {
	// the panel actually got bigger, so we tweak the button
	__b.innerHTML = 'VIEW LESS';
    } else {
	// leave it in a consistent state
	// remove the control
	//Element.hide(__b);
	//Element.removeClassName(__e, "full-size");
	//Element.addClassName(__e, "squished");
    }
}

function squish(name) {
    __e = $('editable_story_' + name);
    __b = $('viewall_' + name);

    var origHeight = Element.getHeight(__e);

    // the panel will be squished
    Element.removeClassName(__e, "full-size");
    Element.addClassName(__e, "squished");
    var newHeight = Element.getHeight(__e);

    // if it got smaller, there was less text to see
    if (newHeight < origHeight) {
	// the panel actually got smaller, so we tweak the button
	__b.innerHTML = 'VIEW MORE';
	scrollto(__e);
    } else {
	// remove the control
	Element.hide(__b);
    }	    


}

function collapse(name) {
    __e = $('editable_story_' + name);
    __b = $('viewall_' + name);

    var origHeight = Element.getHeight(__e);

    // the panel will be squished
    Element.removeClassName(__e, "full-size");
    Element.addClassName(__e, "collapsed");
    var newHeight = Element.getHeight(__e);

    // if it got smaller, there was less text to see
    if (newHeight < origHeight) {
	// the panel actually got smaller, so we tweak the button
	__b.innerHTML = 'VIEW MORE';
    } else {
	// remove the control
	//Element.hide(__b);
    }	    


}

/* add a comment to the comment area
 */
function showComment (req) {
    new Insertion.Top($("comment_area"), req.responseText);
    Element.update($("add_comment_div"), "");
}

function commentError(req) {
    new Insertion.Top($("comment_area"), "<span class='warning'>Failed to add comment.</span>");
    Element.update($("add_comment_div"), "");
}

/* update block */
function clearUpdateBlock() {
    __e = $('update-block');

    __e.innerHTML = "";
}

  /* a timer */
   var timer = { 
      initialize: function(el, fn) { 
          value = 0;
          element = el;
          callback = fn;
          executer = new PeriodicalExecuter(this.cycle, 1); // every second
      }, 
      cycle: function() { 
          value++;
          Element.update(element, callback(value));
          //if (value % 10 == 0) { alert(""+value); }
      } 
  } 

  /* timer usage example */
  //window.onload = timer.initialize("timer", function(v) { return 'T = '+v; });


var currentMarked = null;
