var Note = Class.create()
Note.zindex = 0
Note.counter = -1
Note.all = []
Note.display = true

Note.show = function() {
	for (var i=0; i<Note.all.length; ++i) {
		Note.all[i].bodyHide()
		Note.all[i].elements.box.style.display = "block"
	}
}

Note.hide = function() {
	for (var i=0; i<Note.all.length; ++i) {
		Note.all[i].bodyHide()
		Note.all[i].elements.box.style.display = "none"
	}
}

Note.find = function(id) {
	for (var i = 0; i<Note.all.length; ++i) {
		if (Note.all[i].id == id) {
			return Note.all[i]
		}
	}

	return null
}

Note.toggle = function() {
	if (Note.display) {
		Note.hide()
		Note.display = false
	}
	else
	{
		// only show the note of not resized
		var img = $("image");
 		if ((img.scale_factor == 1) || (img.scale_factor == null))
		{
			Note.show()
			Note.display = true
		}
	}
}

Note.updateNoteCount = function() {
	// function deleted since not used in main code just now.
};

Note.create = function() {
	var note = ''
	note += '<div class="note-box" style="width: 150px; height: 150px; '
	note += 'top: ' + ($('image').clientHeight / 2 - 75) + 'px; '
	note += 'left: ' + ($('image').clientWidth / 2 - 75) + 'px;" '
	note += 'id="note-box-' + Note.counter + '">'
	note += '<div class="note-corner" id="note-corner-' + Note.counter + '"></div>'
	note += '</div>'
	note += '<div class="note-body" title="Click to edit" id="note-body-' + Note.counter + '"></div>'
	new Insertion.Bottom('note-container', note)
	Note.all.push(new Note(Note.counter, true, ''))
	Note.counter -= 1
};

Note.prototype = {
	// Necessary because addEventListener/removeEventListener don't play nice with
	// different instantiations of the same method.
	bind: function(method_name) {
		if (!this.bound_methods) {
			this.bound_methods = new Object()
		}

		if (!this.bound_methods[method_name]) {
			this.bound_methods[method_name] = this[method_name].bindAsEventListener(this)
		}

		return this.bound_methods[method_name]
	},

	initialize: function(id, is_new, raw_body) {
		this.id = id
		this.is_new = is_new

		// get the elements
		this.elements = {
			box:		$('note-box-' + this.id),
			corner:		$('note-corner-' + this.id),
			body:		$('note-body-' + this.id),
			image:		$('image')
		}

		// store the data
		this.old = {
			left:           this.elements.box.offsetLeft,
			top:            this.elements.box.offsetTop,
			width:          this.elements.box.clientWidth,
			height:         this.elements.box.clientHeight,
			raw_body:       raw_body,
			formatted_body: this.elements.body.innerHTML
		}

		// reposition the box to be relative to the image

		this.elements.box.style.top = this.elements.box.offsetTop + "px"
		this.elements.box.style.left = this.elements.box.offsetLeft + "px"

		// attach the event listeners
		Event.observe(this.elements.box, "mousedown", this.bind("dragStart"), true)
		Event.observe(this.elements.box, "mouseout", this.bind("bodyHideTimer"), true)
		Event.observe(this.elements.box, "mouseover", this.bind("bodyShow"), true)
		Event.observe(this.elements.corner, "mousedown", this.bind("resizeStart"), true)
		Event.observe(this.elements.body, "mouseover", this.bind("bodyShow"), true)
		Event.observe(this.elements.body, "mouseout", this.bind("bodyHideTimer"), true)
		Event.observe(this.elements.body, "click", this.bind("showEditBox"), true)
	},

	textValue: function() {
		return this.old.raw_body.replace(/(?:^\s+|\s+$)/, '')
	},

	hideEditBox: function(e) {
		var editBox = $('edit-box')

		if (editBox != null) {
			// redundant?
			Event.stopObserving('note-save-' + this.id, 'click', this.bind("save"), true)
			Event.stopObserving('note-cancel-' + this.id, 'click', this.bind("cancel"), true)
			Event.stopObserving('note-remove-' + this.id, 'click', this.bind("remove"), true)
			Event.stopObserving('note-history-' + this.id, 'click', this.bind("history"), true)

			Element.remove('edit-box')
		}

	},

	showEditBox: function(e) {
		var editBox = $('edit-box')

		this.hideEditBox(e)

		var inject = ''
		Position.prepare()

		var top = Position.deltaY
		var left = Position.deltaX

		inject += '<div id="edit-box" style="width: 350px; height: 150px; top: '+top+'px; left: '+left+'px; z-index: 1000;">'
		inject += '<form onsubmit="return false;">'
		inject += '<textarea rows="6" id="edit-box-text">' + this.textValue() + '</textarea>'
		inject += '<input type="submit" value="Save" name="save" id="note-save-' + this.id + '" />'
		inject += '<input type="submit" value="Cancel" name="cancel" id="note-cancel-' + this.id + '" />'
		inject += '<input type="submit" value="Remove" name="remove" id="note-remove-' + this.id + '" />'
		inject += '<input type="submit" value="History" name="history" id="note-history-' + this.id + '" />'
		inject += '</form>'
		inject += '</div>'

		new Insertion.Bottom('note-container', inject)

		Event.observe('note-save-' + this.id, 'click', this.bind("save"), true)
		Event.observe('note-cancel-' + this.id, 'click', this.bind("cancel"), true)
		Event.observe('note-remove-' + this.id, 'click', this.bind("remove"), true)
		Event.observe('note-history-' + this.id, 'click', this.bind("history"), true)
		$("edit-box-text").focus()
	},

	bodyShow: function(e) {
		if (this.dragging)
			return

		if (this.hideTimer) {
			clearTimeout(this.hideTimer)
			this.hideTimer = null
		}

		// hide the other notes
		if (Note.all) {
			for (var i=0; i<Note.all.length; ++i) {
				if (Note.all[i].id != this.id) {
					Note.all[i].bodyHide()
				}
			}
		}

		this.elements.box.style.zIndex = ++Note.zindex
		this.elements.body.style.zIndex = Note.zindex
		this.elements.body.style.top = (this.elements.box.offsetTop + this.elements.box.clientHeight + 5) + "px"
		this.elements.body.style.left = this.elements.box.offsetLeft + "px"
		this.elements.body.style.display = "block"
	},

	bodyHideTimer: function(e) {
		this.hideTimer = setTimeout(this.bind("bodyHide"), 250)
	},

	bodyHide: function(e) {
		this.elements.body.style.display = "none"
	},

	dragStart: function(e) {
		Event.observe(document.documentElement, 'mousemove', this.bind("drag"), true)
		Event.observe(document.documentElement, 'mouseup', this.bind("dragStop"), true)
		document.onselectstart = function() {return false}

		this.cursorStartX = Event.pointerX(e)
		this.cursorStartY = Event.pointerY(e)
		this.boxStartX = this.elements.box.offsetLeft
		this.boxStartY = this.elements.box.offsetTop
		this.dragging = true

		this.bodyHide()
	},

	dragStop: function(e) {
		Event.stopObserving(document.documentElement, 'mousemove', this.bind("drag"), true)
		Event.stopObserving(document.documentElement, 'mouseup', this.bind("dragStop"), true)
		document.onselectstart = function() {return true}

		this.cursorStartX = null
		this.cursorStartY = null
		this.boxStartX = null
		this.boxStartY = null
		this.dragging = false

		this.bodyShow()
	},

	drag: function(e) {
		var left = this.boxStartX + Event.pointerX(e) - this.cursorStartX
		var top = this.boxStartY + Event.pointerY(e) - this.cursorStartY
		var bound

		bound = 5
		if (left < bound)
			left = bound

		bound = this.elements.image.clientWidth - this.elements.box.clientWidth - 5
		if (left > bound)
			left = bound

		bound = 5
		if (top < bound)
			top = bound

		bound = this.elements.image.clientHeight - this.elements.box.clientHeight - 5
		if (top > bound)
			top = bound

		this.elements.box.style.left = left + 'px'
		this.elements.box.style.top = top + 'px'

		Event.stop(e)
	},

	resizeStart: function(e) {
		this.cursorStartX = Event.pointerX(e)
		this.cursorStartY = Event.pointerY(e)
		this.boxStartWidth = this.elements.box.clientWidth
		this.boxStartHeight = this.elements.box.clientHeight
		this.boxStartX = this.elements.box.offsetLeft
		this.boxStartY = this.elements.box.offsetTop
		this.dragging = true

		Event.stopObserving(document.documentElement, 'mousemove', this.bind("drag"), true)
		Event.stopObserving(document.documentElement, 'mouseup', this.bind("dragStop"), true)
		Event.observe(document.documentElement, 'mousemove', this.bind("resize"), true)
		Event.observe(document.documentElement, 'mouseup', this.bind("resizeStop"), true)

		this.bodyHide()
	},

	resizeStop: function(e) {
		Event.stopObserving(document.documentElement, 'mousemove', this.bind("resize"), true)
		Event.stopObserving(document.documentElement, 'mouseup', this.bind("resizeStop"), true)

		this.boxCursorStartX = null
		this.boxCursorStartY = null
		this.boxStartWidth = null
		this.boxStartHeight = null
		this.boxStartX = null
		this.boxStartY = null
		this.dragging = false
	},

	resize: function(e) {
		var w = this.boxStartWidth + Event.pointerX(e) - this.cursorStartX
		var h = this.boxStartHeight + Event.pointerY(e) - this.cursorStartY
		var bound

		if (w < 10)
			w = 10

		bound = this.elements.image.clientWidth - this.boxStartX - 5
		if (w > bound)
			w = bound

		if (h < 10)
			h = 10

		bound = this.elements.image.clientHeight - this.boxStartY - 5
		if (h > bound)
			h = bound

		this.elements.box.style.width = w + "px"
		this.elements.box.style.height = h + "px"
		this.elements.box.style.left = this.boxStartX + "px"
		this.elements.box.style.top = this.boxStartY + "px"
	},

	save: function(e) {
		this.old.left = this.elements.box.offsetLeft
		this.old.top = this.elements.box.offsetTop
		this.old.width = this.elements.box.clientWidth
		this.old.height = this.elements.box.clientHeight
		this.old.raw_body = $('edit-box-text').value
		this.old.formatted_body = this.textValue()
		this.elements.body.innerHTML = this.textValue()

		this.hideEditBox(e)
		this.bodyHide()

		var params = []
		params.push("note%5Bx%5D=" + this.old.left)
		params.push("note%5By%5D=" + this.old.top)
		params.push("note%5Bwidth%5D=" + this.old.width)
		params.push("note%5Bheight%5D=" + this.old.height)
		params.push("note%5Bbody%5D=" + encodeURIComponent(this.old.raw_body))
		params.push("note%5Bis_active%5D=" + 1)

		
		params.push("note%5Bpost_id%5D=" + Note.post_id)
		

		notice("Saving note...")
		new Ajax.Request('/note/update/' + this.id, {
			asynchronous: true,
			method: 'post',
			parameters: params.join("&"),
			onSuccess: function(req) {
				var response = eval("(" + req.responseText + ")");
				notice("Note Saved!")
				if (response.old_id < 0) {
					
					var n = Note.find(response.old_id)
					n.is_new = false
					n.id = response.new_id
					
					
					n.elements.box.id = 'note-box-' + n.id
					n.elements.body.id = 'note-body-' + n.id
					n.elements.corner.id = 'note-corner-' + n.id
				}
				$("note-body-" + response.new_id).innerHTML = response.formatted_body
			}
		})

		Event.stop(e)
	},

	cancel: function(e) {
		this.hideEditBox(e)
		this.bodyHide()

		this.elements.box.style.top = this.old.top + "px"
		this.elements.box.style.left = this.old.left + "px"
		this.elements.box.style.width = this.old.width + "px"
		this.elements.box.style.height = this.old.height + "px"
		this.elements.body.innerHTML = this.old.formatted_body

		Event.stop(e)
	},

	removeCleanup: function() {
		Element.remove(this.elements.box)
		Element.remove(this.elements.body)

		var allTemp = []
		for (i=0; i<Note.all.length; ++i) {
			if (Note.all[i].id != this.id) {
				allTemp.push(Note.all[i])
			}
		}

		Note.all = allTemp
		Note.updateNoteCount()
	},

	remove: function(e) {
		this.hideEditBox(e)
		this.bodyHide()

		if (this.is_new) {
			this.removeCleanup()
			notice("Note removed")

		} else {
			notice("Removing note...")

			new Ajax.Request('/note/update/' + this.id, {
				asynchronous: true,
				method: 'post',
				postBody: 'note[is_active]=0&note[post_id]=0'+Note.post_id,
				onComplete: function(req) {		
				
          var resp = eval("(" + req.responseText + ")")
		  			notice("Note Removed");
					if (req.status == 403) {
						notice("Access denied")
					} else if (req.status == 500) {
						notice("Error: " + resp.reason)
					} else {
						Note.find(parseInt(resp.old_id)).removeCleanup()
						notice("Note removed")
					}
				}
			})
		}

		Event.stop(e)
	},

	history: function(e) {
		this.hideEditBox(e)

		if (this.is_new) {
			notice("This note has no history")
		} else {
			location.pathname = '/note/history/' + this.id
		}
	}
}
