var OCReader = Class.create();
OCReader.prototype =
{
	initialize : function ()
	{
		Element.setStyle('instr', { "display" : "block" });
		this.episode_div = $('episode');
		this.episode_div_inner = $('episode-inner');
		Element.setStyle(this.episode_div_inner,
			{
				"position" : "relative",
				"left" : "0px",
				"top" : "0px"
			});
		// set up instructions link
		this.instructions_div = $('instr');
		this.instructions_link = this.instructions_div.getElementsByTagName('a')[0];
		this.on = true;
		
		this.epi_dims = Element.getDimensions(this.episode_div_inner);
		this.orientation = this.episode_div.className;
		var off = Position.cumulativeOffset(this.episode_div_inner);
		this.epi_offset = { left : off[0], top : off[1] };
		// IE 5.5 chokes on cursor:pointer set via javascript, so...
		this.setPointerCursor(this.episode_div_inner);
		this.cur_pos = { x : 0, y : 0 };
		// create mousing surface
		this.window_surface = document.createElement('div');
		this.window_surface.setAttribute('id', 'js_comics_read_window_surface');
		Element.setStyle(this.window_surface,
			{
				"background-color" : "transparent",
				"background-image" : "url(/style/trans.gif)",
				"position" : "absolute",
				"left" : "0",
				"top" : "0",
				"width" : "100%",
				"height" : "100%",
				"display" : "none",
				"cursor" : "move",
				"z-index" : "1100"
			});
		this.window_surface.reader = this;
		document.body.appendChild(this.window_surface);
		this.startEpisodeDragCallback = this.startEpisodeDrag.bindAsEventListener(this);
		
		this.recalibrateScroll();
		
		Event.observe(window, 'resize', this.recalibrateScroll.bindAsEventListener(this));
		
		Event.observe(this.episode_div, "mousedown", this.startEpisodeDragCallback);
		Event.observe(this.instructions_link, "click", this.toggle.bind(this));
		if (!this.getPreferenceCookie())
		{
			this.toggle();
		}
	},
	
	recalibrateScroll : function ()
	{
		var dims = this.getViewPortDims();
		var w = dims[0]*0.66;
		var h = dims[1]*0.66;
		this.x_mult = Math.round(this.epi_dims.width/w);
		this.y_mult = Math.round(this.epi_dims.height/h);
	},

	getViewPortDims : function ()
	{
		// thanks quirksmode.org
		var x,y;
		if (self.innerHeight) // all except Explorer
		{
			x = self.innerWidth;
			y = self.innerHeight;
		}
		else if (document.documentElement && document.documentElement.clientHeight)
			// Explorer 6 Strict Mode
		{
			x = document.documentElement.clientWidth;
			y = document.documentElement.clientHeight;
		}
		else if (document.body) // other Explorers
		{
			x = document.body.clientWidth;
			y = document.body.clientHeight;
		}
		return [x, y];
	},
	
	setPointerCursor : function (elem)
	{
		try
		{
			Element.setStyle(elem, { "cursor" : "pointer" });
		}
		catch (e)
		{
			Element.setStyle(elem, { "cursor" : "hand" });
		}
	},
	
	toggle : function ()
	{
		if (this.on)
		{
			// turn off
			// change text of instructions
			this.instructions_link.innerHTML = '<span>Drag To Read</span> / Scroll To Read';
			Event.stopObserving(this.episode_div, "mousedown", this.startEpisodeDragCallback);
			Element.setStyle(this.episode_div_inner,
				{
					"cursor" : "default"
				});
			/*
			Element.setStyle(this.episode_div,
				{
					"margin-left" : "0px",
					"margin-top" : "0px"
				});
			*/
			Element.setStyle(this.episode_div_inner,
				{
					"left" : "0px",
					"top" : "0px"
				});
			this.cur_pos = { x : 0, y : 0 };
			Element.setStyle(document.body,
				{
					"overflow" : ""
				});
			// scrollbars won't appear on Safari without:
			window.scrollTo(1,1);
			this.on = false;
		}
		else
		{
			// turn on
			// change text of instructions
			this.instructions_link.innerHTML = 'Drag to Read / <span>Scroll To Read</span>';
			Event.observe(this.episode_div, "mousedown", this.startEpisodeDragCallback);
			this.setPointerCursor(this.episode_div_inner);
			Element.setStyle(document.body,
				{
					"overflow" : "hidden"
				});
			this.on = true;
		}
		this.setPreferenceCookie();
	},
	
	getPreferenceCookie : function ()
	{
		var cookies = document.cookie;
		var pos = cookies.indexOf("js_comics_read_pref=");
		if (pos != -1)
		{
			var end = cookies.indexOf(";", pos);
			if (end == -1)
			{
				end = cookies.length;
			}
			var value = cookies.substring(pos+20, end);
			value = parseInt(value);
			if (isNaN(value))
			{
				value = 0;
			}
			if (value == 1)
			{
				return true;
			}
			return false;
		}
		// default is true
		return true;
	},
	
	setPreferenceCookie : function () 
	{
		var nextyear = new Date(  );
		nextyear.setFullYear(nextyear.getFullYear()+1);
		if (this.on)
		{
			document.cookie = "js_comics_read_pref=1; expires="+nextyear.toGMTString();
		}
		else
		{
			document.cookie = "js_comics_read_pref=0; expires="+nextyear.toGMTString();
		}
	},
	
	startSurfaceDrag : function (onmove, onup, onout)
	{
		if (!onout)
		{
			onout = onup;
		}
		// THANK YOU: http://www.ditchnet.org/wp/2005/06/15/ajax-freakshow-drag-n-drop-events-2/
		document.body.old_ondrag = document.body.ondrag;
		document.body.ondrag = function () { return false; }
		document.body.old_onselectstart = document.body.onselectstart;
		document.body.onselectstart = function () { return false; }
		
		Element.setStyle(this.window_surface, { "display" : "block" });
        Event.observe(this.window_surface, "mouseup", onup);
        Event.observe(this.window_surface, "mouseout", onout);
        Event.observe(this.window_surface, "mousemove", onmove);
        this.window_surface.drag_events = { onmove : onmove, onup : onup, onout : onout };
    },
    
    stopSurfaceDrag : function ()
    {
    	if (!this.window_surface.drag_events)
    	{
    		return;
    	}
    	var de = this.window_surface.drag_events;
    	Event.stopObserving(this.window_surface, "mouseup", de.onup);
    	Event.stopObserving(this.window_surface, "mouseout", de.onout);
    	Event.stopObserving(this.window_surface, "mousemove", de.onmove);
    	Element.setStyle(this.window_surface, { "display" : "none" });
    	this.window_surface.drag_events = null;
    	
    	// THANK YOU: http://www.ditchnet.org/wp/2005/06/15/ajax-freakshow-drag-n-drop-events-2/
		document.body.ondrag = document.body.old_ondrag;
    	document.body.onselectstart = document.body.old_onselectstart;
    },
	
	startEpisodeDrag : function (e)
	{
		if (this.dragging)
		{
			return;
		}
		var elem = Event.element(e);
		if (elem.tagName.toLowerCase() == 'a')
		{
			return;
		}
		this.dragging = 1;
		this.dragging_last_position = { x : Event.pointerX(e), y : Event.pointerY(e) };
		if (!this.episodeDragCallback)
		{
			this.episodeDragCallback = this.episodeDrag.bindAsEventListener(this);
			this.stopEpisodeDragCallback = this.stopEpisodeDrag.bindAsEventListener(this);
		}
		this.startSurfaceDrag(this.episodeDragCallback, this.stopEpisodeDragCallback);
		Event.stop(e);
	},
	
	episodeDrag : function (e)
	{
		if (!this.dragging)
		{
			Event.stop(e);
			return;
		}
		var cur = { x : Event.pointerX(e), y : Event.pointerY(e) };
		this.moveEpisodeBy(
			(this.dragging_last_position.x - cur.x)*this.x_mult,
			(this.dragging_last_position.y - cur.y)*this.y_mult
		);
		this.dragging_last_position = cur;
		Event.stop(e);
	},
	
	stopEpisodeDrag : function (e)
	{
		this.dragging = 0;
		this.stopSurfaceDrag();
		Event.stop(e);
	},
	
	moveEpisodeBy : function (dx, dy)
	{
		var new_pos = { x : (this.cur_pos.x - dx), y : (this.cur_pos.y - dy) };
		if (new_pos.x > 0)
		{
			new_pos.x = 0;
		}
		if (new_pos.y > 0)
		{
			new_pos.y = 0;
		}
		if (self.innerHeight) // all except Explorer
		{
			x = self.innerWidth;
			y = self.innerHeight;
		}
		else if (document.documentElement && document.documentElement.clientHeight)
			// Explorer 6 Strict Mode
		{
			x = document.documentElement.clientWidth;
			y = document.documentElement.clientHeight;
		}
		else if (document.body) // other Explorers
		{
			x = document.body.clientWidth;
			y = document.body.clientHeight;
		}
		var body_dims = { width : x, height : y };
		if (this.orientation != 'vertical' && this.epi_dims.width + this.epi_offset.left > body_dims.width)
		{
			if (-1*new_pos.x + body_dims.width > this.epi_dims.width)
			{
				new_pos.x = body_dims.width - this.epi_dims.width;
			}
		}
		else
		{
			if (new_pos.x != 0)
			{
				new_pos.x = 0;
			}
		}
		// took out this.orientation != 'horizontal' condition to allow horizontal
		// episodes to move up and down for people on small-ish monitors
		if (this.epi_dims.height + this.epi_offset.top > body_dims.height)
		{
			if (-1*new_pos.y + body_dims.height - this.epi_offset.top > this.epi_dims.height)
			{
				new_pos.y = body_dims.height - this.epi_dims.height - this.epi_offset.top;
			}
		}
		else
		{
			if (new_pos.y != 0)
			{
				new_pos.y = 0;
			}
		}
		/*
		Element.setStyle(this.episode_div,
			{
				"margin-left" : (new_pos.x)+"px",
				"margin-top" : (new_pos.y)+"px"
			}
		);
		*/
		Element.setStyle(this.episode_div_inner,
			{
				"left" : (new_pos.x)+"px",
				"top" : (new_pos.y)+"px"
			});
		this.cur_pos = new_pos;
	}
};