/**
 * FILE					ymip.js
 * AUTHOR				Matt Holford <matt@helen-marie.com>
 * DATE					2007-12-16 17:10:52
 * DESCRIPTION
 * YMiP-related interface scripting
 */


/**
 * Debug mode ?
 */
var YMIP_DEBUG = false;

/**
 * Log error messages?
 */
var YMIP_SHOW_ERROR = false;

/* Data locations */
var YMIP_URL_GLOSSARY = 'data/glossary.xml';
var YMIP_URL_PAGES = 'data/pages.xml';
var YMIP_URL_JSON = 'json.php';

var NAV_YMIP_IDS = ['about', 'glossary', 'poc', 'curricula', 'credits'];

var YMIP_BASE_IMG_DIR = '/ymip/images';


/* Navigation handler */
var ymip = {
	nav: new Array(),
	
	over: false,
	
	selected: false,
	
	init: function() {
		for (var i = 0; i < NAV_YMIP_IDS.length; i++) {
			var idx = NAV_YMIP_IDS[i];
			this.nav[idx] = Ext.get('ymip-nav-' + idx);
			Ext.getDom('ymip-nav-' + idx + '-img').src = YMIP_BASE_IMG_DIR + '/nav/' + idx + '-off.gif';
		}
		
		Ext.addBehaviors({
			'#ymip-nav-about@mouseover': 				this.makeMouseover('about'),
			'#ymip-nav-about@mouseout': 				this.makeMouseout('about'),
			'#ymip-nav-poc@mouseover': 					this.makeMouseover('poc'),
			'#ymip-nav-poc@mouseout': 					this.makeMouseout('poc'),
			'#ymip-nav-glossary@mouseover': 		this.makeMouseover('glossary'),
			'#ymip-nav-glossary@mouseout': 			this.makeMouseout('glossary'),
			'#ymip-nav-curricula@mouseover': 		this.makeMouseover('curricula'),
			'#ymip-nav-curricula@mouseout': 		this.makeMouseout('curricula'),
			'#ymip-nav-credits@mouseover':			this.makeMouseover('credits'),
			'#ymip-nav-credits@mouseout': 			this.makeMouseout('credits')
		});
		
		if (typeof(YMIP_PAGE_SELECT) != 'undefined') {
			this.selectPage(YMIP_PAGE_SELECT);
		}
	},
	
	makeMouseover: function(idx) {
		return function(e, t) { 
			if (ymip.selected == idx) {
				return;
			}
			log.write("Turning on " + idx);
			Ext.getDom('ymip-nav-' + idx + '-img').src = YMIP_BASE_IMG_DIR + '/nav/' + idx + '-on.gif';
		};
	},
	
	makeMouseout: function(idx) {
		return function(e, t) { 
			if (ymip.selected == idx) {
				return;
			}
			log.write("Turning off " + idx);
			Ext.getDom('ymip-nav-' + idx + '-img').src = YMIP_BASE_IMG_DIR + '/nav/' + idx + '-off.gif';
		};
	},
	
	selectPage: function(idx) {
		if (typeof(this.nav[idx]) != 'undefined') {
			Ext.getDom(this.nav[idx]).className = ('about' == idx) ? 'ymip-nav-item ymip-nav-selected ymip-nav-selected-first' : 'ymip-nav-item ymip-nav-selected';
			Ext.getDom('ymip-nav-' + idx + '-img').src = YMIP_BASE_IMG_DIR + '/nav/' + idx + '-on.gif';
			this.selected = idx;
		}
	}
};

Ext.onReady(function() {
	ymip.init();
});


/* Logger */
var log = {
	write: function(/* string */msg) {
		if (YMIP_DEBUG == true && typeof(console) != 'undefined') {
			console.log(msg);
		}
	},
	
	error: function(/* string */msg) {
		if (YMIP_SHOW_ERROR == true && typeof(console) != 'undefined') {
			console.log('Error: ' + msg);
		}
	}
}


/* Page content handler */
var page = {
	render: function(/* string */idx, /* string */divName) {
		var dh = Ext.DomHelper;
		
		Ext.onReady(function() {
			// create the Data Store
			var store = new Ext.data.Store({
				// load using HTTP
				url: YMIP_URL_PAGES,

				reader: new Ext.data.XmlReader({
						record: 'page',
						id: 'id'
					}, [
						// set up the fields mapping into the xml doc
						'title',
						'body',
						'area'
				 ])
			});
			
			store.on("load", function() {
				log.write("Loaded " + store.getTotalCount() + " pages");
				var record = store.getById(idx);
				log.write("Reading pages data store: ID=" + idx + "; record=" + typeof(record));
				
				var title = dh.append(divName, {
					tag: 'h1', html: record.data['title']
				});
				var body = dh.append(divName, {
					tag: 'p', html: '<p>' + record.data['body'] + '<\/p>'
				});
			});
			
			store.load();
		});
	}
}


/* Glossary content handler */
var glossary = {
	
	defdivs: [],				// Store def layers here as we create them
	definition: false,	// Currently-exposed definition
	dh: false,					// Ext.DomHelper; assigned in init()
	groups: [],					// Alphabetical groups of terms
	poc: [],						// Projects of Change: IDs and titles
	terms: [],					// Terms indexed by ID
	
	init: function() {
		
		this.dh = Ext.DomHelper;
		
		Ext.onReady(function() {
		
			// create the Data Store
			var store = new Ext.data.Store({
				// load using HTTP
				url: YMIP_URL_GLOSSARY,

				// the return will be XML, so lets set up a reader
				reader: new Ext.data.XmlReader({
						// records will have a "ROW" tag
						record: 'ROW',
						id: 'id2'
					}, [
						// set up the fields mapping into the xml doc
						'id2',
						'Glossary_Term',
						'See_Also',
						'Definition',
						'Links_to_Projects_of_Change',
						'In_Practice',
						'External_Links',
						'References'
					]
				)
			});
			
			var pocRecord = Ext.data.Record.create([
				{ name: 'id' },
				{ name: 'title' }
			]);
			
			var pocStore = new Ext.data.Store({
				url: YMIP_URL_JSON,
				
				reader: new Ext.data.JsonReader({
					totalProperty: 'results',
					root: 'rows',
					id: 'id'
				}, pocRecord)
			});
			
			pocStore.on("load", function() {
				log.write("Loaded " + pocStore.getTotalCount() + " POC records");
				
				pocStore.each( 
					function() {
						glossary.poc[glossary.poc.length] = { id: this.get('id'), title: this.get('title') };
					}
				);
			});
			
			pocStore.load();
	
			store.on("load", function() {
				log.write("Loaded " + store.getTotalCount() + " records");
				
				/* Sort defs into letter groups */
				store.each(
					function() {
						var first = this.get('Glossary_Term').match(/^[A-Za-z]/);
						if (typeof(glossary.groups[first]) == 'undefined') {
							glossary.groups[first] = [];
						}
						
						glossary.groups[first][this.get('id2')] = this;
						glossary.terms[this.get('id2')] = this;
					}
				);
				
				glossary.dh.append(Ext.get('glossary-nav'), {
					tag: 'span', id: 'glossary-nav-intro', html: 'Jump to a letter: '
				});
				
				for (var i in glossary.groups) {
					if ('remove' == i || 'indexOf' == i) {
						log.write("Skipping non-group " + i);
						continue;
					}
					
					var group = glossary.groups[i];
					
					var toplink = glossary.dh.append(Ext.get('glossary-nav'), {
						tag: 'a', cls: 'glossary-nav-item', href: '#section-' + i, html: i
					});
					
					var anchor = glossary.dh.append('glossary-render', {
						tag: 'a', id: 'link-defgroup-' + i, name: 'section-' + i
					});
					
					var section = glossary.dh.append('glossary-render', {
						tag: 'div', id: 'defgroup-' + i, children: {
							tag: 'h2', html: i
						}
					});
					
					for (var j in group) {
						var term = group[j];
						
						try {
							var parts = term.get('Definition').split(/\./);
						} catch (e) {
							log.error('Skipping bad term: ' + typeof(term));
							continue;
						}
						var txt = parts[0]; // + '. <a href="#" id="link-expand-' + term.get('id2') + '">more<\/a>';
						
						try {
							var tid = term.get('id2');
						} catch (e) {
							log.error('Skipping term with no "get" method: ' + typeof(term));
							continue;
						}
						
						var def1 = glossary.dh.append('defgroup-' + i, { tag: 'a', name: 'def-list-item-' + tid, html: '' });
						var def2 = glossary.dh.append('defgroup-' + i, { tag: 'div', id: 'def-list-item-full-' + tid, html: '' });
						var def3 = glossary.dh.append('defgroup-' + i, {
							tag: 'p', cls: 'def-list-item', id: 'def-list-item-title-' + tid, children: [{
									tag: 'a', id: 'definition-' + tid, title: txt, 
									href: 'javascript:void(0)', // '#def-list-item-' + tid,
									html: term.get('Glossary_Term')
							}]
						});
						
						eval("var behavior = { '#definition-" + tid + "@click' : glossary.makeDefExpandFunction('" + tid + "') }");
						Ext.addBehaviors(behavior);
					}
					
					var back = glossary.dh.append('defgroup-' + i, { tag: 'p', cls: 'def-list-item', children: [{ 
							tag: 'a', href: '#top', html: 'Back to top &rarr;'
						}]
					});
				}
			});
			
			store.load();
		});
	},
	
	makeDefExpandFunction: function(/* int */tid) {
		return function(e, t) {
			var term = glossary.terms[tid];
			glossary.clearDefinition();
			if (typeof(glossary.defdivs[tid]) != 'undefined') {
				glossary.defdivs[tid].style.display = 'block';
			} else {
				var def = glossary.dh.append('def-list-item-full-' + tid, {
					tag: 'div', cls: 'def-item-full', children: [
						{ tag: 'div', cls: 'wrapper-def-item-close', children: [
							{ tag: 'a', cls: 'def-item-close', href: 'javascript:glossary.clearDefinition()', title: 'Hide this definition' }
						]},
						{ tag: 'div', cls: 'wrapper-def-item-text', id: 'wrapper-def-item-text-' + tid, children: [
							{ tag: 'h3', cls: 'def-item-title', html: term.get('Glossary_Term') },
							{ tag: 'p', html: term.get('Definition') }
						]}
					]
				});
				
				if (term.get('See_Also') != '') {
					var def3 = glossary.dh.append('wrapper-def-item-text-' + tid, {
						tag: 'p', html: 'See also: ' + term.get('See_Also')
					});
				}
				
				if (term.get('Links_to_Projects_of_Change') != '') {
					var links = term.get('Links_to_Projects_of_Change').split(/,/);
					var linkHtml = '';
					
					for (var i = 0; i < links.length; i++) {
						var name = Ext.util.Format.trim(links[i]);
						var id = glossary.getPOCKey(name);
						if (false === id) {
							log.error("No match for '" + name + "'");
							linkHtml += name;
						} else {
							linkHtml += '<a href="?p=poc&amp;pid=' + id + '">' + name + '<\/a>';
						}
						if (i < (links.length - 1)) {
							linkHtml += ', ';
						}
					}
					
					var def4 = glossary.dh.append('wrapper-def-item-text-' + tid, {
						tag: 'p', html: 'Related Projects of Change: ' + linkHtml
					});
				}
				
				if (term.get('In_Practice') != '') {
					var links = term.get('In_Practice').split(/\s/);
					var linkHtml = '';
					for (var i = 0; i < links.length; i++) {
						if (links[i].match(/^http:\/\//)) {
							linkHtml += '<a href="' + links[i] + '">' + links[i] + '<\/a>';
							if (i < links.length - 1) {
								linkHtml += ',';
							}
							linkHtml += ' ';
						} else {
							linkHtml += ' ' + links[i] + ' ';
						}
					}
					var def2 = glossary.dh.append('wrapper-def-item-text-' + tid, {
						tag: 'p', html: 'In practice: ' + linkHtml
					});
				}
				
				if (term.get('External_Links') != '') {
					var links = term.get('External_Links').split(/\s/);
					var linkHtml = '';
					for (var i = 0; i < links.length; i++) {
						if (links[i].match(/^http:\/\//)) {
							linkHtml += '<a href="' + links[i] + '">' + links[i] + '<\/a>';
							if (i < links.length - 1) {
								linkHtml += ',';
							}
							linkHtml += ' ';
						} else {
							linkHtml += ' ' + links[i] + ' ';
						}
					}
					var def5 = glossary.dh.append('wrapper-def-item-text-' + tid, {
						tag: 'p', html: 'Learn more: ' + linkHtml
					});
				}
				
				if (term.get('References') != '') {
					var links = term.get('References').split(/\s/);
					var linkHtml = '';
					for (var i = 0; i < links.length; i++) {
						if (links[i].match(/^http:\/\//)) {
							linkHtml += '<a href="' + links[i] + '">' + links[i] + '<\/a>';
							if (i < links.length - 1) {
								linkHtml += ',';
							}
							linkHtml += ' ';
						} else {
							linkHtml += ' ' + links[i] + ' ';
						}
					}
					var def6 = glossary.dh.append('wrapper-def-item-text-' + tid, {
						tag: 'p', html: 'References: ' + linkHtml
					});
				}
				
			}
			glossary.setDefinition(tid);
		}
	},
	
	clearDefinition: function() {
		if (this.definition != false) {
			log.write("Clearing definition " + this.definition);
			this.hideDefinition(this.definition);
			this.definition = false;
		}
	},
	
	getPOCKey: function(/* string */title) {
		for (var i = 0; i < this.poc.length; i++) {
			if (this.poc[i].title.toLowerCase() == title.toLowerCase()) {
				return this.poc[i].id;
			}
		}
		return false;
	},
	
	hideDefinition: function(/* int */tid) {
		this.defdivs[tid].style.display = 'none';
		Ext.getDom('def-list-item-title-' + tid).style.display = '';
	},
	
	setDefinition: function(/* int */tid) {
		log.write("Setting current definition to " + tid);
		this.definition = tid;
		this.defdivs[tid] = Ext.getDom('def-list-item-full-' + tid);
		Ext.getDom('def-list-item-title-' + tid).style.display = 'none';
	}
}

