/*
	File:		SMG Base Classes
	Author:		Eric Shepherd (except where noted)
	Date:		January 2008
	Copyright:	2008 Sayers Media Group, LLC. All Rights Reserved
*/

// Defines the console.log() for debugging 
// if it doesn't already exist.
if (typeof console == 'undefined') {
	var console = {
		log: function(msg) { 
			//alert(msg); 
		}
	}
}

var SMG = window.SMG || {};

/**
 * <p>Class Interface - Constructor.</p>
 *
 * @return void
 * @author Ross Harmes and Dustin Diaz
 **/
SMG.Interface = function(name, methods) {
	if (arguments.length != 2) {
		throw new Error('Interface constructor called with ' + arguments.length + ' arguments, but expected exactly 2.');
	}
	this.name = name;
	this.methods = [];
	for (var i = 0, len = methods.length; i<len; i++) {
		if (typeof methods[i] !== 'string') {
			throw new Error('Interface constructor expects method names to be ' + ' passed in as a string.');
		}
		this.methods.push(methods[i]);
	}
};


/**
 * <p>Class Interface - Static class method.</p>
 *
 * @return void
 * @author Ross Harmes and Dustin Diaz
 **/
SMG.Interface.ensureImplements = function(object) {
	if (arguments.length > 2) {
		throw new Error('Function Interface.ensureImplements called with ' + arguments.length + ' arguments, but expected at least 2.');
	}
	for (var i = 1, len = arguments.length; i < len; i++) {
		var interface = arguments[i];
		if (interface.constructor !== Interface) {
			throw new Error('Function Interface.ensureImplements expects arguments two and above to be instances of Interface');
		}
		for (var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
			var method = interface.methods[j];
			if (!object[method] || typeof object[method] !== 'function') {
				throw new Error('Function Interface.ensureImplements: object does no implement the ' 
					+ interface.name + ' interface. Method ' + method + ' was not found.');
			}
		}
	}
};




/***********************
   SMG.clone
***********************/


/**
 * <p>Clone</p>
 *
 * @return A cloned empty object with a prototype attribute
 * @author Unknown
 **/
SMG.clone = function(object) {
	function F() {}
	F.prototype = object;
	return new F;
}




/**********************
   SMG.Error
**********************/


/**
 * <p>Prototype Error</p>
 *
 * @author Eric Shepherd
 **/
SMG.Error = {
	errorMessages		: ['Sorry, there has been an error.'],
	getErrorMessages	: function() {
		return this.errorMessages;
	}
};


/**
 * <p>Form Field Error. There is one error object per form field, with one or multiple error messages.</p>
 *
 * @author Eric Shepherd
 **/
SMG.FormError = SMG.clone(SMG.Error);
SMG.FormError.fieldName			= '';
SMG.FormError.shortErrors		= ['Error'];
SMG.FormError.getFieldName		= function() {
	return this.fieldName;
}
SMG.FormError.getShortErrors	= function() {
	return this.shortErrors;
}




/*******************************
   SMG.Json Utilities
*******************************/

SMG.Json = window.SMG.Json || {};


/**
 * <p>Form Field Error. There is one error object per form field, with one or multiple error messages.</p>
 *
 * @returns An array of SMG.FormError objects
 * @param json A server-provided json object containing all errors for the form in question
 * @author Eric Shepherd
 **/

// TODO: should this be a bridge?
SMG.Json.convertToErrors = function(json) {
	
	var newErrors = [];
	
	for (var field in json) {
		var newError = SMG.clone(SMG.FormError);
		newError.fieldName = field;
		newError.shortErrors = [];
		newError.errorMessages = [];
		for (var shortError in json[field]) {
			newError.shortErrors.push(shortError);
			newError.errorMessages.push(json[field][shortError]['errorMessage']);
		}
		newErrors.push(newError);
	}
	return newErrors;
}


/*********************************
   SMG.PageHelpers
*********************************/

SMG.PageHelpers = window.SMG.PageHelpers || {};

/**
 * <p>Inserts a print link inside a given element.</p>
 *
 * @returns void
 * @param el An HTML element into which to insert the print link
 * @param options An optional parameter containing options such as link text
 * @author Eric Shepherd
 **/
SMG.PageHelpers.addPrintLink = {
	
	linkText : 'Print this page',
		
	init : function(el, options) {
		
		if (!document.createTextNode) return;
		if (!window.print) return;
		
		var linkText = (options && options.linkText) ? options.linkText : 'Print this page';
				
		var link = document.createElement('a');
		link.id = 'print-link';
		link.setAttribute('href', '#');
		link.appendChild(document.createTextNode(linkText));
		link.onclick = function() {
			window.print();
			return false;
		}
		try {
			el.appendChild(link);
		} catch (e) {
			console.log('SMG.PageHelpers.addPrintLink: Could not insert print link; the expected elements were not found on the page');
		}
	}
};