/* $Id: common.js 613 2009-11-21 00:37:07Z rfludwick $ */

var GLOBALS = $H({});
GLOBALS.set("mobile", false);

/**
 * OMGN cookies
 */
var OMGNCookie =
{
	/*
	 * Sets a cookie
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param name The cookie name
	 * @param value The cookie value
	 * @param number_days The number of days to set the cookie for
	 * @return void
	 */
	set : function(name, value, number_days)
	{
		var expires = "";

		if (number_days)
		{
			var date = new Date();
			date.setTime(date.getTime() + (number_days * 24 * 60 * 60 * 1000));

			expires = "; expires=" + date.toGMTString();
		}

		document.cookie = name + "=" + value + expires + "; path=/" + (document.domain.match(/omgn.com$/) ? "; domain=omgn.com" : "");
	},

	/*
	 * Gets a cookie's value
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param name The cookie name
	 * @return The cookie value
	 */
	get : function(name)
	{
		var name_equals = name + "=",
			cookies = document.cookie.split(";");

		for (var counter = 0; counter < cookies.length; counter++)
		{
			var cookie = cookies[counter];

			while (cookie.charAt(0) == " ")
			{
				cookie = cookie.substring(1, cookie.length);
			}

			if (cookie.indexOf(name_equals) == 0)
			{
				return (cookie.substring(name_equals.length, cookie.length));
			}
		}

		return ("");
	},

	/*
	 * Clears a cookie
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param name The cookie name
	 * @return void
	 */
	clear : function(name)
	{
		this.set(name, "", -1);
	}
};

/**
 * OMGN dates
 */
var OMGNDate =
{
	/*
	 * Creates a YYYY-MM-DD format for a date
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param date The date
	 * @return The YYYY-MM-DD format for the date
	 */
	createYMD : function(date)
	{
		var month = (date.getMonth() + 1),
			day = date.getDate();

		return (date.getFullYear() + "-" + ((month < 10) ? "0" : "") + month + "-" + ((day < 10) ? "0" : "") + day);
	},

	/*
	 * Creates a textual date
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param date The date to create textual
	 * @return The textual date
	 */
	createTextual : function(date)
	{
		return (OMGNDate.translateDayOfWeek(date.getDay()) + ", " + OMGNDate.translateMonth(date.getMonth()) + " " + OMGNFormat.addNumericalSuffix(date.getDate())
			+ ", " + date.getFullYear());
	},

	/*
	 * Translates a day of the week into a textual one
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param day The day of the week
	 * @return The textual day of the week
	 */
	translateDayOfWeek : function(day)
	{
		switch (day)
		{
			case 0:
			{
				return ("Sunday");
			} break;
			case 1:
			{
				return ("Monday");
			} break;
			case 2:
			{
				return ("Tuesday");
			} break;
			case 3:
			{
				return ("Wednesday");
			} break;
			case 4:
			{
				return ("Thursday");
			} break;
			case 5:
			{
				return ("Friday");
			} break;
			case 6:
			{
				return ("Saturday");
			} break;
			default:
			{
				return ("");
			} break;
		}
	},

	/*
	 * Translates a numerical month into a textual one
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param month The month
	 * @return The textual month
	 */
	translateMonth : function(month)
	{
		switch (month)
		{
			case 0:
			{
				return ("January");
			} break;
			case 1:
			{
				return ("February");
			} break;
			case 2:
			{
				return ("March");
			} break;
			case 3:
			{
				return ("April");
			} break;
			case 4:
			{
				return ("May");
			} break;
			case 5:
			{
				return ("June");
			} break;
			case 6:
			{
				return ("July");
			} break;
			case 7:
			{
				return ("August");
			} break;
			case 8:
			{
				return ("September");
			} break;
			case 9:
			{
				return ("October");
			} break;
			case 10:
			{
				return ("November");
			} break;
			case 11:
			{
				return ("December");
			} break;
			default:
			{
				return ("");
			} break;
		}
	}
};

/**
 * OMGN format
 */
var OMGNFormat =
{
	/*
	 * Adds a numerical suffix to a number
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param number The number
	 * @return The number with its suffix
	 */
	addNumericalSuffix : function(number)
	{
		var last_2 = (number % 100),
			last_1 = (number % 10);

		if ((last_2 >= 11) && (last_2 <= 13))
		{
			return (number + "th");
		}
		else
		{
			switch (last_1)
			{
				case 0:
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:
				case 9:
				{
					return (number + "th");
				} break;
				case 1:
				{
					return (number + "st");
				} break;
				case 2:
				{
					return (number + "nd");
				} break;
				case 3:
				{
					return (number + "rd");
				} break;
			}
		}

		return ("");
	}
};

/**
 * OMGN Ajax base
 */
var OMGNAjaxBase =
{
	/** @var default_error The base error message */
	default_error : "There has been an generic Ajax error.",

	/** @var contact_link The contact link */
	contact_link : 'Please <a href="/static/contact-us" title="Contact Us">contact us</a> with as much detail as possible, thank you.',

	/** @var number_processing The number of ongoing Ajax calls processing */
	number_processing : 0,

	/**
	 * Initializes the Ajax base
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @return void
	 */
	init : function()
	{
		document.observe("mousemove", function(event)
		{
			GLOBALS.set("mouse_x", event.pointerX());
			GLOBALS.set("mouse_y", event.pointerY());
		});

		document.observe("keyup", function(event)
		{
			if (OMGNAjaxBase.getKeyCode(event) == Event.KEY_ESC)
			{
				OMGNOverlay.remove();
			}
		});
	},

	/*
	 * Gets a keycode from an event
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param event The event
	 * @return The keycode
	 */
	getKeyCode : function(event)
	{
		// Get the event if we have to
		if (!event)
		{
			event = window.event;
		}

		event = Event.extend(event);

		// Get the code
		return (event.keyCode ? event.keyCode : event.which);
	},

	/*
	 * Alerts of an Ajax error
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param error The error message
	 * @return void
	 */
	showError : function(error)
	{
		if (!error || !error.length)
		{
			error = this.default_error;
		}

		OMGNOverlay.write('<div class="title">Ajax Error</div><p>' + error + "</p><p>" + this.contact_link + "</p>", "ajax_error");
	},

	/**
	 * Shows the Ajax processing indicator
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @return void
	 */
	showProcessing : function()
	{
		if (!GLOBALS.get("mobile"))
		{
			this.number_processing++;

			if (this.number_processing == 1)
			{
				var ajax_indicator = $("ajax_indicator");

				if (!ajax_indicator)
				{
					ajax_indicator = new Element("img", {
						src : "/images/ajax.gif",
						width : 32,
						height : 16,
						alt : "Ajax Processing",
						title : "Ajax Processing",
						id : "ajax_indicator"
					}).addClassName("ajax_processing").setStyle({
						left : (GLOBALS.get("mouse_x") + 10) + "px",
						top : (GLOBALS.get("mouse_y") + 10) + "px"
					});

					var bodies = $$("body"),
						body = bodies[0];

					body.insert(ajax_indicator);

					OMGNBinds.set("OMGNAjaxBase_attachToMouse", this.attachToMouse.bind(this));
					document.observe("mousemove", OMGNBinds.get("OMGNAjaxBase_attachToMouse"));
				}
			}
		}
	},

	/**
	 * Hides the Ajax processing indicator
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @return void
	 */
	hideProcessing : function()
	{
		if (!GLOBALS.get("mobile"))
		{
			this.number_processing--;

			if (this.number_processing <= 0)
			{
				var ajax_indicator = $("ajax_indicator");

				if (ajax_indicator)
				{
					ajax_indicator.remove();

					document.stopObserving("mousemove", OMGNBinds.get("OMGNAjaxBase_attachToMouse"));
				}

				this.number_processing = 0;
			}
		}
	},

	/**
	 * Attaches the image to the mouse
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param event The triggering event
	 * @return void
	 */
	attachToMouse : function(event)
	{
		var ajax_indicator = $("ajax_indicator");

		ajax_indicator.setStyle({
			left : (event.pointerX() + 10) + "px",
			top : (event.pointerY() + 10) + "px"
		});
	},

	/**
	 * Fades an element during Ajax processing
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param element The element to fade
	 * @return void
	 */
	fadeElement : function(element)
	{
		element.setStyle({
			opacity : 0.5,
			filter : "alpha(opacity = 50)"
		});
	},

	/**
	 * Unfades an element during Ajax processing
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param element The element to unfade
	 * @return void
	 */
	unfadeElement : function(element)
	{
		element.setStyle({
			opacity : 1,
			filter : "alpha(opacity = 100)"
		});
	},

	/**
	 * Strips HTML tags from the supplied string
	 *
	 * @author Kevin van Zonneveld
	 * @param string The string
	 * @param allowed_tags The allowed tags
	 * @return The stripped string
	 */
	stripHTMLTags : function(string, allowed_tags)
	{
		allowed_tags = (((allowed_tags || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
		var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
			commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
		return string.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
			return allowed_tags.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
    })
}

};

/**
 * OMGN overlay
 */
var OMGNOverlay =
{
	/**
	 * @var scroll_offsets The scroll offsets
	 */
	scroll_offsets : {},

	/**
	 * @var binds The binds
	 */
	binds : $A([]),

	/**
	 * Builds the overlay
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param contents The contents to put in the overlay
	 * @param container_class The container class
	 * @return void
	 */
	write : function(contents, container_class)
	{
		// Set bind
		OMGNBinds.set("OMGNOverlay_remove", this.remove.bind(this));

		// Do we have an existing overlay?
		var existing_overlay_vertical = $("overlay_vertical");

		if (existing_overlay_vertical)
		{
			this.remove();
		}

		// Body, height and width
		var bodies = $$("body"),
			body = bodies[0];

		body.setStyle({
			"overflow" : "hidden"
		});

		var body_dimensions = body.getDimensions(),
			viewport_dimensions = document.viewport.getDimensions(),
			scroll_offsets = document.viewport.getScrollOffsets();

		// Overlay background
		var overlay_background = new Element("div", {
			id : "overlay_background"
		}).setStyle({
			width : ((body_dimensions.width > viewport_dimensions.width) ? body_dimensions.width : viewport_dimensions.width) + "px",
			height : ((body_dimensions.height > viewport_dimensions.height) ? body_dimensions.height : viewport_dimensions.height) + "px"
		});

		// Overlay vertical
		var overlay_vertical = new Element("div", {
			id : "overlay_vertical"
		});

		// Overlay and close
		var overlay = new Element("div", {
			id : "overlay"
		}).addClassName("overlay");

		if (container_class)
		{
			overlay.addClassName(container_class);
		}

		var overlay_close = new Element("div", {
			id : "overlay_close"
		}).addClassName("close").update("X");

		// Update
		body.insert(overlay_background).insert(overlay_vertical.insert(overlay.insert(contents).insert('<div class="clear"></div>'))).insert(overlay_close);

		// Positioning
		var vertical_height = overlay_vertical.getHeight(),
			top = Math.round(scroll_offsets.top + (viewport_dimensions.height / 2) - (vertical_height / 2)),
			close_dimensions = overlay_close.getDimensions(),
			close_right = overlay.getLayout().get("right");

		overlay_vertical.setStyle({
			height : vertical_height + "px",
			top : top + "px"
		});

		if (!GLOBALS.get("mobile"))
		{
			close_right -= (close_dimensions.width / 2);
		}

		overlay_close.setStyle({
			top : Math.round(top - (close_dimensions.height / 2)) + "px",
			right : Math.round(close_right) + "px"
		});

		// Hide objects
		var objects = $$("object");

		if (objects.size())
		{
			objects.each(function(item)
			{
				item.toggle();
			}.bind(this));
		}

		// Attack close
		this.attachClickClose($A([
			"overlay_close"
		]));
	},

	/**
	 * Removes the hover
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param event If supplied, the event that kicked off the removal
	 * @return void
	 */
	remove : function(event)
	{
		// Drop overlay
		var overlay_background = $("overlay_background"),
			overlay_vertical = $("overlay_vertical"),
			overlay_close = $("overlay_close");

		if (overlay_background)
		{
			overlay_background.remove();
		}
		if (overlay_vertical)
		{
			overlay_vertical.remove();
		}
		if (overlay_close)
		{
			overlay_close.remove();
		}

		// Show objects
		var objects = $$("object");

		if (objects.size())
		{
			objects.each(function(item)
			{
				item.show();
			}.bind(this));
		}

		// Re-enable scrolling on body
		var bodies = $$("body"),
			body = bodies[0];

		body.setStyle({
			overflow : "scroll"
		});

		// Stop event
		if (event)
		{
			Event.stop(event);
		}
	},

	/**
	 * Attaches the remove function to the following element ids via click
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param element_ids The element IDs to attach close to
	 * @return void
	 */
	attachClickClose : function(element_ids)
	{
		element_ids.each(function(item)
		{
			var element = $(item);

			if (element)
			{
				element.observe("click", OMGNBinds.get("OMGNOverlay_remove"));
			}
		}.bind(this));
	},

	/**
	 * Removes the remove function from the following element ids via click
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param element_ids The element IDs to remove close from
	 * @return void
	 */
	removeClickClose : function(element_ids)
	{
		element_ids.each(function(item)
		{
			var element = $(item);

			if (element)
			{
				element.stopObserving("click", OMGNBinds.get("OMGNOverlay_remove"));
			}
		}.bind(this));
	},

	/**
	 * Shows an error
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param error The error message
	 * @return void
	 */
	showError : function(error)
	{
		this.write('<div class="title">Error</div><p>' + error + '</p>', "error");
	},

	/**
	 * Shows a success
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param success The success message
	 * @return void
	 */
	showSuccess : function(success)
	{
		this.write('<div class="title">Success</div><p>' + success + '</p>', "success");
	}
};

/**
 * OMGN auto focus
 */
var OMGNAutoFocus =
{
	/**
	 * Focuses on a particular element ID
	 *
	 * @author Robert F. Ludwick <rfludwick@darqflare.com>
	 * @param id The element ID to focus
	 * @param select_contents A flag to select the contents
	 * @return void
	 */
	autofocus : function(id, select_contents)
	{
		var element = $(id);

		if (element)
		{
			if (select_contents)
			{
				element.activate();
			}
			else
			{
				element.focus();
			}
		}
	}
};

/**
 * Fixes tinyMCE tabbing issues; from http://tinymce.moxiecode.com/punbb/viewtopic.php?pid=56589
 * @param instance The tinyMCE instance
 * @return void
 */
function fixTinyMCETabIssue(instance)
{
    instance.onKeyDown.add(function(instance, event)
	{
        var code = null;

        if (event.keyCode)
		{
			code = event.keyCode;
		}
        else if (event.which)
		{
			code = event.which;
		}

        if((code == 9) && !event.altKey && !event.ctrlKey)
		{
            // toggle between Indent and Outdent command, depending on if SHIFT is pressed
            if (event.shiftKey)
			{
				instance.execCommand('Outdent');
			}
            else
			{
				instance.execCommand('Indent');
			}

            // prevent tab key from leaving editor in some browsers
            Event.stop(event);
        }
    });
}

/**
 * OMGN binds
 */
var OMGNBinds = $H({});

// Required fields
var required_fields = '<div class="required">Required fields in <strong>purple</strong></div>';

// Setup clear form buttons
document.observe("dom:loaded", function()
{
	$$("input.clear_form").each(function(item)
	{
		item.observe("click", function(event)
		{
			var element = event.element(),
				form = element.up("form"),
				submit_button = null;

			form.descendants().each(function(item_2)
			{
				switch(item_2.nodeName)
				{
					case "INPUT":
						var type = item_2.getAttribute("type");

						if (type == "submit")
						{
							submit_button = item_2;
						}
						else if ((type != "button") && (type != "reset"))
						{
							item_2.clear();
						}
						break;
					case "TEXTAREA":
						item_2.clear();
						break;
				}
			});

			if (element.hasClassName("auto_submit") && submit_button)
			{
				submit_button.click();
			}

			Event.stop(event);
		});
	});
});
