// fancyborder.js (version 0.1p alpha)
//
// Add border images to a div. Requires prototype.js.
//
// Copyright (c) 2007 Modern Webspace, Inc. (http://modernwebspace.com, http://bgok.net)
// 
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice, associated urls and this permission notice
// shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// History:
// 0.1a alpha - Orginal version (little testing, but it seems to work in IE7, FF2, Opera 9.21 & Safari for Windows 3.0.2)

// fancyBorder()
// Builds 3 3x1 tables within the specified div and moves all of the orginal content of the
// div to the center element of the table. Each table element has the designated theme
// attached to it as a class so that the 8 border elements can be styled with CSS. This allows
// you to add irregular borders, rounded corners and shadows to the div.
//
// This function works best when the div is given padding that is wide enough to contain the
// border. The padding will automatically be reduced by the width of the border. This is done
// so that you can get a better idea of what the page will look like as you design it and
// so that the content doesn't jump around on the screen as the borders are added.
//
// The minimum width of all borders is 1 pixel. If you don't want the border to show up, just make
// it the same color as the inner background.
//
// After a border is added using this function, the size of the div will be fixed and will
// no longer flow to fit the content if it is changed.
function fancyBorder(id, theme) {
	var outer = $(id);
	if (!outer)
		return null;
		
	// Fix the outer div to the current	size
	outer.style.height = outer.clientHeight + 'px';
	outer.style.width = outer.clientWidth + 'px';

	// Create a new div
	var inner = document.createElement("div");
    inner.setAttribute('id', id+'_content');
    inner.className = theme;

	// move contents of original div to the new div
	while(outer.childNodes.length) {
		inner.appendChild(outer.firstChild);
	}
	
	// add the theme class name to the outer div
	outer.addClassName(theme);

	// Build the HTML to be inserted into the outer div
    outer.innerHTML = "\
      <table id='"+ id +"_row1' class=\"top table_window\">\
        <tr>\
          <td id ='" + id + "_nw' class='"+ theme +"_nw'><span style='float:left; width:1px; height:1px;'></span></td>\
          <td id ='" + id + "_n' class='"+ theme +"_n'><span style='float:left; width:1px; height:1px;'></span></td>\
          <td id ='" + id + "_ne' class='"+ theme +"_ne'><span style='float:left; width:1px; height:1px;'></span></td>\
        </tr>\
      </table>\
      <table id='"+ id +"_row2' class=\"mid table_window\">\
        <tr>\
          <td id ='" + id + "_w' class='"+ theme +"_w'><span style='float:left; width:1px; height:1px;'></td>\
            <td id='"+ id +"_table_content' class='"+ theme +"_table_content' valign='top'></td>\
          <td id ='" + id + "_e' class='"+ theme +"_e'><span style='float:left; width:1px; height:1px;'></td>\
        </tr>\
      </table>\
        <table id='"+ id +"_row3' class=\"bot table_window\">\
        <tr>\
          <td id ='" + id + "_sw' class='"+ theme +"_sw'><span style='float:left; width:1px; height:1px;'></span></td>\
            <td id ='" + id + "_s' class='"+ theme +"_s'><span style='float:left; width:1px; height:1px;'></span></td>\
            <td id ='" + id + "_se' class='" + theme +"_se'><span style='float:left; width:1px; height:1px;'></span></td>\
        </tr>\
      </table>\
    ";
	
	// Make the content div a child of the center element of the table
	$(id+"_table_content").appendChild(inner);

	// Move inner styles from the outer div to the innner div
	adjustPadding(outer, inner, 'Left', parseInt($(id + '_w').getStyle('width')));
	adjustPadding(outer, inner, 'Right', parseInt($(id + '_e').getStyle('width')));
	adjustPadding(outer, inner, 'Top', parseInt($(id + '_n').getStyle('height')));
	adjustPadding(outer, inner, 'Bottom', parseInt($(id + '_s').getStyle('height')));
	styleMoveClear(outer, inner, 'backgroundColor', 'transparent');

	// Fix the content width
	$(id+"_table_content").style.width = (parseInt($(outer).getStyle('width')) - parseInt($(id + '_w').getStyle('width')) - parseInt($(id + '_e').getStyle('width'))) + "px";
	$(inner).style.width = (parseInt($(id+"_table_content").style.width) - parseInt($(inner).getStyle('paddingLeft')) -  parseInt($(inner).getStyle('paddingRight'))) + 'px';

	// Fix the content height
	$(id+"_table_content").style.height = (parseInt($(outer).getStyle('height')) - parseInt($(id + '_n').getStyle('height')) - parseInt($(id + '_s').getStyle('height'))) + "px";
	$(inner).style.height = (parseInt($(id+"_table_content").style.height) - parseInt($(inner).getStyle('paddingTop')) -  parseInt($(inner).getStyle('paddingBottom'))) + 'px';

	return outer;
}

// adjustPadding()
// Moves the padding from the outer element to the inner element, set the padding of
// the outer element to zero and reduce the padding by the width of the border (or to
// zero if the border is wider than the padding).
function adjustPadding(srcDiv, dstDiv, side, borderWidth) {	
	var padWidth = parseInt(srcDiv.getStyle('padding'+side));
	// Negative padding is invalid and makes IE gag
	dstDiv.style['padding' + side] = ((borderWidth < padWidth)? padWidth - borderWidth : 0) + 'px';
	srcDiv.style['padding' + side] = '0px';
}

// styleMoveClear()
// Move a style from the outer div to the inner div and clears the outer div style
function styleMoveClear(srcDiv, dstDiv, styleName, clearValue) {
	dstDiv.style[styleName] = srcDiv.getStyle(styleName);
	srcDiv.style[styleName] = clearValue;
}

// === Sample CSS ===
// In this example, the images are contained in a directory called 'images/rounded' which a subdirectory of the
// directory that contains the file that contains this css
/*
.rounded table {
	border-collapse:collapse;
	border-spacing:0px;
	width:100%;
}
.rounded_table_content, .rounded_nw, .rounded_ne, .rounded_sw, .rounded_se, .rounded_n, .rounded_s, .rounded_w, .rounded_e {
	margin: 0px;
	border: none;
	padding: 0px;
}
td.rounded_nw {
	height: 10px;
	width: 10px;
	background-repeat: no-repeat;
	background-image: url(images/rounded/nw.png);
}
td.rounded_ne {
	height: 10px;
	width: 10px;
	background-repeat: no-repeat;
	background-image: url(images/rounded/ne.png);
}
td.rounded_sw {
	height: 10px;
	width: 10px;
	background-repeat: no-repeat;
	background-image: url(images/rounded/sw.png);
}
td.rounded_se {
	height: 10px;
	width: 10px;
	background-repeat: no-repeat;
	background-image: url(images/rounded/se.png);
}
td.rounded_n {
	height: 10px;
	background-repeat: repeat-x;
	background-image: url(images/rounded/n.png);
}
td.rounded_s {
	height: 10px;
	background-repeat: repeat-x;
	background-image: url(images/rounded/s.png);
}
td.rounded_e {
	width: 2px;
	background-repeat: repeat-y;
	background-image: url(images/rounded/e.png);
}
td.rounded_w {
	width: 2px;
	background-repeat: repeat-y;
	background-image: url(images/rounded/w.png);
}
*/

// === Invoking this function ===
// Add script tags to the header to include this file and prototype.js to the head of your HTML.
//
// To apply the rounded style to a div called 'main', change the <body> tag to:
//   <body onload="fancyBorder("contentMainWrapper", "lewoofMain");">