// (script.js) //


// FUNCTIONS //

// HTTP
function QueryString () {
	// gather data
	var qs = location.search; // use the built-in "location.search" object.property to discover the current URL's query string.
	var ps = (qs.replace("?","")).split("&"); // remove the beginning ? question mark, and split the query-string into name/value pairs.
	// parse data
	for (var i=0; i < ps.length; i++) {
		var p = ps[i]; p = p.split('=');
		var n = p[0]; // pair name
		var v = p[1]; // pair value
		this[n] = v; // pair name/value, and add element to the associative array.
	};
	// return data
	return this; // return the associative array of the QueryString.
} // parses the the current HTTP QueryString and returns an object equivalent of a name/value associative array.
QueryString = new QueryString(); // global object


function most(y,p) { // object-type-tag-name, property
	m = 0; // "most" value
	var os = document.getElementsByTagName(y); // get all object names of object-type-tag-name
	for (var o in os) { // loops per object name
		o = get(o);
		v = get(o,p);
//		alert(v);
		if (o) {
			if (o.style) { alert(o.style[p]) }; 
		};
	}; // booya!
}; // returns the most value of a given "named" object-type's known property. * object must be named in order to work

function site() {
//	fit('midder');
};

function swap(n,p) { // image-tag-name/id, image-src-path
	var o = get(n);
	if ((o) && (p)) { o.src = p; }; //
} // swaps a given image

function index (a,v) { // array, value
	// 2D arrays //
	if ((is(a,'array')) && (is(v,'string'))) {
//		alert('indexing 2D array');
		r = new Array();
		return r;
	};
	// 1D arrays //
	if (is(a,'array')) {
//		alert('indexing 1D array');
		r = new Array();
			for (e in a) {
//				alert(a[e]);
				r[a[e]] = a[e]; // copies the current value into the current name/key, leaving both name/key and value equal.
//				alert(r[a[e]]);
			};
		
//			for (e in r) {
//				alert(e); // name
//				alert(r[e]); // value
//			};
		return r;
	};
} // "index" adds an index to the given array, based on the current 1st dimension value of a 1D array, or a given value within the 2nd dimension of a multi-dimensional array.

function fix(p,a,d) { // <#string:prefix>,<#string|#array-of-#strings:data>,<#string:postfix>
	if (is(a,'string')) { // takes old string
		if (is(p,'string')) { a = p + a; }; // prefixes
		if (is(d,'string')) { a = a + d; }; // postfixes
	};
	if (is(a,'array')) {
		for (e in a) { // &referncing the element is essential // "e" acts like an index number for the given array being parsed.
			a[e] = fix(p,a[e],d); // recurse to "fix" each string
//			alert(a);
		};
	};
//	alert(a);
	return a; // returns new (or same) string
} // attempts to "fix" a string or array-of-strings with a prefix, postfix, or both.
function prefix(p,a) { return fix(p,a); }
function postfix(a,d) { return fix('',a,d); }

//function swap(n,p) { // image-name, image-path
//	alert(n + " : " + p);
//	get(n).src = p;
//}

function style (o,p,v) { // element-object, style-property, value
//	alert(o);
	if (is(o,'string')) { o = get(o); }; // get the "style" object found in the "style" property of the DOM element.
//	if (is(o,'object')) {
//		if (has(o,p)) { o[p] = v; }; // * ideal code, if it works.
//		s = '';
//		for (r in o) {
//			s = s + o + ' : ' + r + '\n';
//			if (p == r) { return o[p]; };
//		};
//	alert(o.style[p]);
	switch (p) {
		case 'background-color' : case 'backgroundColor' : o.style.backgroundColor = v; break; 
		default: // try the others, but it might not work ...
			o.style[p] = v; // document.getElementById(objId).style[style]= 
		break;
	};
	return (o.style[p]); // return new value
//		alert(s);
//	};
};


function act(o,e) {
//	alert(o.name + " " + e.type);
//	alert(o.name + " " + o.href);
//	alert(o.path + o.image);

};


// SETUP EVENTS //
function events () {
	var o = this; // object
	var e = window.event; // event
	var u; // cue
//	alert(o.id + " : " + e.type); // calling object
	
	// begin "navigate" rollovers //
	var p = '/`media/images/graphics/navigate/';
	var a = ['news','features','services','history','locate','contact','links','auctions','realestate','contents','antiques','specialty','appraisals'];
	for (var n in a) {
		n = a[n]; // number-to-name
		if (o.id == ('navigate_' + n)) { 
			switch (e.type) {
				case 'mouseover' : u = 'hover'; break;
				case 'mouseout' : u = 'rest'; break;
			};
			switch (u) {
				case 'hover' : swap('navigate_'+n,(p+n+'_hover.png')); break;
				case 'rest' : swap('navigate_'+n,(p+n+'.png')); break;
			};
		};	
	};
	// end "navigate" rollovers //
};

function setup(m) {
// Interactivity / Custom Event Handlers //

	// mouse / interactivate mouse events on all images //
	var a = document.getElementsByTagName('img');
	for (var o in a) {
		o = get(o);
		if (o) {
			o.onmouseover = events;
			o.onmouseout = events;
		};
	};

	// navigate side //
//	o = get('navigate_side');
//	if (o) {
//		alert('hey navigate');
//	};
};

// * essential * event handlers //
window.onload = setup;

// SUB-ROUTINES //

/*
function preload() {
	// preload images (shell) //
	if (document.images) {
		// set image url
		image_url = new Array('news', 'features', 'services', 'history', 'locate', 'contact', 'links', 'realestate', 'antiques', 'specialty', 'appraisals');  // 
		image_root = "/`media/images/graphics/navigate/";

		// preload basic images
		image_leaf = ".png";
		var i = 0;
		for(i=0; i<=image_url.length; i++) {
			image_object = new Image();
			image_object.src = image_root + image_url[i] + image_leaf;
		};

		// preload hover images
		image_leaf  = "_hover.png";
		var i = 0;
		for(i=0; i<=image_url.length; i++) {
			image_object = new Image();
			image_object.src = image_root + image_url[i] + image_leaf;
		};
	};
}
document.onload = preload; // link subroutine to the document object's onload event.
*/

// CLASSES / OBJECTS //

// CjM_Slideshow

function CjM_Slideshow(a,n) { // #array-of-strings-of-complete-path-data, #string-callback-object's-variable-name
//alert(is(a,'array'));
//alert(n);
	// notes //
	// * CRITICAL * #timeouts make callbacks to elements defined off the root of the DOM Document object ([scope-page] myVariable.myMethod) and not within custom objects themselves ([scope-object] this.myMethod), so it's necessary to synchronize the (3) names of the variable's-name, this-object's-name, and the image-tag's-name-attribute.
	// arguments (defaults)
	if (!a) { }; // #string of file-system-path-of-images |OR| #array of DOM-image-objects.
	if (!n) { var n = 'slideshow'; }; // default

	// properties
	this.name = n; // #string, unique name of this slideshow and projector image required to make #timeout features work. 
		// *** synchronize the varible's name, the image-tag's name, and this-object's name to work ***
		// ex.) CjM_Slideshow = new CjM_Slideshow(); this.name = "CjM_Slideshow"; && <img name="CjM_Slideshow" ...
	this.type = 'CjM_Slideshow'; this.version = '20090310'; this.author = 'CjM'; // signature.
	this.autostart = 1; // #boolean, whether or not to automatically start the slideshow on load.
	this.automatic = 1; // #boolean, whether or not the slides show automatically.
	this.interval = 4000; // #integer, slide-display interval, in millisecconds.
	this.timer; // #object, variable for the required #timeout object with callback generated to make it run.
	this.callback; // #string, the callback-string generated for the #timeout object.
	this.directive = 'random'; // #string, the directive for how the slideshow plays in each timer's callback interval.
	this.point = 0; // #integer, number that points to the current slide of this slideshow (default zero).
	if (is(a,'string')) { this.directory = a; }; // #string, path to the source-directory on the file-system holding the images.
	this.image = n; // #string, references the "name" attribute of the image object to play the slides.
	this.projector = document[this.image]; // #string-to-#image-object, reference to the existing DOM image object of the given image "name" attribute of the markup (<img name="slideshow" src="...).
	this.paths; 
	// #array, slideshow-array of 1st) image-paths on the file-system, and then image-objects created from these paths.
	if (is(a,'array')) { this.slides = a; } else { this.slides = new Array(); };
	this.total; // #integer, representing the total count of images in the slideshow array.
//	this.random = 0; // #boolean, whether or not the slides display randomly.
	this.range = 0; // #integer, the range of numbers from which to display randomly.
	// methods
	this.setup = function () { //a) { // array-of-path-strings
//	alert('trying to setup');
	// make slides (the advantages of creating image objects is to load them into memory).
//		if ((is(a,'string')) || (is(a,'array'))) { this.slides = a; };
		this.total = this.slides.length; // counts the total image-objects in the array.
//		alert(this.slides);
		for (var j = 0; j < this.total; j++) {
			if (is(this.slides[j],'string')) {
				var i = new Image(); // make an new DOM image object.
				i.src = this.slides[j]; // set source-path attribute to preload image data into memory.
				this.slides[j] = i; // replace the image-path with the image-object into the slideshow's slides array.
			};
		};
	}; // generates slides by given path
	this.slide = function (d,a,b) { // directive, argument-a, argument-b
		switch (d) {
			case 'next' : case 'forward' : case 'forwards' : // next slide
				this.point = (this.point + 1) % this.total;
				this.slide(this.point);
			break;
			case 'prev' : case 'previous' : case 'backward' : case 'backwards' : // previous slide
				this.point = (this.point - 1) % this.total;
				this.slide(this.point);
			break;
			case 'random' : // random slide
				if (!a) { a = 0; }; // first element, represented by zero.
				if (!b) { b = (this.images.length - 1); }; // total count of the array, minus 1.
				this.range = a - b + 1;
				this.point = Math.floor(Math.random() * this.range) + a;
				this.slide(this.point);
			break;
			//
			default : // * given integer .. switch the image.
				if (this.automatic) { // then, set the timer to automatically run this slideshow.
////					this.callback = "get('" + this.name + "').slide('" + this.directive + "')"; // * SOMEDAY *
					if (!this.directive) { this.directive = 'next'; };
					this.callback = this.name + ".slide('" + this.directive + "')"; // * (3x) synch'd name
//					alert(this.slides);
//					alert(this.callback);
					this.timer = setTimeout(this.callback,this.interval); // 
				};
				if (this.projector) {
					this.projector = document[this.image]; // * update the projector reference * //
//					this.projector.name = this.slides[this.point].src; // *** make this the name of the image ***
					this.projector.src = this.slides[this.point].src;  // switches the projector-image's source attribute to the current slide-image's source attribute, effectively showing the current slide.
				};
			break;
		};
	};
	this.start = function (d) { this.automatic = 1; this.directive = d; this.slide(); };
		this.play = this.start; // alias
	this.stop = function () { this.automatic = 0; };
	// events
	// links
	// actions
	this.setup(); // * essential * must call "slides" to setup the slideshow.
	if (this.autostart) { this.play(); };
}
//var slideshow = new CjM_Slideshow(); // * synch slideshow's variable name, object's name and img-tag's name.



function CjM_Gallery(c,f) { // display-calls-to-div-names, target-image-id
	// properties (CjM_Gallery) & default values
	if (!c) { c = 'gallery_'; }; // associative-array of "calls"-to-"div-names" ex. ['item' : 'auction_gallery_item']
		this.displays = prefix(c,index(['table','list','item','slideshow'])); // these are the names of the <div> elements that will be displayed (aka. show/hide)
		// "item" properties
	if (f) { this.frame = f; } else { this.frame = 'gallery_item_frame_image'; }; // string, id of the image object being used as the frame receiving the new image
	this.stub = get(this.frame).src; // the first image assigned to the frame is considered the "stub"
	this.loading = '/`media/images/graphics/logos/logo_roan.gif'; // * change this default value * // loading graphic
	this.caption = 'gallery_item_caption_text'; // default, caption <p id="">, necessary for changing the caption text *** <#>.innerHTML DOES NOT WORK for the <div> element !!! ***
	this.details = 'gallery_item_details'; // default, details <div id="">, necessary for changing the details text.
	this.extras = 'gallery_item_extras_table'; // default, extras ...

	// methods (CjM_Gallery)
	this.display = function (c,o,e) { // display-call-string, object, event-object
		// display <div>'s //
		n = this.displays[c];
		for (d in this.displays) {
			get(this.displays[d]).style.display = 'none'; // turn off all displays
		};
		get(n).style.display = 'block'; // this must be setup in "markup" and "style" code correctly to work with this "interactive" code.
		
		// display <img> //
//		alert(o);
//		alert(o.src.replace('thumbs/thumb_','photos/photo_'));
//		s = s.replace(/\/thumbs\/thumb_/gi,'/photos/photo_');

		// load image into frame //
//			get(this.frame).src = this.stub; // stub, if necessary.
			get('gallery_item_loading').style.display = 'block'; // turn on loading graphic.
			get('gallery_item_frame').style.display = 'none'; // turn off frame when image inside is still loading.
			get(this.frame).src = o.src.replace('thumbs/thumb_','photos/photo_'); // .. then, change directories and place parallel thumnail image into item frame image.
			
			// setup callback for loading graphic
			get(this.frame).onload = function () { // begin callback
				// display
				get('gallery_item_loading').style.display = 'none'; // turn off loading graphic.
				get('gallery_item_frame').style.display = 'block';
			}; // end call back

			// synchronize "previous & next" property values from indicating markup custom attributes <img previous="" next=""> //
			get(this.frame).setAttribute("previous",o.getAttribute("previous")); // synch
			get(this.frame).setAttribute("next",o.getAttribute("next")); // synch
			
			// synchronize the "caption & details" property values //
			get(this.frame).setAttribute("caption",o.getAttribute("caption")); // synch
			var e = get(this.caption); if (e) { e.innerHTML = o.getAttribute("caption"); }; // update caption text // * NOTE * <>.innerHTML DOES NOT EXIST IN <DIV> elements! use <SPAN>.
			
			// generate an "extras" table, if extra photographs exist //
			var e = get(this.extras); if (e) { e.innerHTML = o.getAttribute("extras"); };

//			get('gallery_item_frame_link').href = get(this.frame).src.replace('photos/photo_','hires/hires_'); // 
//			get('gallery_item_frame').style.display = 'block';
//			get('gallery_item_loading').style.display = 'none'; // turn off loading graphic.
	};
	this.next = function() { 
		o = get(get(this.frame).getAttribute("next")); // tag is id, get bt id
		this.display('item',o); 
	};
	this.previous = function() { 
		o = get(get(this.frame).getAttribute("previous")); // tag
		this.display('item',o);
	};
//		this.test = function () { alert('CjM_Gallery Object works'); };
};
//	a = index(['table','list','item','slideshow']); // when you "index" a 1D array, the name/values are there, but they're invisible to "alert()" calls.
//	alert(a); // * you can't see it, but it's there.
//	gGallery = new CjM_Gallery('auction_gallery_');
//	gGallery.test();


function CjM_Tabs(a) { // tab-names-as-array-of-strings
	// properties & arguments
	this.tabs = 0; if (is(a,'array')) { this.tabs = a; };
	// methods
	this.tab = function (n) {
		if ((is(n,'string')) && (is(a,'array'))) { // begin "if string"
	//		if has(this.tabs,n) { // begin process
				var t = this.tabs;
				for (var i=0; i < t.length; i++) { hide(t[i]); }; // hide all tabs
				show(n); // show the given one
//			}; // end process
		}; // end "if string"
	};
} // CjM_Tabs collects DIV markups ids, and on the <#CjM_Tabs>.tab(<id>) method, hides all of them, and shows the one that is passed.

// TEST //

function test_this_height() { 
	var vDivs = document.getElementsByTagName('div');
//	alert(vDivs.length);
	var s = "\n";
	for(var vDiv in vDivs) {
		vDiv = document.getElementById(vDiv); 
		if (vDiv != null) { s = s + vDiv.id + " : " + vDiv.offsetHeight + " : " + vDiv.style.display + '\n'; };
	};
	alert(s);
//	get('gallery_table').style.display = '';
//	alert(get('gallery_table').style.display);
	document.getElementById('gallery_table').style.display = 'block';
	alert(document.getElementById('gallery_table').style.display);
}

function test() {
	var v = 'left';
	alert(v + " : " + get(v).offsetLeft);
}

