//////////////////////////// GDrawing codes begin //////////////////////////////////////////////////////////

var browser = new Browser();
function Browser() {
try{	
	var ua, s, i;
	this.isFirefox = false;
	this.version = null;
	ua = navigator.userAgent;
	s = "Firefox";
	if ((i = ua.indexOf(s)) >= 0)
	{
		this.isFirefox = true;
		this.version = parseFloat(ua.substr(i + s.length+1));
		return;
	}
}catch(e)
{alert("GDrawing Browser(): " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}
	
function GDrawing( id, parentId )
{
try{
	this.id = id;
	this.idx = GDrawing.maxIdx++;	// always increment the index
	this.parentId = parentId;
	if ( parentId == "undefined" )
		parentId = null;
	if ( parentId != null )
	{
		this.parentElement = document.getElementById( parentId );
		if ( this.parentElement == null )
		{
			alert( "Parent Id " + parentId + " is invalid" );
			return;
		}
	}
	this.embedElement = null;
	this.viewWin = null;
	
	this.width = 0;
	this.height = 0;
	this.dataStr = "";
	
	this.userSVG = null;
	this.operation = "";
	this.drawingWin = null;
	
	this.getId = function()
	{ return this.id; }

	this.getWidth = function()
	{ return this.width; }

	this.getHeight = function()
	{ return this.height; }
			
	this.getDataStr = function()
	{ return this.dataStr; }

	this.getEmbedElement = function()
	{ return this.embedElement; }

	this.getParentId = function()
	{ return this.parentId; }	
	
	this.getParentElement = function()
	{ return this.parentElement; }	

	this.askName = false;
	this.name = null;

	this.getName = function()
	{ return this.name; }	
}catch(e)
{alert("GDrawing constructor: " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}

GDrawing.GeoSVGDirectory = "./geosvg/";
GDrawing.SVGSupport = "Firefox";
GDrawing.nDrawings = 0;
GDrawing.drawings = new Array();
GDrawing.tmpDrawings = new Array();
GDrawing.nTmpDrawings = 0;
GDrawing.maxIdx = 0;

if ( browser.isFirefox && browser.version >= 1.5 )
	GDrawing.SVGSupport = "Firefox";
else
	GDrawing.SVGSupport = "ASV";


GDrawing.setGeoSVGDirectory = function( dir )
{ GDrawing.GeoSVGDirectory = dir; }

/*
GDrawing.setSVGSupport = function( SVGSupport )
{
	if ( SVGSupport != "Firefox" && SVGSupport != "ASV" )
	{
		alert( "In GDrawing.setSVGSupport(): unrecognized SVG support " + SVGsupport );
		return;
	}
	GDrawing.SVGSupport = SVGSupport;
}
*/
GDrawing.getNDrawings = function()
{ return GDrawing.nDrawings; }

GDrawing.getTmpDrawingById = function( id )
{
	var t1;
	for ( var i=0; i<GDrawing.nTmpDrawings; i++ )
	{
		t1 = GDrawing.tmpDrawings[i];
		if ( t1.id == id && t1.drawingWin != null && !t1.drawingWin.closed )
				return t1;
	}
	return null;
}

GDrawing.getDrawingById = function( id )
{
	for ( var i=0; i<GDrawing.nDrawings; i++ )
		if ( GDrawing.drawings[i].id == id )
			return GDrawing.drawings[i];
	return null;
}

GDrawing.getWidth = function( id )
{
	var tmp = GDrawing.getDrawingById( id );
	if ( tmp != null )
		return tmp.getWidth();
	else
		alert( "In GDrawing.getWidth(): Drawing with id \"" + id + "\" not found!" );
}

GDrawing.getHeight = function( id )
{
	var tmp = GDrawing.getDrawingById( id );
	if ( tmp != null )
		return tmp.getHeight();
	else
		alert( "In GDrawing.getHeight(): Drawing with id \"" + id + "\" not found!" );
}

GDrawing.getDataStr = function( id )
{
	var tmp = GDrawing.getDrawingById( id );
	if ( tmp != null )
		return tmp.getDataStr();
	else
		alert( "In GDrawing.getDataStr(): Drawing with id \"" + id + "\" not found!" );
}

GDrawing.getName = function( id )
{
	var tmp = GDrawing.getDrawingById( id );
	if ( tmp != null )
		return tmp.getName();
	else
		alert( "In GDrawing.getName(): Drawing with id \"" + id + "\" not found!" );
}

GDrawing.validOperation = function( drawing )
{
	if ( drawing.operation == "edit" && (drawing.drawingWin == null || drawing.drawingWin.closed ) )
		drawing.operation = ""
	if ( drawing.operation == "" )
		return true;
	return false;
}

GDrawing.newDrawing = function( id, parentId, askName )
{
try{
	var t1 = GDrawing.getDrawingById( id );
	if ( t1 != null )
	{
		alert( "In GDrawing.newDrawing(): Duplicate id \"" + id + "\"!" );
		return;
	}
	t1 = GDrawing.getTmpDrawingById( id );
	if ( t1 != null )
	{
		alert( "You have already opened a drawing window for drawing " + id + "!" );
		return;
	}
	
	// has memory leakage here
	t1 = new GDrawing( id, parentId );
	GDrawing.tmpDrawings[GDrawing.nTmpDrawings++] = t1;

	t1.operation = "new";
	
	if ( askName )
		t1.askName = askName;
	if ( GDrawing.SVGSupport == "Firefox" )
		t1.drawingWin = window.open( GDrawing.GeoSVGDirectory + "Mozilla/geosvg.xul", "geosvg", "modal, resizable, scrollbars, top=100, left=100, width=800, height=600" );
	else
		t1.drawingWin = window.open( GDrawing.GeoSVGDirectory + "ASV/geosvg.html", "geosvg", "modal, resizable, scrollbars, top=100, left=100, width=800, height=600" );
}catch(e)
{alert("GDrawing newDrawing(): " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}

GDrawing.setParentId = function( id, parentId )
{
try{
	var drawing = GDrawing.getDrawingById( id );
	if ( drawing == null )
	{
		alert( "In GDrawing.setParentId(): Drawing with id \"" + id + "\" not found!" );
		return;
	}
	if ( drawing.parentId != null )
	{
		alert( "In GDrawing.setParentId(): Drawing with id \"" + id + "\" already has a parent!" );
		return;
	}
	drawing.parentId = parentId;
	drawing.parentElement = document.getElementById( parentId );
	if ( drawing.parentElement == null )
	{
		alert( "In GDrawing.setParentId(): Drawing with id \"" + id + "\": Parent Id is invalid" );
		return;
	}
	var em = document.createElement( "embed" );
	drawing.embedElement = em;
	//em.setAttribute( "src", GDrawing.GeoSVGDirectory + ((GDrawing.SVGSupport == "Firefox")?"Mozilla/":"ASV/") + "view.svg" );
	em.setAttribute( "src", GDrawing.GeoSVGDirectory + "Mozilla/view.svg" );
	em.setAttribute( "id", drawing.id );
	em.setAttribute( "width", drawing.width );
	em.setAttribute( "height", drawing.height );
	drawing.parentElement.appendChild( em );
	em.style.overflow = "hidden";
}catch(e)
{alert("GDrawing setParentId: " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}

GDrawing.editDrawing = function( id )
{
try{
	var tmp = GDrawing.getDrawingById( id );
	if ( tmp == null )
	{
		alert( "In GDrawing.editDrawing(): Drawing with id \"" + id + "\" not found!" );
		return;
	}
	if ( !GDrawing.validOperation( tmp ) )
	{
		alert( "Drawing " + tmp.id + " currently cannot be edited!" );
		return;
	}

	tmp.operation = "edit";
	if ( GDrawing.SVGSupport == "Firefox" )
		tmp.drawingWin = window.open( GDrawing.GeoSVGDirectory + "Mozilla/geosvg.xul", "geosvg", "modal, resizable, top=100, left=100, width=800, height=600" );
	else
		tmp.drawingWin = window.open( GDrawing.GeoSVGDirectory + "ASV/geosvg.html", "geosvg", "modal, resizable, top=100, left=100, width=800, height=600" );
}catch(e)
{alert("GDrawing editDrawing(): " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}

GDrawing.displayDrawing = function( id, parentId, str, width, height, userSVG )
{
try{
	var tmp = GDrawing.getDrawingById( id );
	if ( tmp != null )
	{
		alert( "In GDrawing.displayDrawing(): Duplicate id \"" + id + "\"!" );
		return;
	}
	tmp = GDrawing.getTmpDrawingById( id );
	if ( tmp != null )
	{
		alert( "You have already opened a drawing window for drawing " + id + "!" );
		return;
	}
	var drawing = new GDrawing( id, parentId );
	drawing.operation = "display";
	GDrawing.drawings[GDrawing.nDrawings++] = drawing;

	if ( userSVG )
		drawing.userSVG = userSVG;
	else
	{
		drawing.dataStr = str;
		drawing.width = width;
		drawing.height = height;
	}
	if ( drawing.parentId != null )
	{
		em = document.createElement( "embed" );
		drawing.embedElement = em;

		if ( !userSVG )
			//em.setAttribute( "src", GDrawing.GeoSVGDirectory + ((GDrawing.SVGSupport == "Firefox")?"Mozilla/":"ASV/") + "view.svg" );
			em.setAttribute( "src", GDrawing.GeoSVGDirectory + "Mozilla/view.svg" );
		else
		{
			em.setAttribute( "src", userSVG );
			width = 1;
			height = 1;
		}
		em.setAttribute( "id", drawing.id );
		em.setAttribute( "width", width );
		em.setAttribute( "height", height );
		drawing.parentElement.appendChild( em );
		em.style.overflow = "hidden";
	}
	else
	{
		var op = drawing.operation;
		drawing.operation = "";
		if ( GDrawing.clientCallback != null )
			GDrawing.clientCallback( id, op );
	}	
}catch(e)
{alert("GDrawing displayDrawing(): " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}

GDrawing.replaceDrawing = function( id, str, width, height )
{
try{
	var tmp = GDrawing.getDrawingById( id );
	if ( tmp == null )
	{
		alert( "In GDrawing.replaceDrawing(): Drawing with id \"" + id + "\" not found!" );
		return;
	}
	if ( !GDrawing.validOperation( tmp ) )
	{
		alert( "Drawing " + tmp.id + " currently cannot be replaced!" );
		return;
	}	
	tmp.operation = "replace";
	if ( str == null || str == "undefined" )
		str = tmp.dataStr;
	if ( width == null || width == "" || width == "undefined" )
		width = tmp.width;
	if ( height ==  null || height == "" || height == "undefined" )	
		height = tmp.height;
		
	if ( tmp.parentId != null )
		tmp.viewWin.updDrawing( str, width, height );
	
	tmp.embedElement.setAttribute( "width", width );
	tmp.embedElement.setAttribute( "height", height );
	
	var op = tmp.operation;
	tmp.operation = "";
	if ( GDrawing.clientCallback != null )
		GDrawing.clientCallback( id, op );
	
}catch(e)
{alert("GDrawing replaceDrawing: " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}

GDrawing.removeDrawing = function( id )
{
try{
	var tmp = GDrawing.getDrawingById( id );
	if ( tmp == null )
	{
		alert( "In GDrawing.removeDrawing(): Drawing with id \"" + id + "\" not found!" );
		return;
	}
	if ( !GDrawing.validOperation( tmp ) )
	{
		alert( "Drawing " + tmp.id + " currently cannot be removed!" );
		return;
	}	
	tmp.operation = "remove";
	if ( tmp.parentId != null )
		tmp.parentElement.removeChild( tmp.embedElement );
	GDrawing.drawings[tmp.idx] = GDrawing.drawings[--GDrawing.nDrawings];
	var op = tmp.operation;
	tmp.operation = "";
	if ( GDrawing.clientCallback != null )
		GDrawing.clientCallback( id, op );
}catch(e)
{alert("GDrawing removeDrawing(): " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}	
	
GDrawing.onInitDrawingHandler = function( drawingWin )	// called by geosvg.svg for new or edit operation
{
try{
	var tmp;
	for ( var i=0; i<GDrawing.nDrawings; i++ )
		if ( GDrawing.drawings[i].drawingWin == drawingWin )
			break;
	if ( i < GDrawing.nDrawings )	// indicates edit
	{
		tmp = GDrawing.drawings[i];
		tmp.drawingWin.updDrawing( tmp.dataStr, tmp.width, tmp.height );
	}
}catch(e)
{alert("GDrawing onInitDrawingHandler(): " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}

GDrawing.onInitViewingHandler = function( viewWin, dataStr, width, height )	//called by view.svg for new or display operation
{
try{
	var tmp, embed;

	for ( var i=0; i<GDrawing.nDrawings; i++ )
	{
		embed = GDrawing.drawings[i].embedElement;
		if ( embed.getSVGDocument() == viewWin.document )
			break;
	}
	tmp = GDrawing.drawings[i];
	tmp.viewWin = viewWin;
	if ( tmp.operation == "new" )
	{
	}
	else
	{
		if ( tmp.userSVG )	// view.svg has dataStr/width/height set already when displayDrawing was called
		{
			tmp.dataStr = dataStr;
			tmp.width = width;
			tmp.height = height;
			tmp.embedElement.setAttribute( "width", tmp.width );
			tmp.embedElement.setAttribute( "height", tmp.height );
		}
	}
	
	viewWin.updDrawing( tmp.dataStr, tmp.width, tmp.height );
	
	if ( tmp.operation == "new" )
		tmp.drawingWin = null;
	var op = tmp.operation;
	tmp.operation = "";
	if ( GDrawing.clientCallback != null )
		GDrawing.clientCallback( tmp.id, op );
	
}catch(e)
{alert("GDrawing onInitViewingHandler(): " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}

GDrawing.onDrawingDoneHandler = function( drawingWin, str, width, height )	// for new or edit operation
{
try{
	var idx, drawing, operation;
	for ( idx=0; idx<GDrawing.nDrawings; idx++ )
		if ( GDrawing.drawings[idx].drawingWin == drawingWin )
			break;
	if ( idx == GDrawing.nDrawings )
	{
		for ( idx=0; idx<GDrawing.nTmpDrawings; idx++ )
			if ( GDrawing.tmpDrawings[idx].drawingWin == drawingWin )
				break;
		if ( idx == GDrawing.nTmpDrawings )
		{
			alert( "GDrawing.onDrawingDoneHandler program error1!" );
			return;
		}
		drawing = GDrawing.tmpDrawings[idx];
		operation = "new";		
	}
	else
	{
		drawing = GDrawing.drawings[idx];
		operation = "edit";
	}
	if ( drawing.operation != operation )
	{
		alert( "GDrawing.onDrawingDoneHandler program error2!" );
		return;
	}
		
	if ( operation == "new" )
	{
		if ( drawing.askName )
		{
			var name = "";
			while ( name == "" )
			{
				name = prompt( "\nPlease enter the name of the new manipulative", "" );
				if ( !name )
					return;
				// need a call back function to check if name is valid
			}
			drawing.name = name;
		}
		GDrawing.drawings[GDrawing.nDrawings++] = drawing;
		GDrawing.tmpDrawings[idx] = GDrawing.tmpDrawings[--GDrawing.nTmpDrawings];
	}

	drawing.dataStr = str;
	drawing.width = width;
	drawing.height = height;
	var em;
	if ( operation == "new" && drawing.parentId != null )
	{
		em = document.createElement( "embed" );
		drawing.embedElement = em;
		//em.setAttribute( "src", GDrawing.GeoSVGDirectory + ((GDrawing.SVGSupport == "Firefox")?"Mozilla/":"ASV/") + "view.svg" );
		em.setAttribute( "src", GDrawing.GeoSVGDirectory + "Mozilla/view.svg" );
		em.setAttribute( "id", drawing.id );
		em.setAttribute( "width", width );
		em.setAttribute( "height", height );
		drawing.parentElement.appendChild( em );
		em.style.overflow = "hidden";
	}
	else if ( operation == "edit" && drawing.parentId != null )
	{
try{
		drawing.viewWin.updDrawing( str, width, height );
}catch(e)
{alert(e.message + " " + e.lineNumber );}
		drawing.embedElement.setAttribute( "width", width );
		drawing.embedElement.setAttribute( "height", height );
	}

	var loop = true;
	while ( loop )
	{
		try{
			drawingWin.close();		//causes problem in IE
			drawingWin = null;
			break;
		}
		catch(e)
		{
		}
	}
		
/*
	if ( GDrawing.SVGSupport == "Firefox" )
	{
		drawingWin.close();		//causes problem in IE
		drawingWin = null;
	}
	else
	{
		setTimeout( "GDrawing.closeDrawingWin(" + drawing.idx + ");", 500 );
	}
*/
	if ( drawing.operation == "edit" || ( drawing.operation == "new" && drawing.parentId == null ) )
	{
		var op = drawing.operation;
		drawing.drawingWin = null;
		drawing.operation = "";
		if ( GDrawing.clientCallback != null )
			GDrawing.clientCallback( drawing.id, op );
	}
}catch(e)
{alert("GDrawing onDrawingDoneHandler(): " + e.message + " " + e.name + " " + e.lineNumber + " " + e.fileName + " " + e.stack );}
}

GDrawing.registerCallback = function( handler )
{
	GDrawing.clientCallback = handler; 
}

GDrawing.closeDrawingWin = function( idx )
{
	for ( var i=0; i<GDrawing.maxIdx; i++ )
		if ( GDrawing.drawings[i].idx == idx )
		{
			GDrawing.drawings[i].drawingWin.close();
			GDrawing.drawings[i].drawingWin = null;
			GDrawing.drawings[i].operation = "";
			return;
		}
}

GDrawing.randomString = function() 
{
	var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
	var strlen = 8;
	var t1, t2 = '';
	for ( var i=0; i<strlen; i++ ) 
	{
		t1 = Math.floor( Math.random() * chars.length );
		t2 += chars.substring( t1, t1+1 );
	}
	return t2;
}
GDrawing.code = GDrawing.randomString();

//////////////////////////// GDrawing codes end //////////////////////////////////////////////////////////
