var objectifier;

(function ($) {
	var method = function () {
		this.index = [];
		this.instances = [];
		this.storage = [];
	}

	method.prototype = {
		destroy: function (name) {
			// Declare variables.
			var id, instance;

			id = $.inArray(name, this.index);

			if (id === -1) {
				// Assume it doesn't exist.
				return null;
			}

			instance = this.instances[id];

			// Set the object to inactive, and call the closure.
			instance.active = false;
			instance.initiate();

			this.index[id] = null;
			this.storage[id] = null;
			this.instances[id] = null;

			delete this.index[id];
			delete this.storage[id];
			delete this.instances[id];
			delete instance;

			return null;
		},

		get: function (name) {
			// Declare variables.
			var id;

			id = $.inArray(name, this.index);

			if (id === -1) {
				// Dynamically generate a new object.
				return this.make(name, null);
			}

			// Return the method.
			return this.instances[id].initiate;
		},

		make: function (name, method) {
			// Declare variables.
			var id, instance, object;

			id = name ? $.inArray(name, this.index) : -1;

			if (id === -1) {
				object = function () {
					this.active = true;

					return null;
				};

				// Create a new instance of the object.
				instance = new object();

				object.prototype.initiate = (function (instance) {
					return function () {
						if (!instance) {
							return null;
						}

						if (instance.active) {
							// Call the initiate function. If it is not present, it will crash.
							return instance.method.apply(this, arguments);
						}

						// Delete the instance, hopefully freeing it from memory.
						instance = null;
						delete instance;

						return null;
					};
				})(instance);
			} else {
				object = this.storage[id];
				instance = this.instances[id];
			}

			if (method) {
				// Prototype it!
				object.prototype.method = method;
			}

			if (id === -1 && name) {
				// Store the object.
				this.index.push(name);
				this.storage.push(object);
				this.instances.push(instance);
			}

			// Return the method.
			return instance.initiate;
		}
	}

	var object = function () {
		this.index = [];
		this.storage = [];
	}

	object.prototype = {
		destroy: function (name) {
			// Declare variables.
			var id;

			id = $.inArray(name, this.index);

			if (id === -1) {
				return null;
			}

			this.index[id] = null;
			this.storage[id] = null;

			delete this.index[id];
			delete this.storage[id];

			return null;
		},

		get: function (name, factory, instance) {
			// Declare variables.
			var id;

			id = $.inArray(name, this.index);

			if (id === -1) {
				// Dynamically generate a new object.
				return this.make(name, factory, null);
			}

			// Return the object.
			return this.storage[id];
		},

		make: function (name, factory, prototype) {
			// Declare variables.
			var i, id, object;

			id = name ? $.inArray(name, this.index) : -1;

			if (id === -1) {
				if (factory) {
					object = function () {
						if (this.initiate) {
							// Call the initiate function. If it is not present, it will crash.
							this.initiate.apply(this, arguments);
						}

						return null;
					};
				} else {
					object = {};
				}
			} else {
				object = this.storage[id];
			}

			if (prototype) {
				if (factory) {
					for (i in object.prototype) {
						delete object.prototype[i];
					}

					// Prototype it!
					for (i in prototype) {
						object.prototype[i] = prototype[i];
					}
				} else {
					for (i in object) {
						delete object[i];
					}

					// Prototype it!
					for (i in prototype) {
						object[i] = prototype[i];
					}
				}
			}

			if (id === -1 && name) {
				// Store the object.
				this.index.push(name);
				this.storage.push(object);
			}

			// Return the object.
			return object;
		}
	}

	var objectifier = {
		method: function () {
			// Get a new method constructor.
			return new method();
		},

		object: function () {
			// Get a new object constructor.
			return new object();
		}
	}

	// Export it to the global variable.
	window.objectifier = objectifier;
})(jQuery);

