(function() {

// 年的上限和下限
var yearLowerBorder = 1000;
var yearUpperBorder = 9999;

// 月名称数组
// Javascript 中 Date 类型的 getMonth 得到的是从零开始的序号，而不是月，也就是说 0 代表 1 月，11 代表 12 月。
// 正好利用这个特性，省去了 1 位数补零，2 位数不变这种恶心的处理。
var months= ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];

// 模拟枚举
function YearOnly() {}
function YearAndMonth() {}

function MoveStance() {};
function InputStance() {};

function DateTimePicker(type)
{
	// 目前只支持“年”、“年月”两种类型，如果不是这两种类型，直接抛出一个异常
	if ((type.constructor === YearOnly || type.constructor === YearAndMonth) === false)
	{
		throw new Error("Unsupported datetime type!");
	}

	var reliable = true;
	var value = {
		"empty": true,
		"year": 0,
		"month": 0
	};

	var eventListeners = {
		'change': [],
		'validate': []
	};

	var controlEnabled = true;
	var canMoveBackward = true;
	var canMoveForward = true;

	var control = null;

	var moveStance = null;
	var backward = null;
	var display = null;
	var forward = null;

	var inputStance = null;
	var input = null;

	// 更新显示的内容，并调用所有的 change 事件处理函数
	function update()
	{
		// 移除原有的显示内容
		if (display.firstChild)
		{
			display.removeChild(display.firstChild)
		}

		// 控制向前和向后两个按钮的可用与否
		var ignoreMonth = type.constructor === YearOnly;
		if (value.year === yearLowerBorder && (ignoreMonth || value.month === 0))
		{
			canMoveBackward = false;
			canMoveForward = true;
		}
		else if (value.year === yearUpperBorder && (ignoreMonth || value.month === 11))
		{
			canMoveBackward = true;
			canMoveForward = false;
		}
		else
		{
			canMoveBackward = true;
			canMoveForward = true;
		}
		forward.disabled = !(controlEnabled && canMoveForward);
		forward.className = "directionButton " + (forward.disabled ? "forwardDisabled" : "forward");
		backward.disabled = !(controlEnabled && canMoveBackward);
		backward.className = "directionButton " + (backward.disabled ? "backwardDisabled" : "backward");

		// 显示新的值
		var valueString = input.value = getValue();
		display.appendChild(document.createTextNode(valueString));

		// 依次调用 change 事件的处理函数
		for (var i = 0, n = eventListeners.change.length; i < n; ++i)
		{
			eventListeners.change[i](valueString);
		}
	}

	// 获取整个控件的容器
	function getControl()
	{
		return control;
	}

	// 设定控件的值为当前时间
	function moveToNow()
	{
		reliable = false;
		var now = new Date();
		value = {
			"empty": false,
			"year": now.getFullYear(),
			"month": now.getMonth()
		};
		update();
		reliable = true;
	}

	// 前移一个月
	function monthMoveBackward()
	{
		if (value === null || value.empty) moveToNow();
		reliable = false;
		if (value.month > 0)
		{
			--value.month;
		}
		else if (value.year > yearLowerBorder)
		{
			--value.year;
			value.month = 11;
		}
		update();
		reliable = true;
	}

	// 前移一年
	function yearMoveBackward()
	{
		if (value === null || value.empty) moveToNow();
		reliable = false;
		if (value.year > yearLowerBorder)
		{
			--value.year;
		}
		update();
		reliable = true;
	}

	var moveBackward = type instanceof YearOnly ? yearMoveBackward : monthMoveBackward;

	// 后移一个月
	function monthMoveForward()
	{
		if (value === null || value.empty) moveToNow();
		reliable = false;
		if (value.month < 11)
		{
			++value.month;
		}
		else if (value.year < yearUpperBorder)
		{
			++value.year;
			value.month = 0;
		}
		update();
		reliable = true;
	}

	// 后移一年
	function yearMoveForward()
	{
		reliable = false;
		if (value === null || value.empty) moveToNow();
		(value.year < yearUpperBorder) && (++value.year);
		update();
		reliable = true;
	}

	var moveForward = type instanceof YearOnly ? yearMoveForward : monthMoveForward;

	// 注册一个事件处理函数
	function addEventListener(type, handler)
	{
		if (type in eventListeners)
		{
			eventListeners[type].push(handler);
		}
	}

	// 取得控件的当前值
	function getValue()
	{
		var result = "";
		if (value === null || value.empty)
		{
			result = "";
		}
		else
		{
			result = type instanceof YearOnly ? value.year.toString() : value.year + "-" + months[value.month]
		}
		return result;
	}

	// 设定控件的当前值为指定值
	// 成功返回 true，失败返回 false
	function setValue(inputString)
	{
		var legal = false;
		var newValue = {
			"empty": true,
			"year": 0,
			"month": 0
		};

		if (inputString === "")
		{
			legal = true;
		}
		else
		{
			newValue.empty = false;

			var regEx = /^([1-9][0-9]{0,3})([\/\.\-]([0-9]{1,2}))?/;
			var tokens = null;
			if (tokens = inputString.match(regEx))
			{
				var year = parseInt(tokens[1], 10);
				if (isNaN(year) || year < yearLowerBorder || year > yearUpperBorder)
				{
					year = NaN;
				}

				var month = parseInt(tokens[3], 10);
				if (isNaN(month) || month < 1 || month > 12)
				{
					month = NaN;
				}

				if (!isNaN(year))
				{
					newValue.year = year;

					if (type instanceof YearOnly)
					{
						legal = true;
					}
					else if (!isNaN(month))
					{
						newValue.month = month - 1;
						legal = true;
					}
				}
			}
		}

		if (legal)
		{
			reliable = false;
			value = newValue;
			update();
			reliable = true;
		}
		else
		{
			for (var i = 0, n = eventListeners.validate.length; i < n; ++i)
			{
				eventListeners.validate[i]();
			}
		}
		return legal;
	}

	function changeStance(stance)
	{
		if (stance instanceof MoveStance)
		{
			reliable = true;
			moveStance.style.display = "";
			inputStance.style.display = "none";
		}
		else if (stance instanceof InputStance)
		{
			reliable = false;
			moveStance.style.display = "none";
			inputStance.style.display = "";
		}
		else
		{
			throw new Error("Unsupported stance!");
		}
	}
	this.changeStance = changeStance;

	function setEnabled(enabled)
	{
		controlEnabled = enabled;

		display.disabled = !enabled;
		forward.disabled = !(controlEnabled && canMoveForward);
		forward.className = "directionButton " + (forward.disabled ? "forwardDisabled" : "forward");
		backward.disabled = !(controlEnabled && canMoveBackward);
		backward.className = "directionButton " + (backward.disabled ? "backwardDisabled" : "backward");
	}

	function inputBlur()
	{
		if (setValue(input.value))
		{
			changeStance(DateTimePicker.Stance.MoveStance);
			return true;
		}
		else
		{
			try
			{
				input.select();
				input.focus();
			}
			catch (e) {}
			return false;
		}
	}

	function inputKeyDown(event)
	{
		keyCode = window.event ? window.event.keyCode : event.which;
		if (keyCode === 13)
		{
			inputBlur();
			if (window.event)
			{
				return false
			}
			else
			{
				event.preventDefault();
			}
		}
	}

	function isReliable()
	{
		return reliable;
	}

	this.getControl = getControl;
	this.moveToNow = moveToNow;
	this.addEventListener = addEventListener;
	this.getValue = getValue;
	this.setValue = setValue;
	this.moveBackward = moveBackward;
	this.moveForward = moveForward;
	this.setEnabled = setEnabled;
	this.isReliable = isReliable;

	(function construct()
	{
		control = document.createElement("span");
		control.className = "dateTimePicker ";
		control.className += (type.constructor === YearOnly ? "yearOnly" : "yearAndMonth");

		moveStance = document.createElement("span");
		moveStance.className = "moveStance";

		backward = document.createElement("a");
		backward.className = "directionButton backward";
		backward.onclick = moveBackward;
		backward.href = "javascript: void 0;";
		moveStance.appendChild(backward);

		display = document.createElement("a");
		display.className = type instanceof YearOnly ? "yearOnlyDisplay" : "yearAndMonthDisplay";
		display.href = "javascript: void 0;";
		display.onclick = function()
		{
			var valueString = getValue();
			if (valueString === "") moveToNow();
			changeStance(DateTimePicker.Stance.InputStance);
			input.select();
		}
		moveStance.appendChild(display);

		forward = document.createElement("a");
		forward.className = "directionButton forward";
		forward.onclick = moveForward;
		forward.href = "javascript: void 0;";
		moveStance.appendChild(forward);

		control.appendChild(moveStance);

		inputStance = document.createElement("span");
		inputStance.style.display = "none";

		input = document.createElement("input");
		input.type = "text";
		input.className = (type instanceof YearOnly ? "yearOnlyInput" : "yearAndMonthInput") + (document.compatMode === "CSS1Compat" ? "" : "Quirk");
		input.maxLength = type instanceof YearOnly ? "4" : "7";
		input.onblur = inputBlur;
		if (window.ActiveXObject)
		{
			input.attachEvent("onkeydown", inputKeyDown);
		}
		else
		{
			input.addEventListener("keydown", inputKeyDown, false);
		}
		inputStance.appendChild(input);

		control.appendChild(inputStance);

	})();
}

DateTimePicker.Type = {
	'YearOnly': new YearOnly(),
	'YearAndMonth': new YearAndMonth()
};

DateTimePicker.Stance = {
	"MoveStance": new MoveStance(),
	"InputStance": new InputStance()
};

window.DateTimePicker = DateTimePicker;

})();

(function() {

function Button(text)
{
	var anchor = null;

	this.getControl = function() {
		return anchor;
	};

	(function construct() {
		anchor = document.createElement("a");
		anchor.className = "yearMonthButton";

		anchor.appendChild(document.createTextNode(text));
	})();
}

function DateTimeSelector()
{
	var iframe = null;
	var container = null;
	var toolbar = null;
	var currentPage = null;
	var backupPage = null;

	var backward = null;
	var display = null;
	var forward = null;

	var buttons = [];

	function moveTo(x, y)
	{
		iframe.style.left = container.style.left = x;
		iframe.style.top = container.style.top = y;
	}

	(function construct(){
		iframe = document.createElement("iframe");
		iframe.className = "dateTimeSelectorPlatform"
		iframe.style.width = iframe.style.height = 200 + "px";
		document.body.appendChild(iframe);

		container = document.createElement("div");
		container.className = "dateTimeSelector"
		document.body.appendChild(container);
		container.style.width = container.style.height = 200 + "px";

		toolbar = container.appendChild(document.createElement("div"));
		toolbar.className = "toolbar";

		backward = toolbar.appendChild(document.createElement("a"));
		backward.className = "directionButton backward";
		backward.href = "javascript: void 0;";

		display = toolbar.appendChild(document.createElement("a"));
		display.className = '';

		moveTo(200, 120);
	})();
}

// window.DateTimeSelector = DateTimeSelector;
// window.Button = Button;

})();