var ppImage;
var pen;
var drawing;
var hoverDrawMode;
var mousex;
var mousey;
var hover;
var hoverShadow;
var brushSize;

function bonk( message )
{
	alert( message );
}

function ppOnload()
{
//	bonk( "onload" );
	// try to find article data somewhere
	var ppOriginalArticle = document.getElementById( "ppOriginalArticle" );
	if( ppOriginalArticle )
	{
		// editor setup
		ppImage = new PPImage();
		ppImage.initFromString( ppOriginalArticle.value );
		ppImage.showInEditor();
//		bonk( "shownineditor" );
	
		// init editor stuff
		setPen( '1' );
		drawing = false;
		hoverDrawMode = false;
		document.onmouseup = "mouseUp()";
		brushSize = 0;
	}
	
	// look for hover tooltip elements
	hover = document.getElementById( "ppHover" );
	hoverShadow = document.getElementById( "ppHoverShadow" );
}

function ppGo( target, known )
{
	var action = "";
	if( known == "false" )
	{
		action = "&action=edit";
	}
	window.location = "/index.php?title=" + target + action;
}

function mouseMove( event )
{
	var newMouseX = getMouseX( event );
	var newMouseY = getMouseY( event );

	// check for change
	if( mousex != newMouseX || mousey != newMouseY )
	{
		// record
		mousex = newMouseX;
		mousey = newMouseY;

		// respond
		
		// move hover tooltip
		if( hover && hoverShadow )
		{
			// set position
			var x = mousex - hover.clientWidth / 2;
			var y = mousey - hover.clientHeight - 16;
			hover.style.left = x + "px";
			hover.style.top = y + "px";
			hoverShadow.style.left = ( x + 1 ) + "px";
			hoverShadow.style.top = ( y + 1 ) + "px";
		}
	}
}

function ppHover( text, known )
{
	if( hover && hoverShadow )
	{
		// modify text for unknown pages
		if( known == "false" )
		{
			text = text + "<br/>(Draw new page)</br>";
		}

		// set text
		hover.innerHTML = text;
		hoverShadow.innerHTML = text;
	
		// set visible
		hover.style.visibility = "visible";
		hoverShadow.style.visibility = "visible";
	}
}

function ppUnhover()
{
	if( hover && hoverShadow )
	{
		// set visible
		hover.style.visibility = "hidden";
		hoverShadow.style.visibility = "hidden";
	}
}

function ppSave( target )
{
	// grab edit summary
	var summary = document.getElementById( "ppSummary" ).value;
	
	// make sure ppImage is up to date
	ppImage.refreshHoverData();
	
	// grab image data
	var image = ppImage.getArticleText();
	
	// submit
	postwith( target, { ppAction:"save", ppSummary:summary, ppImage:image } );
}

// seems to work nicely, found here:
// http://mentaljetsam.wordpress.com/2008/06/02/using-javascript-to-post-data-between-pages/
// Usage: <a href="javascript:postwith('post.aspx',{user:'peter',cc:'aus'})">click</a>
function postwith( to, p )
{
	var myForm = document.createElement( "form" );
	myForm.method="post";
	myForm.action = to;
	myForm.enctype = "multipart/form-data";
	for( var k in p )
	{
		var myInput = document.createElement( "textarea" );
		myInput.setAttribute( "name", k ) ;
		myInput.value = p[k];
		myForm.appendChild( myInput ) ;
	}
	document.body.appendChild( myForm ) ;
	myForm.submit() ;
	document.body.removeChild( myForm ) ;
}

function setPen( p )
{
	pen = p;
	setHoverDrawMode( false );
}

function setBrushSize( b )
{
	brushSize = b;
}

function setHover( p )
{
	pen = p;
	setHoverDrawMode( true );
}

function setHoverDrawMode( newMode )
{
	hoverDrawMode = newMode;
	ppImage.showHover( newMode );
}

function mouseDownOnPixel( x, y )
{
	drawing = true;
	ppImage.draw( x, y );
	return false;
}

function mouseEnterPixel( x, y )
{
	if( drawing )
	{
		ppImage.draw( x, y );
	}
}

function mouseUp()
{
	drawing = false;
}
	
// mouse position browser fix cludges found here: http://javascript.about.com/library/blmousepos.htm
function getMouseX(evt) {
	if (evt.pageX) return evt.pageX;
	else if (evt.clientX)
		return evt.clientX + (document.documentElement.scrollLeft ?
			document.documentElement.scrollLeft :
			document.body.scrollLeft);
	else return null;
}
function getMouseY(evt) {
	if (evt.pageY) return evt.pageY;
	else if (evt.clientY)
		return evt.clientY + (document.documentElement.scrollTop ?
			document.documentElement.scrollTop :
			document.body.scrollTop);
	else return null;
}

// eew - javascript uses functions as classes somehow. Nasty.
function PPImage()
{
	// member vars
	this.pixels = new Array( 48 );
	this.hoverPixels = new Array( 48 );
	this.hoverPages = new Array( 16 );
	this.hoverVerbs = new Array( 16 );
	
	// extra var init
	var pixValues = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" ]
	var blankPixel = pixValues[ Math.floor( Math.random() * pixValues.length ) ] 
	for( var x = 0; x < 48; ++x )
	{
		this.pixels[x] = new Array( 32 );
		this.hoverPixels[x] = new Array( 32 );
		for( var y = 0; y < 32; ++y )
		{
			this.pixels[x][y] = blankPixel;
			this.hoverPixels[x][y] = ".";
		}
	}
	for( var i = 0; i < 16; ++i )
	{
		this.hoverPages[i] = "";
		this.hoverVerbs[i] = "";
	}
	this.hoverPages[0] = "Destination page";
	this.hoverVerbs[0] = "Description for player";
	
	// declare member functions
	this.initFromString = initFromString;
	this.getArticleText = getArticleText;
	this.refreshHoverData = refreshHoverData;
	this.showInEditor = showInEditor;
	this.draw = draw;
	this.drawInternal = drawInternal;
	this.showHover = showHover;
	
	// implement member functions
	
	function initFromString( inputString )
	{
		// extract first tag data
		// bail early if tag is missing or data is borked
		var data = inputString.split( "<ppimage>" );
		if( data.length <= 1 )
			return;
		data = data[1].split( "</ppimage>" );
		
		// split into rows
		data = data[0].split( String.fromCharCode( 10 ) );
		
		// read pixel rows
		for( var x = 0; x < 48; ++x )
		{
			for( var y = 0; y < 32; ++y )
			{
				this.pixels[x][y] = data[y+1].charAt( x );
			}
		}
		
		// hover data is in next version - just check length to see if it's here
		if( data.length > 34 )
		{
			// read hover pixel rows
			for( var x = 0; x < 48; ++x )
			{
				for( var y = 0; y < 32; ++y )
				{
					this.hoverPixels[x][y] = data[y+1+32].charAt( x );
				}
			}
			
			// read other hover data
			for( var i = 0; i < 16; ++i )
			{
				this.hoverPages[i] = data[i*2+1+64];
				this.hoverVerbs[i] = data[i*2+1+64+1];
			}
		}
	}
	
	function showInEditor()
	{
		var element;
	
		// read pixel rows
		for( var x = 0; x < 48; ++x )
		{
			for( var y = 0; y < 32; ++y )
			{
				element = document.getElementById( "pp" + x + "x" + y + "y" );
				var className = "pp" + this.pixels[x][y];
				element.setAttribute( "class", className );		// browsers that don't suck
				element.setAttribute( "className", className );	// IE 6
				// test number drawing for layer stuff
//				element.innerHTML = this.pixels[x][y];

				// disable selection in Firefox
				element.style.MozUserSelect= "none";
			}
		}
		
		// fill fields
		for( var i = 0; i < 16; ++i )
		{
			document.getElementById( "pphpage" + i ).value = this.hoverPages[i];
			document.getElementById( "pphverb" + i ).value = this.hoverVerbs[i];
		}
	}
	
	function showHover( show )
	{
		// read pixel rows
		for( var x = 0; x < 48; ++x )
		{
			for( var y = 0; y < 32; ++y )
			{
				var element = document.getElementById( "pp" + x + "x" + y + "y" );
				if( show )
				{
					element.innerHTML = this.hoverPixels[x][y];
				}
				else
				{
					element.innerHTML = "";
				}
			}
		}
	}		
	
	function getArticleText()
	{
		var terminator = String.fromCharCode( 10 );
		
		// header
		var output = "<ppimage>" + terminator;
		
		// pixels
		for( var y = 0; y < 32; ++y )
		{
			for( var x = 0; x < 48; ++x )
			{
				output += this.pixels[x][y];
			}
			output += terminator;
		}
		
		// hover pixels
		for( var y = 0; y < 32; ++y )
		{
			for( var x = 0; x < 48; ++x )
			{
				output += this.hoverPixels[x][y];
			}
			output += terminator;
		}
		
		// hover metadata
		for( var i = 0; i < 16; ++i )
		{
			output += this.hoverPages[i] + terminator;
			output += this.hoverVerbs[i] + terminator;
		}
		
		// footer
		output += "</ppimage>";
		
		// done
		return output;
	}
	
	function refreshHoverData()
	{
		// from fields
		for( var i = 0; i < 16; ++i )
		{
			this.hoverPages[i] = document.getElementById( "pphpage" + i ).value;
			this.hoverVerbs[i] = document.getElementById( "pphverb" + i ).value;
		}
	}
	
	function draw( x, y )
	{
		// apply brush size
		if( brushSize == 0 )
		{
			// small
			this.drawInternal( x, y );
		}
		else if( brushSize == 1 )
		{
			// big
			this.drawInternal( x, y-1 );
			this.drawInternal( x-1, y );
			this.drawInternal( x, y );
			this.drawInternal( x+1, y );
			this.drawInternal( x, y+1 );
		}
		else
		{
			// huge
			this.drawInternal( x, y-2 );
			this.drawInternal( x-1, y-1 );
			this.drawInternal( x, y-1 );
			this.drawInternal( x+1, y-1 );
			this.drawInternal( x-2, y );
			this.drawInternal( x-1, y );
			this.drawInternal( x, y );
			this.drawInternal( x+1, y );
			this.drawInternal( x+2, y );
			this.drawInternal( x-1, y+1 );
			this.drawInternal( x, y+1 );
			this.drawInternal( x+1, y+1 );
			this.drawInternal( x, y+2 );
		}
	}
	
	function drawInternal( x, y )
	{
		if( x >= 0 && y >= 0 && x < 48 && y < 32 )
		{
			if( hoverDrawMode )
			{
				// store data
				this.hoverPixels[x][y] = pen;
			
				// display
				var element = document.getElementById( "pp" + x + "x" + y + "y" );
				element.innerHTML = pen;
			}
			else
			{
				// store data
				this.pixels[x][y] = pen;
			
				// display
				var element = document.getElementById( "pp" + x + "x" + y + "y" );
				var className = "pp" + pen;
				element.setAttribute( "class", className );		// browsers that don't suck
				element.setAttribute( "className", className );	// IE 6
			}
		}
	}
};
