/**********************************************************************************
*
* Project Name:		jsDraw2D (Graphics Library for JavaScript)
* Version:		Beta 1.1.0 (17-August-2009) (Uncompressed)
* Project Homepage:	http://jsdraw2d.jsfiction.com
* Author:			Sameer Burle
* Copyright 2009:		jsFiction.com (http://www.jsfiction.com)
* Licensed Under:		LGPL
*
* This program (library) is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
************************************************************************************/

//jsColor class holds the color information and provides some color related basic functions.
function jsColor()
{
	//Member variables
	var hex="#000000";
	
	switch(arguments.length)
	{
		//Hexadecimal Color
		case 1:
            setHex(arguments[0]);			
			break;
		//RGB Color
		case 3:
			var red=arguments[0];
			var green=arguments[1];
			var blue=arguments[2];
			hex=rgbToHex(red,green,blue);
			if(hex==false)
				hex="#000000";
			break;
	}
	
	//Public Methods
	
	//Set color by specifying the hexa-decimal value. 
	this.setHex=setHex;
	function setHex(hexColor)
	{
	    if(hexColor.charAt(0)=="#")
		{
			hex=hexColor;
		}
		else
		{
            if(isNaN(hexColor))
            {
                setNamedColor(hexColor.toLowerCase());
            }
            else
            {			
				hex="#" + hexColor;
		    }    
		}
			
		var rgbArray=hexToRgb(hex);
		if(!rgbArray)
		{
		    hex="#000000"
		}
	}
	//Get the hexa-decimal value of the object
	this.getHex=getHex;
	function getHex()
	{
	    return hex;
	}
	
	//Set color by specifying the RGB values.
	this.setRGB=setRGB;
	function setRGB(redValue,greenValue,blueValue)
	{
		hex=rgbToHex(redValue,greenValue,blueValue);
		if(hex==false)
			hex="#000000";
	}
	
	//Get the RGB values of the object
	this.getRGB=getRGB;
	function getRGB()
	{
	    return hexToRgb(hex);
	}
	
	//Returns new jsColor object with darker color shade 
	this.getDarkerShade=getDarkerShade;
	function getDarkerShade(value)
	{
		var redValue,greenValue,blueValue;
		var resArray=getRGB();
		
		if(!isNaN(value))
		{
			redValue=parseInt(resArray[0]-value);
			greenValue=parseInt(resArray[1]-value);
			blueValue=parseInt(resArray[2]-value);
		}
		
		if(redValue<0)
			redValue=0;
		if(greenValue<0)
			greenValue=0;
		if(blueValue<0)
			blueValue=0;
			
		return new jsColor(redValue,greenValue,blueValue);	
	}

	//Returns new jsColor object with lighter color shade 
	this.getLighterShade=getLighterShade;	
	function getLighterShade(value)
	{
		var redValue,greenValue,blueValue;
		var resArray=getRGB();
		
		if(!isNaN(value))
		{
			redValue=parseInt(resArray[0]+value);
			greenValue=parseInt(resArray[1]+value);
			blueValue=parseInt(resArray[2]+value);
		}
		
		if(redValue>255)
			redValue=255;
		if(greenValue>255)
			greenValue=255;
		if(blueValue>255)
			blueValue=255;
		
		return new jsColor(redValue,greenValue,blueValue);	
	}

	//Static-Shared Utility Methods
	
	//Convert RGB color to Hex color
	this.rgbToHex=rgbToHex;
	function rgbToHex(redValue, greenValue, blueValue)
	{
		//Check argument values
		if(redValue<0 || redValue>255 || greenValue<0 || greenValue>255 || blueValue<0 || blueValue>255)
		{
			return false;
		}
		                        		
   		var colorDec = Math.round(blueValue) + 256 * Math.round(greenValue) + 65536 * Math.round(redValue);
   		return "#" + zeroPad(colorDec.toString(16),6);
	}
	
	//Convert Hex color to RGB color
	this.hexToRgb=hexToRgb;
	function hexToRgb(hexValue)
	{
		var redValue,greenValue,blueValue;
		if(hexValue.charAt(0)=="#")
		{
			hexValue=hexValue.substring(1,7);
		}
		
		redValue=parseInt(hexValue.substring(0,2),16);
		greenValue=parseInt(hexValue.substring(2,4),16);
		blueValue=parseInt(hexValue.substring(4,6),16);
		
		//Check argument values
		if(redValue<0 || redValue>255 || greenValue<0 || greenValue>255 || blueValue<0 || blueValue>255)
		{
			return false;
		}

		return new Array(redValue,greenValue,blueValue);
	}

	//Private Methods
	//Set the color using specified name of the color out of 16 web colors.
	function setNamedColor(colorName)
	{
	    switch(colorName)
        {   
            case "aqua":
                hex="#00FFFF";
                break;
            case "black":
                hex="#000000";
                break;
            case "blue":
                hex="#0000FF";
                break;
            case "fuchsia":
                hex="#FF00FF";
                break;
            case "green":
                hex="#008000";
                break;
            case "gray":
                hex="#808080";
                break;
            case "lime":
                hex="#00FF00";
                break;
            case "maroon":
                hex="#800000";
                break;
            case "navy":
                hex="#000080";
                break;
            case "olive":
                hex="#808000";
                break;
            case "purple":
                hex="#800080";
                break;
            case "red":
                hex="#FF0000";
                break;
            case "silver":
                hex="#C0C0C0";
                break;
            case "teal":
                hex="#008080";
                break;
            case "white":
                hex="#FFFFFF";
                break;
            case "yellow":
                hex="#FFFF00";
                break;
        }
	}
	
	//Add zero padding to the left. Used for building hexa-decimal string.	
	function zeroPad(val,count)
	{ 
		var valZeropad = val + "";
		while(valZeropad.length < count) 
		{
			valZeropad = "0" + valZeropad; 
		}
		return valZeropad;
	}

}

//jsFont class holds the font information which can be used by other objects in object oriented way.
function jsFont(family,weight,size,style,variant)
{
    //Properties: family, weight, size, style and varient with default value null
    this.family=null;
    this.weight=null;
    this.size=null;
    this.style=null;
    this.variant=null;
    
    if(family && family!="")
        this.family=family;
    
    if(weight && weight!="")
        this.weight=weight;

    if(size && size!="")
        this.size=size;
        
    if(style && style!="")
        this.style=style;
    
    if(variant && variant!="")
        this.variant=variant;
}

//jsPen class holds the drawing pen/stroke information. Mainly it holds the color and width values to be used for 2D drawing. 
//All draw methods take jsPen object as a parameter. Acts like a pen for drawing.
function jsPen(color,width)
{
	this.color=new jsColor();	//color proprty of jsColor type
	this.width="1px";			//width property with 1px default value
	
	if(arguments.length>0)
	{
		this.color=color;	
	}
	if(arguments.length>=2)
	{
		this.width=width;
	}
	if(!isNaN(width))
	{
		this.width=width+"px";
	}
}

//jsPoint class holds the 2D drawing point information. It holds values of x and y coordinates of the point.
function jsPoint(x,y)
{
	this.x=0;
	this.y=0;

	if(arguments.length==2)
	{
		this.x=x;
		this.y=y;
	}
}

function jsGraphics(canvasDivElement)
{
	//Private member variables
	var origin=new jsPoint(0,0);
	var scale=1;
	var coordinateSystem="default";	//Possible values "default" or "cartecian"
	var canvasDiv;
	
	if(canvasDivElement)
		canvasDiv=canvasDivElement;
	else
		canvasDiv=document.body;	//Document will be used directly for drawing
	
	var gridDiv=null;
	
	//Public Methods
	this.drawLine=drawLine;
	this.drawRectangle=drawRectangle;
	this.fillRectangle=fillRectangle;
	this.drawCircle=drawCircle;
	this.drawEllipse=drawEllipse;
	this.fillCircle=fillCircle;
	this.fillEllipse=fillEllipse;
	this.fillArc=fillArc;
	this.drawArc=drawArc;
	this.drawPolyline=drawPolyline;
	this.drawPolygon=drawPolygon;
	this.fillPolygon=fillPolygon;
	this.drawBezier=drawBezier;
	this.drawPolyBezier=drawPolyBezier;
	this.drawCurve=drawCurve;
	this.drawClosedCurve=drawClosedCurve;
	this.fillClosedCurve=fillClosedCurve;
	this.drawText=drawText;
	this.drawImage=drawImage;
	this.clear=clear;
	this.showGrid=showGrid;
	this.hideGrid=hideGrid;
	this.setOrigin=setOrigin;
	this.getOrigin=getOrigin;
	this.setScale=setScale;
	this.getScale=getScale;
	this.setCoordinateSystem=setCoordinateSystem;
	this.getCoordinateSystem=getCoordinateSystem;
	this.logicalToPhysicalPoint=logicalToPhysicalPoint;
	
	//Initialization
	
	//Grid initialization
	gridDiv=document.createElement("div");
	gridDiv.style.left="0px";
	gridDiv.style.top="0px";
	if(canvasDiv.clientWidth>0 && canvasDiv.clientHeight>0)
	{
	    gridDiv.style.width=(parseInt(canvasDiv.clientWidth)-1) + "px";
	    gridDiv.style.height=(parseInt(canvasDiv.clientHeight)-1) + "px";
	}
	else
	{
	    gridDiv.style.width="0px";
	    gridDiv.style.height="0px";
	}    
	gridDiv.style.zIndex=0;
	gridDiv.style.position="absolute";
	gridDiv.style.display="none";
	canvasDiv.appendChild(gridDiv);

	//Origin
	function setOrigin(point)
	{
		origin=point;	
	}
	
	function getOrigin()
	{
		return origin;
	}

	//Scale
	function setScale(value)
	{
		scale=value;	
	}
	
	function getScale()
	{
		return scale;
	}
	
	//Coordinate System
	function setCoordinateSystem(name)
	{
		name=name.toLowerCase()
		if(name.toLowerCase() != "default" && name.toLowerCase() != "cartecian")
		{
			coordinateSystem="default";
		}
		else
		{
			coordinateSystem=name;
		}
	}
	
	function getCoordinateSystem()
	{
		return coordinateSystem=name;
	}
	
	//Conversion of logical point to physical point based on coordinate system, origin and scale.
	function logicalToPhysicalPoint(point)
	{
		if(coordinateSystem=="cartecian")
		{
			return new jsPoint(point.x*scale+origin.x,origin.y-point.y*scale)
		}
		else
		{
			return new jsPoint(point.x*scale+origin.x,point.y*scale+origin.y)
		}
	}
	
	//Display background grid
	function showGrid(range,showRange,color)
	{
		if(showRange==null)	
			showRange=true;	//range is grid interval. The values will be shown if showRange is true.
			
		var x0,x1,y0,y1;
		var isLeft=false; //range display on left side of y-axis if true otherwise right side.
		var isUp=false;	//range display above the x-axis if true otherwise below.
		gridDiv.innerHTML="";

		if(!color)
			color=new jsColor(200,200,200);
			
		if(!range)
			range=Math.round(parseInt(gridDiv.style.width)/10);	//If range not specified, use grid with devided by 10 as range.
		else	
			range=range*scale;
			
		var hexColor=color.getHex();
		
		//If grid height or width is not available, the grid will not be displayed.
		if(parseInt(gridDiv.style.width)<=0 || parseInt(gridDiv.style.height)<=0)
		    return;
		else
		    gridDiv.style.display="";
		    
		x0=parseInt(gridDiv.style.left)
		x1=parseInt(gridDiv.style.left)+parseInt(gridDiv.style.width);
		y0=parseInt(gridDiv.style.top);
		y1=parseInt(gridDiv.style.top)+parseInt(gridDiv.style.height);

		//On which side of the axis the range to be displayed is decided based on position of the origin in the canvas.
		//Range is displyed on opposite side of the largest section(out of 4 section divided by the 2 axis)  
		if(origin.x-parseInt(gridDiv.style.left)<=parseInt(gridDiv.style.left)+gridDiv.offsetWidth-origin.x)
			isLeft=true
			
		if(origin.y-parseInt(gridDiv.style.top)<=parseInt(gridDiv.style.top)+gridDiv.offsetHeight-origin.y)
			isUp=true
			
		var iHtml=new Array();	//Holds inner html
		var rangeFont=new jsFont("arial",null,"9px");
		var rangeColor=color.getDarkerShade(150);
		var hexRangeColor=rangeColor.getHex(); 

		//Draw the border grids
 		iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;z-index:-100;left:" + x0 + "px;top:" + y0 + "px;width:" + (x1-x0+1) + "px;height:1px;background-color:" + hexColor + "\"></DIV>";
 		iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;z-index:-100;left:" + x0 + "px;top:" + y1 + "px;width:" + (x1-x0+1) + "px;height:1px;background-color:" + hexColor + "\"></DIV>";
 		iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;z-index:-100;left:" + x0 + "px;top:" + y0 + "px;width:1px;height:" + (y1-y0+1) + "px;background-color:" + hexColor + "\"></DIV>";
 		iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;z-index:-100;left:" + x1 + "px;top:" + y0 + "px;width:1px;height:" + (y1-y0+1) + "px;background-color:" + hexColor + "\"></DIV>";

		var gridHeight=gridDiv.offsetHeight;
		var gridWidth=gridDiv.offsetWidth;
		var lastRangeDiv; //previous range div
		var currentRangeDiv //current range div
	
		//Draw vertical grid lines
		for(var x=(origin.x-x0)%range;x<x1;x+=range)
		{
			if(x==origin.x && x>=x0)
			{
				if(x>=x0 && x<=x1)
		 			iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;z-index:-99;left:" + x + "px;top:" + y0 + "px;width:1px;height:" + gridHeight + "px;background-color:" + hexRangeColor + "\"></DIV>";
	 		}	
			else
			{
	 			iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;z-index:-100;left:" + x + "px;top:" + y0 + "px;width:1px;height:" + gridHeight + "px;background-color:" + hexColor + "\"></DIV>";
	 		}	
	 			
			if(showRange && x>=x0 && x<x1)
			{	 		
	 			if(lastRangeDiv && lastRangeDiv.offsetLeft + lastRangeDiv.offsetWidth + 1 < x)
	 			{
	 				if(lastRangeDiv.offsetWidth < x1-x)
	 					currentRangeDiv = drawRange(Math.round((x-origin.x)/scale),new jsPoint(x+2,y0+1+origin.y),rangeFont,rangeColor);
	 			}	
	 			else if(!lastRangeDiv)
	 				currentRangeDiv = drawRange(Math.round((x-origin.x)/scale),new jsPoint(x+2,y0+1+origin.y),rangeFont,rangeColor);
	 			
				if(currentRangeDiv)
				{
	 				if(!isUp)
					{
						if(parseInt(currentRangeDiv.style.top)+currentRangeDiv.offsetHeight > y1)
		 					currentRangeDiv.style.top=y1-currentRangeDiv.offsetHeight-1;
					}
					else
					{
						if(parseInt(currentRangeDiv.style.top)-currentRangeDiv.offsetHeight-1>y0)
		 					currentRangeDiv.style.top=parseInt(currentRangeDiv.style.top)-currentRangeDiv.offsetHeight-1;
		 				
						if(parseInt(currentRangeDiv.style.top)<=y0)
							currentRangeDiv.style.top=y0 + 1;
					}	
				
					currentRangeDiv.style.visibility="visible";
					lastRangeDiv = currentRangeDiv;
				}
				currentRangeDiv=null;	

	 		}		
		}
		lastRangeDiv = null;

		//Draw horizontal grid lines
		for(var y=(origin.y-y0)%range;y<=y1;y+=range)
		{
			if(y==origin.y)
			{
				if(y>=y0 && y<=y1)
					iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;z-index:-99;left:" + x0 + "px;top:" + y + "px;width:" + gridWidth + "px;height:1px;background-color:" + hexRangeColor + "\"></DIV>";
			}	
			else
		 		iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;z-index:-100;left:" + x0 + "px;top:" + y + "px;width:" + gridWidth + "px;height:1px;background-color:" + hexColor + "\"></DIV>";
	 		
			if(showRange && y!=origin.y && y>=y0 && y<y1)
			{	 		
	 			if(lastRangeDiv && lastRangeDiv.offsetTop + lastRangeDiv.offsetHeight < y)
	 			{
	 				if(lastRangeDiv.offsetHeight <= y1-y)
	 				{
	 					if(coordinateSystem=="cartecian")
		 					currentRangeDiv = drawRange(Math.round((origin.y-y)/scale),new jsPoint(x0+2+origin.x,y),rangeFont,rangeColor);
		 				else
		 					currentRangeDiv = drawRange(Math.round((y-origin.y)/scale),new jsPoint(x0+2+origin.x,y),rangeFont,rangeColor);
		 			}	
	 			}	
	 			else if(!lastRangeDiv)
	 			{
	 				if(coordinateSystem=="cartecian")
		 				currentRangeDiv = drawRange(Math.round((origin.y-y)/scale),new jsPoint(x0+2+origin.x,y),rangeFont,rangeColor);
		 			else	
		 				currentRangeDiv = drawRange(Math.round((y-origin.y)/scale),new jsPoint(x0+2+origin.x,y),rangeFont,rangeColor);
				}
				
				if(currentRangeDiv)
				{
					if(!isLeft)
					{
						if(parseInt(currentRangeDiv.style.left)+1+currentRangeDiv.offsetWidth < x1)
			 				currentRangeDiv.style.left=parseInt(currentRangeDiv.style.left)+1;
			 			else
							currentRangeDiv.style.left=x1-currentRangeDiv.offsetWidth-3;
					}
					else
					{
						if(parseInt(currentRangeDiv.style.left)-currentRangeDiv.offsetWidth-2 > x0)
			 				currentRangeDiv.style.left=parseInt(currentRangeDiv.style.left)-currentRangeDiv.offsetWidth-2;
			 			else
			 				currentRangeDiv.style.left=parseInt(currentRangeDiv.style.left)+1;
			 				
						if(parseInt(currentRangeDiv.style.left)<=x0)
							currentRangeDiv.style.left=x0 + 1;
					}
				
					currentRangeDiv.style.visibility="visible";
					
					//Hide the overlapping range.
					if(isUp && parseInt(currentRangeDiv.style.top)+currentRangeDiv.offsetHeight>origin.y-currentRangeDiv.offsetHeight && parseInt(currentRangeDiv.style.top)<origin.y)
						currentRangeDiv.style.visibility="hidden";

					if(isUp && parseInt(currentRangeDiv.style.top)>origin.y && parseInt(currentRangeDiv.style.top)<origin.y+currentRangeDiv.offsetHeight && parseInt(currentRangeDiv.style.top)>origin.y)
						currentRangeDiv.style.visibility="hidden";

					if(origin.y>y1 && parseInt(currentRangeDiv.style.top)+currentRangeDiv.offsetHeight>y1-currentRangeDiv.offsetHeight)
						currentRangeDiv.style.visibility="hidden";	

					if(!isUp && parseInt(currentRangeDiv.style.top)<origin.y+currentRangeDiv.offsetHeight && parseInt(currentRangeDiv.style.top)>origin.y)
						currentRangeDiv.style.visibility="hidden";
						
					if(!isUp && parseInt(currentRangeDiv.style.top)<origin.y && parseInt(currentRangeDiv.style.top)+currentRangeDiv.offsetHeight>origin.y && parseInt(currentRangeDiv.style.top)<origin.y)
					{
						alert(parseInt(currentRangeDiv.style.top));
						currentRangeDiv.style.visibility="hidden";
					}
					if(origin.y<y0 && parseInt(currentRangeDiv.style.top)<y0+currentRangeDiv.offsetHeight)
						currentRangeDiv.style.visibility="hidden";

					lastRangeDiv=currentRangeDiv;
				}
				currentRangeDiv = null;	

			}
		}

		gridDiv.innerHTML=gridDiv.innerHTML + iHtml.join("");
		
		//Internal function only to be used by showGrid method to draw the range value.
		function drawRange(text,point,font,color,align)
		{
	        var textDiv=document.createElement("div");

    	    textDiv.style.position="absolute";
        	textDiv.style.left=point.x + "px";
        	textDiv.style.top=point.y + "px";
        	textDiv.style.color=color.getHex();
        	textDiv.style.zIndex=-98;
			textDiv.style.visibility="hidden";

        	gridDiv.appendChild(textDiv);
                
        	//set font
        	if(font.family)
            	textDiv.style.fontFamily=font.family;

        	if(font.weight)
            	textDiv.style.fontWeight=font.weight;
        
        	if(font.size)
            	textDiv.style.fontSize=font.size;
        
        	if(font.style)
            	textDiv.style.fontStyle=font.style;
        
        	if(font.variant)
            	textDiv.style.fontVariant=font.variant;

            if(align) 
                textDiv.align=align;
        
	        textDiv.innerHTML=text;
    	    return textDiv;
    	}
	}

	//Clear the grid.
	function hideGrid()
	{
		gridDiv.innerHTML="";
		gridDiv.style.display="none";
	}
	
	//Draw Line between the 2 specified points based on Mid point Algorithm.
	function drawLine(pen,point0,point1)
	{
		//Check arguments for null values
		if(!pen || !point0 || !point1)
			return false;
			
	    var lineDiv=canvasDiv.appendChild(document.createElement("div"));
	    
	    //Some library functions use drawLine method and need to pass physical points only. So the following check.
	    if(arguments[3]!="physical") 
	    {
	    	phPoint0=logicalToPhysicalPoint(point0);
	   	    phPoint1=logicalToPhysicalPoint(point1);
   	    }
   	    else
   	    {
   	    	phPoint0=new jsPoint(point0.x,point0.y);
   	    	phPoint1=new jsPoint(point1.x,point1.y);
   	    }

	 	var x0, x1, y0, y1;
	 	x0=phPoint0.x;
	 	x1=phPoint1.x;
	 	y0=phPoint0.y;
	 	y1=phPoint1.y;
	 	
	 	var hexColor=pen.color.getHex();
   	 	//For Horizontal line
	 	if(y0==y1)
	 	{
	 		if(x0<=x1)
		 		lineDiv.innerHTML="<DIV style=\"position:absolute;overflow:hidden;left:" + x0 + "px;top:" + y0 + "px;width:" + (x1-x0+1) + "px;height:" + pen.width + ";background-color:" + hexColor + "\"></DIV>";
	 		else if(x0>x1)
		 		lineDiv.innerHTML="<DIV style=\"position:absolute;overflow:hidden;left:" + x1 + "px;top:" + y0 + "px;width:" + (x0-x1+1) + "px;height:" + pen.width + ";background-color:" + hexColor + "\"></DIV>";
		 		
	 		return lineDiv;
	 	}
	 	
	 	//For Vertical line
	 	if(x0==x1)
	 	{
	 		if(y0<=y1)
		 		lineDiv.innerHTML="<DIV style=\"position:absolute;overflow:hidden;left:" + x0 + "px;top:" + y0 + "px;width:" + pen.width + ";height:" + (y1-y0+1) + "px;background-color:" + hexColor + "\"></DIV>";
	 		else if(y0>y1)
		 		lineDiv.innerHTML="<DIV style=\"position:absolute;overflow:hidden;left:" + x0 + "px;top:" + y1 + "px;width:" + pen.width + ";height:" + (y0-y1+1) + "px;background-color:" + hexColor + "\"></DIV>";
		 		
	 		return lineDiv;
	 	}
		
	    var iHtml=new Array();
	 	var yArray=new Array();
	 	
	 	///Pixel Height Width Start
		var dx=Math.abs(x1-x0);
	 	var dy=Math.abs(y1-y0);
	 	var pixHeight,pixWidth;
	 	var penWidth=parseInt(pen.width);
	 	
	 	pixHeight=Math.round(Math.sqrt((penWidth*penWidth)/((dy*dy)/(dx*dx)+1)));
	 	pixWidth=Math.round(Math.sqrt(penWidth*penWidth-pixHeight*pixHeight));
	
	 	if(pixWidth==0)
	 	{
	 		pixWidth=1;
	 	}
	 	if(pixHeight==0)
	 	{
	 		pixHeight=1;
	 	}
	 	///Pixel Height Width End

	 	var steep = Math.abs(y1 - y0) > Math.abs(x1 - x0); 
		if (steep)
		{   
			// swap   
			var tmp=x0;
			x0=y0;
			y0=tmp;
			tmp=x1;
			x1=y1;
			y1=tmp;
		}

		if (x0 > x1)
		{   
			// swap   
			var tmp=x0;
			x0=x1;
			x1=tmp;
			tmp=y0;
			y0=y1;
			y1=tmp;
		}
		
		var deltax = x1 - x0;
		var deltay = Math.abs(y1 - y0);
		var error  = deltax/2;
		var ystep;
		var y = y0;
		
		if (y0<y1) 
			ystep = 1; 
		else 
			ystep = -1;
			
		var xp,yp;
		var divWidth=0;
 		var divHeight=0;
 		if(steep)
 		{
 			divWidth=pixWidth;
 		}
 		else
 		{
 			divHeight=pixHeight;
 		}
		for (x=x0;x<=x1;x++)
		{
   			if (steep)
   			{ 
   				if(x==x0)
   				{
   					xp=y;
   					yp=x;
   				}
   				else
   				{
   					if(y==xp)
   					{
   						divHeight=divHeight+ 1;
   					}
   					else
   					{
   						divHeight=divHeight+pixHeight;
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xp + "px;top:" + yp + "px;width:" + divWidth+ "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
 						divHeight=0;		
 						xp=y;
	   					yp=x;		
 					}
 				}
 				
 				if(x==x1)
 				{
 					if(divHeight!=0)
 					{
 						divHeight=divHeight+pixHeight;
 						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xp + "px;top:" + yp + "px;width:" + divWidth+ "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
 					}
 					else
 					{
 						divHeight=pixHeight;
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + y + "px;top:" + x + "px;width:" + divWidth+ "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
 					}
 				}
 			}
			else
			{ 
				if(x==x0)
   				{
   					xp=x;
   					yp=y;
   				}
   				else
   				{
   					if(y==yp)
   					{
   						divWidth=divWidth + 1;
   					}
   					else
   					{
   						divWidth=divWidth+pixWidth;
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xp + "px;top:" + yp + "px;width:" + divWidth+ "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
	 					divWidth=0;
 						xp=x;
 						yp=y;			
 					}
 				}	
 				if(x==x1)
 				{
 					if(divWidth!=0)
 					{
   						divWidth=divWidth+pixWidth;
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xp + "px;top:" + yp + "px;width:" + divWidth+ "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
 					}
 					else
 					{
 						divWidth=pixWidth;
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + x + "px;top:" + y + "px;width:" + divWidth+ "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
 					}
 				}
 			}

   			error = error - deltay;
   			if (error < 0)
			{     
				y = y + ystep;
     			error = error + deltax;
   			}
 		}
 		
 		lineDiv.innerHTML=iHtml.join("");
 		return lineDiv;
	}
	
	//Private function returns array of x coordinates for y values
	//for a line (algorithm same as drawLine method). 
	//Used by drawArc, fillArc and fillPolygon methods.
	function getLinePixels(point0,point1)
	{
		function xData()
		{
			this.xMax=0;
			this.xMin=0;
			this.isVertex=false;
		}
		
	 	var x0, x1, y0, y1;
	 	x0=point0.x;
	 	x1=point1.x;
	 	y0=point0.y;
	 	y1=point1.y;
	 	var xDataArray=new Array();
	 	var steep = Math.abs(y1 - y0) > Math.abs(x1 - x0); 
		if (steep)
		{   
			// swap   
			var tmp=x0;
			x0=y0;
			y0=tmp;
			tmp=x1;
			x1=y1;
			y1=tmp;
		}

		if (x0 > x1)
		{   
			// swap   
			var tmp=x0;
			x0=x1;
			x1=tmp;
			tmp=y0;
			y0=y1;
			y1=tmp;
		}

		var deltax = x1 - x0;
		var deltay = Math.abs(y1 - y0);
		var error  = deltax/2;
		var ystep;
		var y = y0;
		
		if (y0<y1) 
			ystep = 1; 
		else 
			ystep = -1;
			
		for (x=x0;x<=x1;x++)
		{
   			if (steep)
   			{ 
		   		xDataArray[x]=new xData();
		   		xDataArray[x].xMin=y;
		   		xDataArray[x].xMax=y;
		   		
		   		if(x==x0 && y==y0)
		   			xDataArray[x].isVertex=true;	
 			}
			else
			{ 
				if(!xDataArray[y])
				{
					xDataArray[y]=new xData();
					xDataArray[y].xMin=x;
			   		xDataArray[y].xMax=x;
			   		
			   		if(x==x0 && y==y0)
			   			xDataArray[y].isVertex=true;	
				}
				else
				{
					xDataArray[y].xMax=x;
				}
 			}

   			error = error - deltay;
   			if (error < 0)
			{     
				y = y + ystep;
     			error = error + deltax;
   			}
 		}
		return xDataArray;
	}

    //Draw rectangle at specified point with specified width and height.	
    function drawRectangle(pen,point,width,height)
    {
	    //Check arguments for null values
	    if(!pen || !point || !width || !height)
		    return false;
    		
	    width=Math.round(width*scale);
	    height=Math.round(height*scale);
    	
        var rectDiv=canvasDiv.appendChild(document.createElement("div"));
        var iHtml=new Array();
        
        var penWidth=parseInt(pen.width);
        var hexColor=pen.color.getHex(); 
        
        //If pen width is less than height or width specified use fillRectangle method
        if(penWidth>=height || penWidth>=width)
    	    return this.fillRectangle(pen.color,point,width,height);
        	
        phPoint=logicalToPhysicalPoint(point);
        
        //Draw 4 sides of the rectangle.
        iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + phPoint.x + "px;top:" + phPoint.y + "px;width:" + width +  "px;height:" + penWidth + "px;background-color:" + hexColor + "\"></DIV>";
        iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + phPoint.x + "px;top:" + (phPoint.y+height-penWidth) + "px;width:" + width +  "px;height:" + penWidth + "px;background-color:" + hexColor + "\"></DIV>";
        iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + phPoint.x + "px;top:" + (phPoint.y+penWidth) + "px;width:" + penWidth +  "px;height:" + (height-2*penWidth+1) + "px;background-color:" + hexColor + "\"></DIV>";
        iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (phPoint.x+width-penWidth) + "px;top:" + (phPoint.y+penWidth) + "px;width:" + penWidth +  "px;height:" + (height-2*penWidth+1) + "px;background-color:" + hexColor + "\"></DIV>";
        
  	    rectDiv.innerHTML=iHtml.join("");
  	    return rectDiv;
    }

    //Draw color filled rectangle at specified point with specified color, width and height
    function fillRectangle(color,point,width,height)
    {
	    //Check arguments for null values
	    if(!color || !point || !width || !height)
		    return false;

	    width=Math.round(width*scale);
	    height=Math.round(height*scale);
    	
        var rectDiv=canvasDiv.appendChild(document.createElement("div"));
        phPoint=logicalToPhysicalPoint(point);

        var hexColor=color.getHex();
        
        //Draw a single div element
  	    rectDiv.innerHTML="<DIV style=\"position:absolute;overflow:hidden;left:" + phPoint.x + "px;top:" + phPoint.y + "px;width:" + width +  "px;height:" + height + "px;background-color:" + hexColor + "\"></DIV>";
  	    return rectDiv;
    }

    //This is a private function to draw an ellipse with width 1px.
    //It is used by drawEllipse method. 
    //Mid point algorithm is used for the drawing
    function drawEllipseSingle(pen,center,width,height)
    {
   	    //Check arguments for null values
	    if(!pen || !center || !width || !height)
		    return false;
        
        var ellipseDiv=canvasDiv.appendChild(document.createElement("div"));
        var iHtml=new Array();

        var penWidth=parseInt(pen.width);
        var hexColor=pen.color.getHex();
        
	    var a=Math.round(width/2);
	    var b=Math.round(height/2);
	    var xc=center.x;
	    var yc=center.y;

	    var x=0;
	    var y=b;
	    var a2=a*a;
	    var b2=b*b;
    	
	    var yp=y;
	    var xp=x;
	    var divWidth;
	    var divHeight;
    	
 	    while(b2*x < a2*y)
  	    {     
  		    x++;    
 		    if((b2*x*x + a2*(y-0.5)*(y-0.5) - a2*b2) >=0)  
 			    y--;    
    		
		    if(x==1 && y!=yp)
		    {
		        iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc+x) + "px;top:" + (yc+y) + "px;width:1px;height:1px;background-color:" + hexColor + "\"></DIV>";
		        iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc+x) + "px;top:" + (yc-y) + "px;width:1px;height:1px;background-color:" + hexColor + "\"></DIV>";
		    }
      	    if(y!=yp)
      	    {
			    divWidth=x-xp;
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc+xp) + "px;top:" + (yc+yp-penWidth+1) + "px;height:" + penWidth + "px;width:" + divWidth + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp-divWidth+1) + "px;top:" + (yc+yp-penWidth+1) + "px;height:" + penWidth + "px;width:" + divWidth + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc+xp) + "px;top:" + (yc-yp) + "px;height:" + penWidth + "px;width:" + divWidth + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp-divWidth+1) + "px;top:" + (yc-yp) + "px;height:" + penWidth + "px;width:" + divWidth + "px;background-color:" + hexColor + "\"></DIV>";

			    yp=y;
			    xp=x;
		    }
    		
		    if(b2*x >= a2*y)
		    {
			    divWidth=x-xp+1;
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc+xp) + "px;top:" + (yc+yp-penWidth+1) + "px;height:" + penWidth + "px;width:" + divWidth + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp-divWidth+1) + "px;top:" + (yc+yp-penWidth+1) + "px;height:" + penWidth + "px;width:" + divWidth + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc+xp) + "px;top:" + (yc-yp) + "px;height:" + penWidth + "px;width:" + divWidth + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp-divWidth+1) + "px;top:" + (yc-yp) + "px;height:" + penWidth + "px;width:" + divWidth + "px;background-color:" + hexColor + "\"></DIV>";
		    }
	    }

  	    yp=y;
	    xp=x;
    	
	    while(y!=0)  
	    {
		    y--;   
  		    if((b2*(x+0.5)*(x+0.5) + a2*y*y - a2*b2)<=0)   
     		    x++;
    		
     	    if(x!=xp)
     	    {
			    divHeight=yp-y;
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc+xp-penWidth+1) + "px;top:" + (yc+yp-divHeight+1) + "px;width:" + penWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc+xp-penWidth+1) + "px;top:" + (yc-yp) + "px;width:" + penWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp) + "px;top:" + (yc+yp-divHeight+1) + "px;width:" + penWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp) + "px;top:" + (yc-yp) + "px;width:" + penWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    			
			    xp=x;
			    yp=y;
		    }
    		
     	    if(y==0)
     	    {
			    divHeight=yp-y+1;
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc+xp-penWidth+1) + "px;top:" + (yc+yp-divHeight+1) + "px;width:" + penWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc+xp-penWidth+1) + "px;top:" + (yc-yp) + "px;width:" + penWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp) + "px;top:" + (yc+yp-divHeight+1) + "px;width:" + penWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp) + "px;top:" + (yc-yp) + "px;width:" + penWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    			
			    xp=x;
			    yp=y;
		    }

 	    }
     	
 	    ellipseDiv.innerHTML=iHtml.join("");
 	    return ellipseDiv;
    }

    //Draw ellipse with specified center, width and height.
    //Mid point algorithm is used for basic drawing.  
    function drawEllipse(pen,center,width,height)
    {
	    //Check arguments for null values
	    if(!pen || !center || !width || !height)
		    return false;
    		
	    width*=scale;
	    height*=scale;

        var ellipseDiv=canvasDiv.appendChild(document.createElement("div"));
        var iHtml=new Array();
        
        phCenter=logicalToPhysicalPoint(center);

	    var penWidth=parseInt(pen.width);
	    if(penWidth<=1)
	    {
		    return drawEllipseSingle(pen,phCenter,width,height);
	    }
    	
	    var hexColor=pen.color.getHex();
    	
	    var a=Math.round(width/2);
	    var b=Math.round(height/2);
	    var xc=phCenter.x;
	    var yc=phCenter.y;
    	
	    //For inner ellipse
	    var ai=a-penWidth + 1;
	    var bi=b-penWidth + 1;
    	
	    //For drawing ellipse having width more than 1px, inner ellipse is required to be considered
	    var res=getInnerEllipse(phCenter,ai*2,bi*2)
    	
	    var xArray=res[0];
	    var xArrayI=res[1];
    	
	    var yi=bi;
	    var ai2=ai*ai;
	    var bi2=bi*bi;
    	
	    var x=0;
	    var y=b;
	    var a2=a*a;
	    var b2=b*b;
    	
	    var xp,yp;
    	
	    xp=1;
	    yp=y;
	    var ypi=yi;
    	
	    var xT;
	    var divWidth;
	    var divHeight=1;
    	
 	    while(b2*x < a2*y)
  	    {     
  		    x++;    
 		    if((b2*x*x + a2*(y-0.5)*(y-0.5) - a2*b2) >=0)  
 			    y--;    
    		
		    if(y+1<bi)
		    {
 			    if(y!=yp)
			    {
				    xT=xc-x+1;
				    divWidth=(x-1)+1-xArray[yp];
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc-yp) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc+yp) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";

				    xT=xT+2*(x-1)+1-divWidth;
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc-yp) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc+yp) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				
				    yp=y;		
				    xp=x;
			    }
			    //Last step in loop
			    if(b2*x >= a2*y)
			    {
				    xT=xc-x;
				    divWidth=x+1-xArray[yp];
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc-y) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc+y) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				
				    xT=xT+2*x+1-divWidth;
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc-y) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc+y) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
		    }	 		
		    else
		    {
      		    if(x==1 && y!=yp) //Topmost and bottom most points, to be tested
      		    {
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;width:1px;height:1px;left:" + xc + "px;top:" + (yc+yp-1) + "px;background-color:" + hexColor + "\"></DIV>";
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;width:1px;height:1px;left:" + xc + "px;top:" + (yc-yp) + "px;background-color:" + hexColor + "\"></DIV>";      		
			    }
			    if(y!=yp)
			    {
   				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-x+1) + "px;top:" + (yc-yp) + "px;width:" + (2*(x-1)+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-x+1) + "px;top:" + (yc+yp) + "px;width:" + (2*(x-1)+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
				    yp=y;
			    }
    					
			    //Last step in loop
			    if(y==bi || y==0)
			    {
  				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-x) + "px;top:" + (yc-y) + "px;width:" + (2*x+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-x) + "px;top:" + (yc+y) + "px;width:" + (2*x+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
		    }
	    }
    	  
	    xp=x;
	    yp=y;
	    divHeight=1;
	    var xpi=xArray[y];

	    while(y!=0)  
	    {     
		    y--;   
  		    if((b2*(x+0.5)*(x+0.5) + a2*y*y - a2*b2)<=0)   
     		    x++;
    		
			    if(y+1<bi)
			    {
				    if(x!=xp || xArray[y]!=xpi)
				    {
					    divHeight=yp-y;
    					
					    xT=xc-xp;
					    divWidth=xp+1-xArray[y+1];
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc-yp) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc+y+1) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				
					    xT=xT+2*xp+1-divWidth;
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc-yp) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc+y+1) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				
					    xp=x;
					    yp=y;
					    xpi=xArray[y];
				    }
    		
				    //Last step in loop
				    if(y==0)
				    {
					    divHeight=yp-y+1;

					    xT=xc-x;
					    divWidth=x+1-xArray[y];
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc-yp) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc+y) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				
					    xT=xT+2*x+1-divWidth;
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc-yp) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + xT + "px;top:" + (yc+y) + "px;width:" + divWidth + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
        				
    				    xp=x;
					    yp=y;
					    xpi=xArray[y];
				    }
			    }
			    else
			    {
				    if(x!=xp)
				    {
					    divHeight=yp-y;
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp) + "px;top:" + (yc-yp) + "px;width:" + (2*xp+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp) + "px;top:" + (yc+y+1) + "px;width:" + (2*xp+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";

					    xp=x;
					    yp=y;
					    xpi=xArray[y];
				    }
    		
				    //Last step in loop
				    if(y==bi || y==0)
				    {
				        divHeight=yp-y+1;
    				    
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-x) + "px;top:" + (yc-yp) + "px;width:" + (2*x+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-x) + "px;top:" + (yc+y) + "px;width:" + (2*x+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
        				
					    xp=x;
					    yp=y;
					    xpi=xArray[y];
				    }
			    }	
 		    }
     		
 		    ellipseDiv.innerHTML=iHtml.join("");
 		    return ellipseDiv;
    }

    //For ellipse having width more than 1 px, get the coordinates for inner ellipse.
    function getInnerEllipse(center,w,h)
    {
	    var a=Math.round(w/2);
	    var b=Math.round(h/2);
	    var xc=center.x;
	    var yc=center.y;
    	
	    xArray=new Array();
	    xArrayI=new Array();

	    var x=0;
	    var y=b;
	    var a2=a*a;
	    var b2=b*b;
    	
	    xArray[y]=x;
	    xArrayI[y]=x;
    	
	    var divWidth;
	    var divHeight;
    	
	    //Upper and Lower portions of the ellipse
 	    while(b2*x < a2*y)
  	    {     
  		    x++;    
 		    if((b2*x*x + a2*(y-0.5)*(y-0.5) - a2*b2) >=0)  
 			    y--;    
      	    if(!xArray[y])
		    xArray[y]=x;
    		
		    xArrayI[y]=x;
	    }
    	
	    //Left and Right portions of the ellipse
	    while(y!=0)  
	    {     
		    y--;   
  		    if((b2*(x+0.5)*(x+0.5) + a2*y*y - a2*b2)<=0)   
     		    x++;

   		    xArray[y]=x;
   		    xArrayI[y]=x;
 	    }
 	    return new Array(xArray,xArrayI);
    }

    //Draw circle with specified center and radius.
    //Uses drawEllipse method only.
    function drawCircle(pen,center,radius)
    {
   	    //Check arguments for null values
	    if(!pen || !center || !radius)
		    return false;
    		
        return drawEllipse(pen,center,2*radius,2*radius);
    }

    //Draw circle filled with the specified color alongwith specified center and radius.
    //Uses drawEllipse method only.
    function fillCircle(color,center,radius)
    {
   	    //Check arguments for null values
	    if(!color || !center || !radius)
		    return false;
    		
        return fillEllipse(color,center,2*radius,2*radius);
    }

    //Draw ellipse filled with specified color and other parameters, center, width and height.
    //Mid point algorithm is used for basic ellipse drawing.  
    function fillEllipse(color,center,width,height)
    {
	    //Check arguments for null values
	    if(!color || !center || !width || !height)
		    return false;
    		
	    width*=scale;
	    height*=scale;

        var ellipseDiv=canvasDiv.appendChild(document.createElement("div"));
        var iHtml=new Array();

        phCenter=logicalToPhysicalPoint(center);

	    var a=Math.round(width/2);
	    var b=Math.round(height/2);
	    var xc=phCenter.x;
	    var yc=phCenter.y;
	    var hexColor=color.getHex();
    	
	    var x=0;
	    var y=b;
	    var a2=a*a;
	    var b2=b*b;
    	
	    var xp,yp;
    	
	    xp=1;
	    yp=y;
    	
	    //Upper and Lower portion of the ellipse
 	    while(b2*x < a2*y)
  	    {     
  		    x++;    
 		    if((b2*x*x + a2*(y-0.5)*(y-0.5) - a2*b2) >=0)  
 			    y--;    
     			
      	    if(x==1 && y!=yp) //Topmost and bottom most points, to be tested
      	    {
          	
      		    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;width:1px;height:1px;left:" + xc + "px;top:" + (yc+yp-1) + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;width:1px;height:1px;left:" + xc + "px;top:" + (yc-yp) + "px;background-color:" + hexColor + "\"></DIV>";

      	    }
		    if(y!=yp)
		    {
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;height:1px;left:" + (xc-x+1) + "px;top:" + (yc-yp) + "px;width:" + (2*x-1) + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;height:1px;left:" + (xc-x+1) + "px;top:" + (yc+yp) + "px;width:" + (2*x-1) + "px;background-color:" + hexColor + "\"></DIV>";

			    yp=y;
			    xp=x;		
		    }
    			
    		
		    //Last step in loop
		    if(b2*x >= a2*y)
		    {
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;height:1px;left:" + (xc-x) + "px;top:" + (yc-yp) + "px;width:" + (2*x+1) + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;height:1px;left:" + (xc-x) + "px;top:" + (yc+yp) + "px;width:" + (2*x+1) + "px;background-color:" + hexColor + "\"></DIV>";
		    }
	    }
    	  
	    xp=x;
	    yp=y;
	    var divHeight=1;

	    //Left and Right portion of the ellipse
	    while(y!=0)  
	    {     
		    y--;   
  		    if((b2*(x+0.5)*(x+0.5) + a2*y*y - a2*b2)<=0)   
     		    x++;
    		
		    if(x!=xp)
		    {
			    divHeight=yp-y;
    			
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp) + "px;top:" + (yc-yp) + "px;width:" + (2*xp+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp) + "px;top:" + (yc+y+1) + "px;width:" + (2*xp+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    			
			    xp=x;
			    yp=y;
		    }
    		
		    //Last step in loop
		    if(y==0)
		    {
			    divHeight=yp-y+1;
    			
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp) + "px;top:" + (yc-yp) + "px;width:" + (2*x+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + (xc-xp) + "px;top:" + (yc+y) + "px;width:" + (2*x+1) + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
		    }
 	    }
     	
 	    ellipseDiv.innerHTML=iHtml.join("");
 	    return ellipseDiv;
    }

    //Draw arc filled with specified color, center, width, height, start angle and swap angle. 
    function fillArc(color,center,width,height,startAngle,swapAngle)
    {
	    //Check arguments for null values 
	    if(!color || !center || !width || !height || startAngle==null || swapAngle==null)
		    return false;

	    width*=scale;
	    height*=scale;
      
        if(swapAngle==0)
        return;
        
        var arcDiv=canvasDiv.appendChild(document.createElement("div"));
        var iHtml=new Array();
        
        phCenter=logicalToPhysicalPoint(center);
        
	    var saD; //arc start angle degrees.
	    if(startAngle>360)
	        saD=startAngle%360;
	    else
	        saD=startAngle;
    	 
	    var swD; //swap angle in degrees.
	    if(swapAngle>360)
	        swD=swapAngle%360;
	    else
	        swD=swapAngle;
    	    
	    var eaD; //arc end angle degrees.
	    eaD=parseFloat(saD)+parseFloat(swD);
	    if(eaD>360)
	        eaD=eaD%360; 

	    //For cartecian coordinate system.
	    if(coordinateSystem=="cartecian")    
	    {
		    saD=360-saD;
		    eaD=360-eaD;
		    var tempAD;
		    tempAD=saD;
		    saD=eaD;
		    eaD=tempAD;
	    }

	    var x1,y1,x2,y2;
	    var saR=saD*Math.PI/180;
	    var swR=swD*Math.PI/180;
	    var eaR=eaD*Math.PI/180;
    	
	    //For start angle
	    if((saD<=45 && saD>=0) || (saD>=135 && saD<=225) || (saD>=315 && saD<=360))
	    {
		    y1=Math.round(phCenter.y+Math.sin(saR)*width/2);
		    if(saD>=90 && saD<=270)
			    x1=Math.round(phCenter.x-width/2);
		    else
			    x1=Math.round(phCenter.x+width/2);
	    }
	    else
	    {
		    x1=Math.round(phCenter.x+Math.cos(saR)*height/2);
		    if(saD>=0 && saD<=180)
			    y1=Math.round(phCenter.y+height/2);
		    else
			    y1=Math.round(phCenter.y-height/2);
	    }
    	
	    //For end angle
	    if((eaD<=45 && eaD>=0) || (eaD>=135 && eaD<=225) || (eaD>=315 && eaD<=360))
	    {
		    y2=Math.round(phCenter.y+Math.sin(eaR)*width/2);
		    if(eaD>=90 && eaD<=270)
			    x2=Math.round(phCenter.x-width/2);
		    else
			    x2=Math.round(phCenter.x+width/2);
	    }
	    else
	    {
		    x2=Math.round(phCenter.x+Math.cos(eaR)*height/2);
		    if(eaD>=0 && eaD<=180)
			    y2=Math.round(phCenter.y+height/2);
		    else
			    y2=Math.round(phCenter.y-height/2);
	    }
    	
	    //Get the pixel arrays for the lines croping the ellipse to form an arc.
	    xDataArraySa=getLinePixels(phCenter,new jsPoint(x1,y1));
	    xDataArrayEa=getLinePixels(phCenter,new jsPoint(x2,y2));
    	
	    var hexColor=color.getHex();

	    var a=Math.round(width/2);
	    var b=Math.round(height/2);
	    var xc=phCenter.x;
	    var yc=phCenter.y;
    	
	    var x=0;
	    var y=b;
	    var a2=a*a;
	    var b2=b*b;
    	
	    var xp,yp;
	    var divX1,divX1pU,divX1pD,divX2,divX2pU,divX2pD,divY1,divY2,saX,eaX,saXp,eaXp,xpU,xpD,ypU,ypD;
	    var divWidthOrg,divWidth1,divWidth2,divWidth3,divWidth4,divWidth1p,divWidth2p,divWidth3p,divWidth4p,divHeight;
	    var draw1p,draw2p,draw3p,draw4p;
    	
	    xp=1;
	    yp=y;
    	
	    //Upper and lower portion of the ellipse constutuing the arc
 	    while(b2*x < a2*y)
  	    {     
  		    x++;    
 		    if((b2*x*x + a2*(y-0.5)*(y-0.5) - a2*b2) >=0)  
 			    y--;    
     			
      	    if(x==1 && y!=yp) //Topmost and bottom most points, to be tested
      	    {
      		    divY1=yc+yp-1;
			    divY2=yc-yp;
			    divWidthOrg=1;
			    divWidth1=divWidthOrg;
			    divWidth2=divWidthOrg;
			    divWidth3=divWidthOrg;
			    divWidth4=divWidthOrg;
			    divX1=xc;
    			
			    if(saD>=0 && saD<180 && eaD>=0 && eaD<180)
			    {
				    fillArcSegOut(true);
				    if(eaD<=saD)
				    fillArcSegOut(false);
			    }
			    else if(saD>=180 && saD<360 && eaD>=180 && eaD<=360)
			    {
				    fillArcSegOut(false);
				    if(eaD<=saD)
				    fillArcSegOut(true);
			    }
			    else
			    {
				    fillArcSegOut(true);
				    fillArcSegOut(false);
			    }
      	    }
		    else if(y!=yp)
		    {
			    divY1=yc+yp;
			    divY2=yc-yp;
			    divWidthOrg=2*(x-1)+1;
			    divWidth1=divWidthOrg;
			    divWidth2=divWidthOrg;
			    divWidth3=divWidthOrg;
			    divWidth4=divWidthOrg;
			    divX1=xc-x+1;
    			
			    if(saD>=0 && saD<180 && eaD>=0 && eaD<180)
			    {
				    fillArcSegOut(true);
				    if(eaD<=saD)
				    fillArcSegOut(false);
			    }
			    else if(saD>=180 && saD<360 && eaD>=180 && eaD<=360)
			    {
				    fillArcSegOut(false);
				    if(eaD<=saD)
				    fillArcSegOut(true);
			    }
			    else
			    {
				    fillArcSegOut(true);
				    fillArcSegOut(false);
			    }	
    			
			    yp=y;
			    xp=x;
		    }
    				
    		
		    //Last step in loop
		    if(b2*x >= a2*y)
		    {
			    divY1=yc+yp;
			    divY2=yc-yp;
			    divWidthOrg=2*x+1;
			    divWidth1=divWidthOrg;
			    divWidth2=divWidthOrg;
			    divWidth3=divWidthOrg;
			    divWidth4=divWidthOrg;
			    divX1=xc-x;
    			
			    if(saD>=0 && saD<180 && eaD>=0 && eaD<180)
			    {
				    fillArcSegOut(true);
				    if(eaD<=saD)
				    fillArcSegOut(false);
			    }
			    else if(saD>=180 && saD<360 && eaD>=180 && eaD<=360)
			    {
				    fillArcSegOut(false);
				    if(eaD<=saD)
				    fillArcSegOut(true);
			    }
			    else
			    {
				    fillArcSegOut(true);
				    fillArcSegOut(false);
			    }
		    }
    		
	    }
    	  
        xp=x;
	    yp=y;
	    divHeight=1;

	    //Similar code as in next while loop for first y before the loop. Only values are retrieved and no drawing.
    	    			
	    divY1=yc+y;
	    divY2=yc-y;
	    divWidthOrg=2*x+1;
	    divWidth1=divWidthOrg;
	    divWidth2=divWidthOrg;
	    divWidth3=divWidthOrg;
	    divWidth4=divWidthOrg;
	    divX1=xc-x;
    	
	    if(saD>=0 && saD<180 && eaD>=0 && eaD<180)
	    {
		    xDataArrayEa.pop();				
		    fillArcSegIn(true,true);
		    if(eaD<=saD)
		    fillArcSegIn(false,true);
	    }				
	    else if(saD>=180 && saD<360 && eaD>=180 && eaD<=360)
	    {
		    xDataArrayEa.pop();				
		    if(y!=0)
			    fillArcSegIn(false,true);
		    if(eaD<=saD)
		        fillArcSegIn(true,true);
	    }
	    else
	    {
		    if(saD>=180 && saD<360)
			    xDataArraySa.pop();
		    else
			    xDataArrayEa.pop();
    		

		    fillArcSegIn(true,true);
		    if(y!=0)
		    {
			    divX1=xc-x;
			    fillArcSegIn(false,true);
		    }
	    }

	    //Left and Right portion of the ellipse ellipse constutuing the arc.
	    while(y!=0)  
	    {
		    y--;   
		    if((b2*(x+0.5)*(x+0.5) + a2*y*y - a2*b2)<=0)   
 			    x++;
     
		    divY1=yc+y;
		    divY2=yc-y;
		    divWidthOrg=2*x+1;
		    divWidth1=divWidthOrg;
		    divWidth2=divWidthOrg;
		    divWidth3=divWidthOrg;
		    divWidth4=divWidthOrg;
		    divX1=xc-x;
			
		    if(saD>=0 && saD<180 && eaD>=0 && eaD<180)
		    {
			    fillArcSegIn(true);
			    if(eaD<=saD)
			    fillArcSegIn(false);
		    }				
		    else if(saD>=180 && saD<360 && eaD>=180 && eaD<=360)
		    {
			    if(y!=0)
				    fillArcSegIn(false);
			    if(eaD<=saD)
				    fillArcSegIn(true);
		    }
		    else
		    {
			    fillArcSegIn(true);
			    if(y!=0)
			    {
				    divX1=xc-x;
				    fillArcSegIn(false);
			    }	
		    }
 	    }
     	
 	    arcDiv.innerHTML=iHtml.join("");
 	    return arcDiv;

	    //Internal function: Arc segment for left and right portion of the ellipse constutuing the arc.
	    function fillArcSegIn(isUpperHalf,valueOnly)
	    {
		    var divY;
		    var xDataArray1,xDataArray1;
		    var divWidthFirst=divWidthOrg;
		    var divWidthSecond=divWidthOrg;
		    var drawFirst=false;
		    var drawSecond=false;
    		
		    if(isUpperHalf)
		    {
			    var draw1=false; //upper half (in all comments upper & lower are in context of cartecian system)
			    var draw3=false; //upper half second
			    divY=divY1;
			    xDataArray1=xDataArraySa;
			    xDataArray2=xDataArrayEa;
			    saDvar=saD;
			    eaDvar=eaD;
		    }
		    else
		    {
			    var draw2=false; //lower half
			    var draw4=false; //lower half second
			    divY=divY2;
			    xDataArray2=xDataArraySa;
			    xDataArray1=xDataArrayEa;
			    saDvar=360-eaD;
			    eaDvar=360-saD;
		    }
		    if(eaDvar>saDvar)
		    {
			    if(xDataArray2[divY] && divX1+divWidthOrg>=xDataArray2[divY].xMin && divX1<=xDataArray2[divY].xMin)
			    {
				    eaX=xDataArray2[divY].xMin;
				    if(xDataArray1[divY] && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
				    {
					    saX=xDataArray1[divY].xMax+1;
					    divWidthFirst=saX-eaX;
				    }
				    else
				    {
					    divWidthFirst=divX1+divWidthOrg-eaX;
				    }
				    divX1=eaX;
				    drawFirst=true;
			    }
			    else if(xDataArray1[divY] && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
			    {
				    saX=xDataArray1[divY].xMax+1;
				    divWidthFirst=saX-divX1;
				    drawFirst=true;
			    }
			    else if(eaDvar>90 && saDvar<90)
			    {
				    drawFirst=true;
			    }
		    }
		    else //saDvar>=eaDvar
		    {
			    if(xDataArray1[divY] && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
			    {
				    saX=xDataArray1[divY].xMax+1;
				    divWidthFirst=saX-divX1;
				    drawFirst=true;
			    }
			    else if(eaDvar<90 && saDvar<90)
			    {
				    drawFirst=true;
			    }
    	
			    if(xDataArray2[divY] && divX1+divWidthOrg>=xDataArray2[divY].xMin && divX1<=xDataArray2[divY].xMin)
			    {
				    divX2=xDataArray2[divY].xMin;
				    divWidthSecond=divWidthOrg-xDataArray2[divY].xMin+divX1;
				    drawSecond=true;
			    }
			    else if(eaDvar>90 && saDvar>90)
			    {
				    divX2=divX1;
				    divWidthSecond=divWidthOrg;
				    drawSecond=true;
			    }
		    }
    		
		    if(isUpperHalf)
		    {
			    if(drawFirst)
				    draw1=true;
    			
			    if(drawSecond)
				    draw3=true;
    				
			    divWidth1=divWidthFirst;
			    divWidth3=divWidthSecond;	
		    }
		    else
		    {
			    if(drawFirst)
				    draw2=true;
    			
			    if(drawSecond)
				    draw4=true;
    				
			    divWidth2=divWidthFirst;
			    divWidth4=divWidthSecond;	
		    }
    		
		    if(saD>=0 && saD<180 && eaD>=0 && eaD<180 && saD>eaD)
		    {
			    draw2=true;
		    }				
		    else if(saD>=180 && saD<360 && eaD>=180 && eaD<360 && saD>eaD)
		    {
			    draw1=true;
		    }
    		
		    if(!divX2)
		    divX2="";
		    if(!divX1)
		    divX1="";
    		
		    if(!valueOnly)
		    {
			    if(isUpperHalf)
			    {
				    if(x!=xpU || divX1pU!=divX1 || divX2pU!=divX2 || divWidth1!=divWidth1p || divWidth3!=divWidth3p)
				    {
					    divHeight=ypU-y;
					    if(draw3p)
					    {
						    if(divX2pU!=null)
							    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2pU + "px;top:" + (divY1+1) + "px;width:" + divWidth3p + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					    }
					    if(draw1p)
					    {
						    if(divX1pU!=null)
							    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1pU + "px;top:" + (divY1+1) + "px;width:" + divWidth1p + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					    }
    					
					    if(draw1p||draw3p)	
					    {
						    divX1pU=divX1;
    					
						    draw1p=draw1;
						    draw3p=draw3;
						    xpU=x;
						    ypU=y;
    					
						    divWidth1p=divWidth1;
						    divWidth3p=divWidth3;
						    divX2pU=divX2;
					    }
				    }
			    }	
			    else
			    {
				    if(x!=xpD || divX1pD!=divX1 || divX2pD!=divX2 || divWidth2!=divWidth2p || divWidth4!=divWidth4p)
				    {
					    divHeight=ypD-y;
					    if(draw4p)
					    {
						    if(divX2pD!=null)
							    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2pD + "px;top:" + (divY2-divHeight) + "px;width:" + divWidth4p + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					    }
					    if(draw2p)
					    {
						    if(divX1pD!=null) 
							    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1pD + "px;top:" + (divY2-divHeight) + "px;width:" + divWidth2p + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					    }
					    if(draw2p||draw4p)
					    {
						    divX1pD=divX1;
    					
						    draw2p=draw2;
						    draw4p=draw4;

						    xpD=x;
						    ypD=y;
    					
						    divWidth2p=divWidth2;
						    divWidth4p=divWidth4;
						    divX2pD=divX2;
					    }
				    }
			    }			
		    }
    		
		    //To get only values; used for first y value before loop. 
		    if(valueOnly)
		    {
			    if(isUpperHalf)
			    {
				    draw1p=draw1;
				    draw3p=draw3;
    				
				    if(draw1p)
				    divX1pU=divX1;
    				
				    if(draw3p)
				    divX2pU=divX2;
    				
				    if(draw1p||draw3p)
				    {
				        ypU=y;
				        xpU=x;
				    }
				    else
				    {
				        ypU=0;
				        xpU=0;
				    }
    				
				    divWidth1p=divWidth1;
				    divWidth3p=divWidth3;
			    }
			    else
			    {
				    draw2p=draw2;
				    draw4p=draw4;

				    if(draw2p)
				    divX1pD=divX1;
    				
				    if(draw4p)
				    divX2pD=divX2;
    				
				    if(draw2p||draw4p)
				    {
				        ypD=y;
				        xpD=x;
				    }
				    else
				    {
				        ypD=0;
				        xpD=0;
				    }
    				
				    divWidth2p=divWidth2;
				    divWidth4p=divWidth4;
			    }
		    }
    		
		    if(!isUpperHalf)
		    {
			    draw2p=draw2;
			    draw4p=draw4;
		    }
		    else
		    {
			    draw1p=draw1;
			    draw3p=draw3;
		    }
    		
		    if(y==1 && !isUpperHalf)
		    {
			    divHeight=ypD-y+1;
			    if(draw4)
			    {
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2 + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth4 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
			    if(draw2)
			    {
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1 + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth2 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
		    }
		    if(y==0 && isUpperHalf)
		    {	
			    divHeight=ypU-y+1;
			    if(draw3)
			    {
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2 + "px;top:" + (divY1) + "px;width:" + divWidth3 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
			    if(draw1)
			    {
				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1 + "px;top:" + (divY1) + "px;width:" + divWidth1 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
		    }		
	    }
    	
	    //Internal function: Arc segment for upper and lower portion of the ellipse constutuing the arc.
	    function fillArcSegOut(isUpperHalf)
	    {
		    var divY;
		    var xDataArray1,xDataArray1;
		    var divWidthFirst=divWidthOrg;
		    var divWidthSecond=divWidthOrg;
		    var drawFirst=false;
		    var drawSecond=false;
    		
		    if(isUpperHalf)
		    {
			    var draw1=false; //upper half
			    var draw3=false; //upper half second
			    divY=divY1;
			    xDataArray1=xDataArraySa;
			    xDataArray2=xDataArrayEa;
			    saDvar=saD;
			    eaDvar=eaD;
		    }
		    else
		    {
			    var draw2=false; //lower half
			    var draw4=false; //lower half second
			    divY=divY2;
			    xDataArray2=xDataArraySa;
			    xDataArray1=xDataArrayEa;
			    saDvar=360-eaD;
			    eaDvar=360-saD;
		    }
		    if(eaDvar>saDvar)
		    {
			    if(xDataArray2[divY]!=null && divX1+divWidthOrg>=xDataArray2[divY].xMin && divX1<=xDataArray2[divY].xMin)
			    {
				    eaX=xDataArray2[divY].xMin;
				    if(xDataArray1[divY]!=null && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
				    {
					    saX=xDataArray1[divY].xMax+1;
					    divWidthFirst=saX-eaX;
				    }
				    else
				    {
					    divWidthFirst=divX1+divWidthOrg-eaX;
				    }
				    divX1=eaX;
				    drawFirst=true;
			    }
			    else if(xDataArray1[divY]!=null && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
			    {
				    saX=xDataArray1[divY].xMax+1;
				    divWidthFirst=saX-divX1;
				    drawFirst=true;
			    }
			    else if(eaDvar>90 && saDvar<90)
			    {
				    drawFirst=true;
			    }
		    }
		    else //saDvar>eaDvar
		    {
			    if(xDataArray1[divY]!=null && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
			    {
				    saX=xDataArray1[divY].xMax+1;
				    divWidthFirst=saX-divX1;
				    drawFirst=true;
			    }
			    else if(eaDvar<90 && saDvar<90)
			    {
				    drawFirst=true;
			    }
    	
			    if(xDataArray2[divY]!=null && divX1+divWidthOrg>=xDataArray2[divY].xMin && divX1<=xDataArray2[divY].xMin)
			    {
				    divX2=xDataArray2[divY].xMin;
				    divWidthSecond=divWidthOrg-xDataArray2[divY].xMin+divX1;
				    drawSecond=true;
			    }
			    else if(eaDvar>90 && saDvar>90)
			    {
				    divX2=divX1;
				    divWidthSecond=divWidthOrg;
				    drawSecond=true;
			    }
		    }
    		
		    if(isUpperHalf)
		    {
			    if(drawFirst)
				    draw1=true;
    			
			    if(drawSecond)
				    draw3=true;
    				
			    divWidth1=divWidthFirst;
			    divWidth3=divWidthSecond;	
		    }
		    else
		    {
			    if(drawFirst)
				    draw2=true;
    			
			    if(drawSecond)
				    draw4=true;
    				
			    divWidth2=divWidthFirst;
			    divWidth4=divWidthSecond;	
		    }
    		
		    if(saD>=0 && saD<180 && eaD>=0 && eaD<180 && saD>eaD)
		    {
			    draw2=true;
		    }				
		    else if(saD>=180 && saD<360 && eaD>=180 && eaD<360 && saD>eaD)
		    {
			    draw1=true;
		    }
    		
		    if(divX2==null)
		    divX2="X";
		    if(divX1==null)
		    divX1="X";
    		
		    if(isUpperHalf)
		    {
			    divHeight=1;
			    if(draw3)
			    {
				    if(divX2!="X")
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2 + "px;top:" + divY1 + "px;width:" + divWidth3 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
			    if(draw1)
			    {
				    if(divX1!="X")
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1 + "px;top:" + divY1 + "px;width:" + divWidth1 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
		    }	
		    else
		    {
			    divHeight=1;
			    if(draw4)
			    {
				    if(divX2!="X")
    				    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2 + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth4 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
			    if(draw2)
			    {
				    if(divX1!="X") 
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1 + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth2 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
		    }			
	    }
    }

    //Draw arc with specified center, width, height, start angle and swap angle. 
    function drawArc(pen,center,width,height,startAngle,swapAngle)
    {
	    //Check arguments for null values
	    if(!pen || !center || !width || !height || startAngle==null || swapAngle==null)
		    return false;

	    width*=scale;
	    height*=scale;
       
        if(swapAngle==0)
        return;

        var arcDiv=canvasDiv.appendChild(document.createElement("div"));
        var iHtml=new Array();
        
        phCenter=logicalToPhysicalPoint(center);

	    var saD; //arc start angle degrees.
	    if(startAngle>360)
	        saD=startAngle%360;
	    else
	        saD=startAngle;
    	 
	    var swD; //swap angle in degrees.
	    if(swapAngle>360)
	        swD=swapAngle%360;
	    else
	        swD=swapAngle;
    	
	    var eaD; //arc end angle degrees.
	    eaD=parseFloat(saD)+parseFloat(swD);
	    if(eaD>360)
	        eaD=eaD%360; 
    	
	    //For cartecian coordinate system.
	    if(coordinateSystem=="cartecian")    
	    {
		    saD=360-saD;
		    eaD=360-eaD;
		    var tempAD;
		    tempAD=saD;
		    saD=eaD;
		    eaD=tempAD;
	    }
    	
	    var x1,y1,x2,y2;
	    var saR=saD*Math.PI/180;
	    var swR=swD*Math.PI/180;
	    var eaR=eaD*Math.PI/180;
    	
	    //For start angle
	    if((saD<=45 && saD>=0) || (saD>=135 && saD<=225) || (saD>=315 && saD<=360))
	    {
		    y1=Math.round(phCenter.y+Math.sin(saR)*width/2);
		    if(saD>=90 && saD<=270)
			    x1=Math.round(phCenter.x-width/2);
		    else
			    x1=Math.round(phCenter.x+width/2);
	    }
	    else
	    {
		    x1=Math.round(phCenter.x+Math.cos(saR)*height/2);
		    if(saD>=0 && saD<=180)
			    y1=Math.round(phCenter.y+height/2);
		    else
			    y1=Math.round(phCenter.y-height/2);
	    }
    	
	    //For end angle
	    if((eaD<=45 && eaD>=0) || (eaD>=135 && eaD<=225) || (eaD>=315 && eaD<=360))
	    {
		    y2=Math.round(phCenter.y+Math.sin(eaR)*width/2);
		    if(eaD>=90 && eaD<=270)
			    x2=Math.round(phCenter.x-width/2);
		    else
			    x2=Math.round(phCenter.x+width/2);
	    }
	    else
	    {
		    x2=Math.round(phCenter.x+Math.cos(eaR)*height/2);
		    if(eaD>=0 && eaD<=180)
			    y2=Math.round(phCenter.y+height/2);
		    else
			    y2=Math.round(phCenter.y-height/2);
	    }
    	
        //Get the pixel arrays for the lines croping the ellipse to form an arc.
	    xDataArraySa=getLinePixels(phCenter,new jsPoint(x1,y1));
	    xDataArrayEa=getLinePixels(phCenter,new jsPoint(x2,y2));
    	
	    var hexColor=pen.color.getHex();

	    var a=Math.round(width/2);
	    var b=Math.round(height/2);
	    var xc=phCenter.x;
	    var yc=phCenter.y;
    	
	    var x=0;
	    var y=b;
	    var a2=a*a;
	    var b2=b*b;
    	
	    var hexColor=pen.color.getHex();
    	
        //For Inner Ellipse
	    var ai=a-parseInt(pen.width)+1;
	    var bi=b-parseInt(pen.width)+1;
    	
	    var res=getInnerEllipse(phCenter,ai*2,bi*2)
	    var xArray=res[0];
	    var xArrayI=res[1];
	    xArray.pop();
	    xArrayI.pop();

	    var xp,yp;
	    var divX1,divX1pU,divX1pD,divX2,divX2pU,divX2pD,divY1,divY2,saX,eaX,saXp,eaXp,xpU,xpD,ypU,ypD,divX1i,divX2i,divX1pUi,divX1pDi,divX2pUi,divX2pDi;
	    var divWidthOrg,divWidth1,divWidth2,divWidth3,divWidth4,divWidth1p,divWidth2p,divWidth3p,divWidth4p,divHeight,divWidth1i,divWidth2i,divWidth3i,divWidth4i,divWidth1pi,divWidth2pi,divWidth3pi,divWidth4pi;
	    var draw1p,draw2p,draw3p,draw4p;
    	
	    xp=1;
	    yp=y;
    	
	    //Upper and lower portion of the ellipse constutuing the arc
 	    while(b2*x < a2*y)
  	    {     
  		    x++;    
 		    if((b2*x*x + a2*(y-0.5)*(y-0.5) - a2*b2) >=0)  
 			    y--;    
     			
      	    if(x==1 && y!=yp) //Topmost and bottom most points, to be tested
      	    {
      		    divY1=yc+yp-1;
			    divY2=yc-yp;
			    divWidthOrg=1;
			    divWidth1=divWidthOrg;
			    divWidth2=divWidthOrg;
			    divWidth3=divWidthOrg;
			    divWidth4=divWidthOrg;
			    divX1=xc;
    			
			    if(saD>=0 && saD<180 && eaD>=0 && eaD<180)
			    {
				    drawArcSegOut(true);
				    if(eaD<=saD)
				    drawArcSegOut(false);
			    }
			    else if(saD>=180 && saD<360 && eaD>=180 && eaD<=360)
			    {
				    drawArcSegOut(false);
				    if(eaD<=saD)
				    drawArcSegOut(true);
			    }
			    else
			    {
				    drawArcSegOut(true);
				    drawArcSegOut(false);
			    }
      	    }
		    else if(y!=yp)
		    {
			    divY1=yc+yp;
			    divY2=yc-yp;
			    divWidthOrg=2*(x-1)+1;
			    divWidth1=divWidthOrg;
			    divWidth2=divWidthOrg;
			    divWidth3=divWidthOrg;
			    divWidth4=divWidthOrg;
			    divX1=xc-x+1;
    			
			    if(saD>=0 && saD<180 && eaD>=0 && eaD<180)
			    {
				    drawArcSegOut(true);
				    if(eaD<=saD)
				    drawArcSegOut(false);
			    }
			    else if(saD>=180 && saD<360 && eaD>=180 && eaD<=360)
			    {
				    drawArcSegOut(false);
				    if(eaD<=saD)
				    drawArcSegOut(true);
			    }
			    else
			    {
				    drawArcSegOut(true);
				    drawArcSegOut(false);
			    }	
    			
			    yp=y;
			    xp=x;
		    }
    				
    		
		    //Last step in loop
		    if(b2*x >= a2*y)
		    {
			    divY1=yc+yp;
			    divY2=yc-yp;
			    divWidthOrg=2*x+1;
			    divWidth1=divWidthOrg;
			    divWidth2=divWidthOrg;
			    divWidth3=divWidthOrg;
			    divWidth4=divWidthOrg;
			    divX1=xc-x;
    			
			    if(saD>=0 && saD<180 && eaD>=0 && eaD<180)
			    {
				    drawArcSegOut(true);
				    if(eaD<=saD)
				    drawArcSegOut(false);
			    }
			    else if(saD>=180 && saD<360 && eaD>=180 && eaD<=360)
			    {
				    drawArcSegOut(false);
				    if(eaD<=saD)
				    drawArcSegOut(true);
			    }
			    else
			    {
				    drawArcSegOut(true);
				    drawArcSegOut(false);
			    }
		    }
	    }
    	  
        xp=x;
	    yp=y;
	    divHeight=1;

	    //Similar code as in next while loop for first y before the loop. Only values are retrieved and no drawing.
         			
	    divY1=yc+y;
	    divY2=yc-y;
	    divWidthOrg=2*x+1;
	    divWidth1=divWidthOrg;
	    divWidth2=divWidthOrg;
	    divWidth3=divWidthOrg;
	    divWidth4=divWidthOrg;
	    divX1=xc-x;
    	
	    if(saD>=0 && saD<180 && eaD>=0 && eaD<180)
	    {
		    xDataArrayEa.pop();				
		    drawArcSegIn(true,true);
		    if(eaD<=saD)
		    drawArcSegIn(false,true);
	    }				
	    else if(saD>=180 && saD<360 && eaD>=180 && eaD<=360)
	    {
		    xDataArrayEa.pop();				
		    if(y!=0)
			    drawArcSegIn(false,true);
		    if(eaD<=saD)
		        drawArcSegIn(true,true);
	    }
	    else
	    {
		    if(saD>=180 && saD<360)
			    xDataArraySa.pop();
		    else
			    xDataArrayEa.pop();
    		

		    drawArcSegIn(true,true);
		    if(y!=0)
		    {
			    divX1=xc-x;
			    drawArcSegIn(false,true);
		    }
	    }

	    //Left and Right portion of the ellipse ellipse constutuing the arc.
	    while(y!=0)  
	    {
		    y--;   
		    if((b2*(x+0.5)*(x+0.5) + a2*y*y - a2*b2)<=0)   
 			    x++;
     
		    divY1=yc+y;
		    divY2=yc-y;
		    divWidthOrg=2*x+1;
		    divWidth1=divWidthOrg;
		    divWidth2=divWidthOrg;
		    divWidth3=divWidthOrg;
		    divWidth4=divWidthOrg;
		    divX1=xc-x;
			
		    if(saD>=0 && saD<180 && eaD>=0 && eaD<180)
		    {
			    drawArcSegIn(true);
			    if(eaD<=saD)
			    drawArcSegIn(false);
		    }				
		    else if(saD>=180 && saD<360 && eaD>=180 && eaD<=360)
		    {
			    if(y!=0)
				    drawArcSegIn(false);
			    if(eaD<=saD)
				    drawArcSegIn(true);
		    }
		    else
		    {
			    drawArcSegIn(true);
			    if(y!=0)
			    {
				    divX1=xc-x;
				    drawArcSegIn(false);
			    }	
		    }
 	    }

 	    arcDiv.innerHTML=iHtml.join("");
 	    return arcDiv;

        //Internal function: Arc segment for left and right portion of the ellipse constutuing the arc.
	    function drawArcSegIn(isUpperHalf,valueOnly)
	    {
		    var divY;
		    var xDataArray1,xDataArray1;
		    var divWidthFirst=divWidthOrg;
		    var divWidthSecond=divWidthOrg;
		    var drawFirst=false;
		    var drawSecond=false;
		    var xIn;
    		
		    if(isUpperHalf)
		    {
			    var draw1=false; //upper half
			    var draw3=false; //upper half second
			    divY=divY1;
			    xDataArray1=xDataArraySa;
			    xDataArray2=xDataArrayEa;
			    saDvar=saD;
			    eaDvar=eaD;
		    }
		    else
		    {
			    var draw2=false; //lower half
			    var draw4=false; //lower half second
			    divY=divY2;
			    xDataArray2=xDataArraySa;
			    xDataArray1=xDataArrayEa;
			    saDvar=360-eaD;
			    eaDvar=360-saD;
		    }
		    if(eaDvar>saDvar)
		    {
			    if(xDataArray2[divY]!=null && divX1+divWidthOrg>=xDataArray2[divY].xMin && divX1<=xDataArray2[divY].xMin)
			    {
				    eaX=xDataArray2[divY].xMin;
				    if(xDataArray1[divY]!=null && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
				    {
					    saX=xDataArray1[divY].xMax+1;
					    divWidthFirst=saX-eaX;
				    }
				    else
				    {
					    divWidthFirst=divX1+divWidthOrg-eaX;
				    }
				    divX1=eaX;
				    drawFirst=true;
			    }
			    else if(xDataArray1[divY]!=null && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
			    {
				    saX=xDataArray1[divY].xMax+1;
				    divWidthFirst=saX-divX1;
				    drawFirst=true;
			    }
			    else if(eaDvar>90 && saDvar<90)
			    {
				    drawFirst=true;
			    }
		    }
		    else //saDvar>eaDvar
		    {
			    if(xDataArray1[divY]!=null && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
			    {
				    saX=xDataArray1[divY].xMax+1;
				    divWidthFirst=saX-divX1;
				    drawFirst=true;
			    }
			    else if(eaDvar<90 && saDvar<90)
			    {
				    drawFirst=true;
			    }
    	
			    if(xDataArray2[divY]!=null && divX1+divWidthOrg>=xDataArray2[divY].xMin && divX1<=xDataArray2[divY].xMin)
			    {
				    divX2=xDataArray2[divY].xMin;
				    divWidthSecond=divWidthOrg-xDataArray2[divY].xMin+divX1;
				    drawSecond=true;
			    }
			    else if(eaDvar>90 && saDvar>90)
			    {
				    divX2=divX1;
				    divWidthSecond=divWidthOrg;
				    drawSecond=true;
			    }
		    }
    		
		    if(isUpperHalf)
		    {
			    if(drawFirst)
				    draw1=true;
    			
			    if(drawSecond)
				    draw3=true;
    				
			    divWidth1=divWidthFirst;
			    divWidth3=divWidthSecond;	
		    }
		    else
		    {
			    if(drawFirst)
				    draw2=true;
    			
			    if(drawSecond)
				    draw4=true;
    				
			    divWidth2=divWidthFirst;
			    divWidth4=divWidthSecond;	
		    }
    		
		    if(saD>=0 && saD<180 && eaD>=0 && eaD<180 && saD>eaD)
		    {
			    draw2=true;
		    }				
		    else if(saD>=180 && saD<360 && eaD>=180 && eaD<360 && saD>eaD)
		    {
			    draw1=true;
		    }
     
            //Start: Only for drawArc (not in fillArc)        
            if(draw1)
            {
	            if(xArray[divY1-yc]!=null && divX1!=null)
	            {
	                if(xc+xArray[divY1-yc]<=divX1+divWidth1)
	                {
	                    if(divWidth1>divX1+divWidth1-xc-xArray[divY1-yc])
	                    {
	                        divX1i=xc+xArray[divY1-yc];
	                        divWidth1i=divX1+divWidth1-xc-xArray[divY1-yc];
	                    }
	                }
	                else
	                divX1i=null;
    	            
	                if(divX1<=xc-xArray[divY1-yc]+1)
	                {
	                    if(divWidth1>xc-xArray[divY1-yc]-divX1+1)
                            divWidth1=xc-xArray[divY1-yc]-divX1+1;
	                }
	                else if(divWidth1>=divX1+divWidth1-xc-xArray[divY1-yc]+1)
	                divX1=null;
		        }
		    }
            
            if(draw3)
            {
	            if(xArray[divY1-yc]!=null && divX2!=null)
	            {
                    if(xc+xArray[divY1-yc]<=divX2+divWidth3)
	                {
	                    if(divWidth3>divX2+divWidth3-xc-xArray[divY1-yc])
	                    {
	                        divX2i=xc+xArray[divY1-yc];
	                        divWidth3i=divX2+divWidth3-xc-xArray[divY1-yc];
	                    }
	                }
	                else
	                divX2i=null;
    	            
	                if(divX2<=xc-xArray[divY1-yc]+1)
	                {
	                    if(divWidth3>xc-xArray[divY1-yc]-divX2+1)
                            divWidth3=xc-xArray[divY1-yc]-divX2+1;
	                }
	                else if(divWidth3>=divX2+divWidth3-xc-xArray[divY1-yc]+1)
	                divX2=null;
	            }
	        }

            //Lower Half    
            if(draw2)
            {
	            if(xArray[divY1-yc]!=null && divX1!=null)
	            {
	                if(xc+xArray[divY1-yc]<=divX1+divWidth2)
	                {
	                    if(divWidth2>divX1+divWidth2-xc-xArray[divY1-yc])
	                    {
	                        divX1i=xc+xArray[divY1-yc];
	                        divWidth2i=divX1+divWidth2-xc-xArray[divY1-yc];
	                    }
	                }
	                else
	                divX1i=null;
    	            
	                if(divX1<=xc-xArray[divY1-yc]+1)
	                {
	                    if(divWidth2>xc-xArray[divY1-yc]-divX1+1)
                            divWidth2=xc-xArray[divY1-yc]-divX1+1;
	                }
	                else if(divWidth2>=divX1+divWidth2-xc-xArray[divY1-yc]+1)
	                divX1=null;
		        }
		    }
    		
            if(draw4)
            {
	            if(xArray[divY1-yc]!=null && divX2!=null)
	            {
                    if(xc+xArray[divY1-yc]<=divX2+divWidth4)
	                {
	                    if(divWidth4>divX2+divWidth4-xc-xArray[divY1-yc])
	                    {
	                        divX2i=xc+xArray[divY1-yc];
	                        divWidth4i=divX2+divWidth4-xc-xArray[divY1-yc];
	                    }
	                }
	                else
	                divX2i=null;
    	            
	                if(divX2<=xc-xArray[divY1-yc]+1)
	                {
	                    if(divWidth4>xc-xArray[divY1-yc]-divX2+1)
                            divWidth4=xc-xArray[divY1-yc]-divX2+1;
	                }
	                else if(divWidth4>=divX2+divWidth4-xc-xArray[divY1-yc]+1)
	                divX2=null;
	            }
	        }
            //End: Only for drawArc (not in fillArc)
            		
		    if(divX2==null)
		    divX2="";
		    if(divX1==null)
		    divX1="";
    		
    		
		    if(!valueOnly)
		    {
			    if(isUpperHalf)
			    {
				    if(x!=xpU || divX1pU!=divX1 || divX1pUi!=divX1i || divX2pU!=divX2 || divX2pUi!=divX2i || divWidth1!=divWidth1p || divWidth3!=divWidth3p || divWidth1i!=divWidth1pi || divWidth3i!=divWidth3pi)
				    {
					    divHeight=ypU-y;
					    if(draw3p)
					    {
						    if(divX2pU!=null && divX2pU!="")							
	    					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2pU + "px;top:" + (divY1+1) + "px;width:" + divWidth3p + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    	    					
    					    if(divX2pUi!=null && divX2pUi!="")
	    					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2pUi + "px;top:" + (divY1+1) + "px;width:" + divWidth3pi + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					    }

					    if(draw1p)
					    {
						    if(divX1pU!=null && divX1pU!="")
		    		            iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1pU + "px;top:" + (divY1+1) + "px;width:" + divWidth1p + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";

						    if(divX1pUi!=null && divX1pUi!="")
		    		            iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1pUi + "px;top:" + (divY1+1) + "px;width:" + divWidth1pi + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					    }
    					
					    if(draw1p||draw3p)	
					    {
						    divX1pU=divX1;
					        divX1pUi=divX1i;
    					    
						    draw1p=draw1;
						    draw3p=draw3;
    						
						    xpU=x;
						    ypU=y;
    					
						    divWidth1p=divWidth1;
						    divWidth3p=divWidth3;
    						
						    divX2pU=divX2;
						    divX2pUi=divX2i;
    						
						    divWidth1pi=divWidth1i;
						    divWidth3pi=divWidth3i;
					    }
				    }
			    }	
			    else
			    {
				    if(x!=xpD || divX1pD!=divX1 ||divX1pDi!=divX1i || divX2pD!=divX2 || divWidth2!=divWidth2p || divWidth2i!=divWidth2pi || divWidth4!=divWidth4p || divWidth4i!=divWidth4pi)
				    {
					    divHeight=ypD-y;
					    if(draw4p)
					    {
						    if(divX2pD!=null && divX2pD!="")
							    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2pD + "px;top:" + (divY2-divHeight) + "px;width:" + divWidth4p + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    						
						    if(divX2pDi!=null && divX2pDi!="")
							    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2pDi + "px;top:" + (divY2-divHeight) + "px;width:" + divWidth4pi + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					    }
					    if(draw2p)
					    {
						    if(divX1pD!=null && divX1pD!="") 
							    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1pD + "px;top:" + (divY2-divHeight) + "px;width:" + divWidth2p + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
    						
						    if(divX1pDi!=null && divX1pDi!="") 
							    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1pDi + "px;top:" + (divY2-divHeight) + "px;width:" + divWidth2pi + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					    }
					    if(draw2p||draw4p)
					    {
						    divX1pD=divX1;
					        divX1pDi=divX1i;
    					    
						    draw2p=draw2;
						    draw4p=draw4;

						    xpD=x;
						    ypD=y;
    					
						    divWidth2p=divWidth2;
						    divWidth4p=divWidth4;
    						
						    divX2pD=divX2;
						    divX2pDi=divX2i;
    						
						    divWidth2pi=divWidth2i;
						    divWidth4pi=divWidth4i;
					    }
				    }
			    }			
		    }
    		
		    //To get only values; used for first y value before loop.
		    if(valueOnly)
		    {
			    if(isUpperHalf)
			    {
				    draw1p=draw1;
				    draw3p=draw3;
    				
				    if(draw1p)
				    {
				        divX1pU=divX1;
				        divX1pUi=divX1i;
				    }
    				
				    if(draw3p)
				    {
					    divX2pU=divX2;
					    divX2pUi=divX2i;
				    }
    				
				    if(draw1p||draw3p)
				    {
				        ypU=y;
				        xpU=x;
				    }
				    else
				    {
				        ypU=0;
				        xpU=0;
				    }
    				
				    divWidth1p=divWidth1;
				    divWidth3p=divWidth3;
				    divWidth1pi=divWidth1i;
				    divWidth3pi=divWidth3i;

			    }
			    else
			    {
				    draw2p=draw2;
				    draw4p=draw4;

				    if(draw2p)
				    {
					    divX1pD=divX1;
					    divX1pDi=divX1i;
				    }
    				
				    if(draw4p)
				    {
					    divX2pD=divX2;
					    divX2pDi=divX2i;
				    }
    				
				    if(draw2p||draw4p)
				    {
				        ypD=y;
				        xpD=x;
				    }
				    else
				    {
				        ypD=0;
				        xpD=0;
				    }
    				
				    divWidth2p=divWidth2;
				    divWidth4p=divWidth4;
				    divWidth2pi=divWidth2i;
				    divWidth4pi=divWidth4i;
			    }
		    }
    		
		    if(!isUpperHalf)
		    {
			    draw2p=draw2;
			    draw4p=draw4;
		    }
		    else
		    {
			    draw1p=draw1;
			    draw3p=draw3;
		    }
    		
		    if(y==1 && !isUpperHalf)
		    {
			    divHeight=ypD-y+1;
			    if(draw4)
			    {
			        if(divX2!="")
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2 + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth4 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					
			        if(divX2i!=null)
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2i + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth4i + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
			    if(draw2)
			    {
			        if(divX1!="")
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1 + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth2 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					
				    if(divX1i!=null)
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1i + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth2i + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";						
			    }
		    }
		
		    if(y==0 && isUpperHalf)
		    {			
			    divHeight=ypU-y+1;
			    if(draw3)
			    {
			        if(divX2!="")
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2 + "px;top:" + divY1 + "px;width:" + divWidth3 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					
			        if(divX2i!=null)
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2i + "px;top:" + divY1 + "px;width:" + divWidth3i + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }

			    if(draw1)
			    {
                    if(divX1!="")
    			        iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1 + "px;top:" + divY1 + "px;width:" + divWidth1 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
				    
                    if(divX1i!=null)
	    		        iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1i + "px;top:" + divY1 + "px;width:" + divWidth1i + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
		    }		
	    }
    	
	    //Internal function: Arc segment for upper and lower portion of the ellipse constutuing the arc.
	    function drawArcSegOut(isUpperHalf)
	    {
		    var divY;
		    var xDataArray1,xDataArray1;
		    var divWidthFirst=divWidthOrg;
		    var divWidthSecond=divWidthOrg;
		    var drawFirst=false;
		    var drawSecond=false;
    		
		    if(isUpperHalf)
		    {
			    var draw1=false; //upper half
			    var draw3=false; //upper half second
			    divY=divY1;
			    xDataArray1=xDataArraySa;
			    xDataArray2=xDataArrayEa;
			    saDvar=saD;
			    eaDvar=eaD;
		    }
		    else
		    {
			    var draw2=false; //lower half
			    var draw4=false; //lower half second
			    divY=divY2;
			    xDataArray2=xDataArraySa;
			    xDataArray1=xDataArrayEa;
			    saDvar=360-eaD;
			    eaDvar=360-saD;
		    }
		    if(eaDvar>saDvar)
		    {
			    if(xDataArray2[divY]!=null && divX1+divWidthOrg>=xDataArray2[divY].xMin && divX1<=xDataArray2[divY].xMin)
			    {
				    eaX=xDataArray2[divY].xMin;
				    if(xDataArray1[divY] && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
				    {
					    saX=xDataArray1[divY].xMax+1;
					    divWidthFirst=saX-eaX;
				    }
				    else
				    {
					    divWidthFirst=divX1+divWidthOrg-eaX;
				    }
				    divX1=eaX;
				    drawFirst=true;
			    }
			    else if(xDataArray1[divY]!=null && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
			    {
				    saX=xDataArray1[divY].xMax+1;
				    divWidthFirst=saX-divX1;
				    drawFirst=true;
			    }
			    else if(eaDvar>90 && saDvar<90)
			    {
				    drawFirst=true;
			    }
		    }
		    else //saDvar>eaDvar
		    {
			    if(xDataArray1[divY]!=null && divX1+divWidthOrg>=xDataArray1[divY].xMax+1 && divX1<=xDataArray1[divY].xMax+1)
			    {
				    saX=xDataArray1[divY].xMax+1;
				    divWidthFirst=saX-divX1;
				    drawFirst=true;
			    }
			    else if(eaDvar<90 && saDvar<90)
			    {
				    drawFirst=true;
			    }
    	
			    if(xDataArray2[divY]!=null && divX1+divWidthOrg>=xDataArray2[divY].xMin && divX1<=xDataArray2[divY].xMin)
			    {
				    divX2=xDataArray2[divY].xMin;
				    divWidthSecond=divWidthOrg-xDataArray2[divY].xMin+divX1;
				    drawSecond=true;
			    }
			    else if(eaDvar>90 && saDvar>90)
			    {
				    divX2=divX1;
				    divWidthSecond=divWidthOrg;
				    drawSecond=true;
			    }
		    }
    		
		    if(isUpperHalf)
		    {
			    if(drawFirst)
				    draw1=true;
    			
			    if(drawSecond)
				    draw3=true;
    				
			    divWidth1=divWidthFirst;
			    divWidth3=divWidthSecond;	
		    }
		    else
		    {
			    if(drawFirst)
				    draw2=true;
    			
			    if(drawSecond)
				    draw4=true;
    				
			    divWidth2=divWidthFirst;
			    divWidth4=divWidthSecond;	
		    }
    		
		    if(saD>=0 && saD<180 && eaD>=0 && eaD<180 && saD>eaD)
		    {
			    draw2=true;
		    }				
		    else if(saD>=180 && saD<360 && eaD>=180 && eaD<360 && saD>eaD)
		    {
			    draw1=true;
		    }
    		
            //Start: Only for drawArc (not in fillArc)    
            if(draw1)
            {
            
	            if(xArray[divY1-yc] && divX1!=null)
	            {
	                if(xc+xArray[divY1-yc]<=divX1+divWidth1)
	                {
	                    if(divWidth1>divX1+divWidth1-xc-xArray[divY1-yc])
	                    {
	                        divX1i=xc+xArray[divY1-yc];
	                        divWidth1i=divX1+divWidth1-xc-xArray[divY1-yc];
	                    }
	                }
	                else
	                divX1i="X";
    	            
	                if(divX1<xc-xArray[divY1-yc]+1)
	                {
	                    if(divWidth1>xc-xArray[divY1-yc]-divX1+1)
                            divWidth1=xc-xArray[divY1-yc]-divX1+1;
	                }
	                else if(divWidth1>=divX1+divWidth1-xc-xArray[divY1-yc]+1)
	                divX1="X";
		        }
    		    
		    }
            
            if(draw3)
            {
	            if(xArray[divY1-yc] && divX2!=null)
	            {
                    if(xc+xArray[divY1-yc]<=divX2+divWidth3)
	                {
	                    if(divWidth3>divX2+divWidth3-xc-xArray[divY1-yc])
	                    {
	                        divX2i=xc+xArray[divY1-yc];
	                        divWidth3i=divX2+divWidth3-xc-xArray[divY1-yc];
	                    }
	                }
	                else
	                divX2i="X";
    	            
	                if(divX2<=xc-xArray[divY1-yc]+1)
	                {
	                    if(divWidth3>xc-xArray[divY1-yc]-divX2+1)
                            divWidth3=xc-xArray[divY1-yc]-divX2+1;
	                }
	                else if(divWidth3>=divX2+divWidth3-xc-xArray[divY1-yc]+1)
	                divX2="X";
	            }
	        }

            //Lower Half    
            if(draw2)
            {
	            if(xArray[divY1-yc] && divX1!=null)
	            {
	                if(xc+xArray[divY1-yc]<=divX1+divWidth2)
	                {
	                    if(divWidth2>divX1+divWidth2-xc-xArrayI[divY1-yc])
	                    {
	                        divX1i=xc+xArray[divY1-yc];
	                        divWidth2i=divX1+divWidth2-xc-xArray[divY1-yc];
	                    }
	                }
	                else
	                divX1i="X";
    	            
	                if(divX1<=xc-xArray[divY1-yc]+1)
	                {
	                    if(divWidth2>xc-xArray[divY1-yc]-divX1+1)
                            divWidth2=xc-xArray[divY1-yc]-divX1+1;
	                }
	                else if(divWidth2>=divX1+divWidth2-xc-xArray[divY1-yc]+1)
	                divX1="X";
		        }
		    }
    		
            if(draw4)
            {
	            if(xArrayI[divY1-yc] && divX2!=null)
	            {
                    if(xc+xArray[divY1-yc]<=divX2+divWidth4)
	                {
	                    if(divWidth4>divX2+divWidth4-xc-xArray[divY1-yc])
	                    {
	                        divX2i=xc+xArray[divY1-yc];
	                        divWidth4i=divX2+divWidth4-xc-xArray[divY1-yc];
	                    }
	                }
	                else
	                divX2i="X";
    	            
	                if(divX2<=xc-xArray[divY1-yc]+1)
	                {
	                    if(divWidth4>xc-xArray[divY1-yc]-divX2+1)
                            divWidth4=xc-xArray[divY1-yc]-divX2+1;
	                }
	                else if(divWidth4>=divX2+divWidth4-xc-xArray[divY1-yc]+1)
	                divX2="X";
	            }
	        }
            //End: Only for drawArc (not in fillArc)    

		    if(divX2==null)
		    divX2="X";
		    if(divX1==null)
		    divX1="X";
    		
	        if(divX2i==null)
		    divX2i="X";
		    if(divX1i==null)
		    divX1i="X";
    		
		    if(isUpperHalf)
		    {
			    divHeight=1;
			    if(draw3)
			    {
				    if(divX2!="X")
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2 + "px;top:" + divY1 + "px;width:" + divWidth3 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					
				    if(divX2i!="X")
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2i + "px;top:" + divY1 + "px;width:" + divWidth3i + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }

			    if(draw1)
			    {
				    if(divX1!="X")
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1 + "px;top:" + divY1 + "px;width:" + divWidth1 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";

				    if(divX1i!="X")
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1i + "px;top:" + divY1 + "px;width:" + divWidth1i + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
		    }	
		    else
		    {
			    divHeight=1;
			    if(draw4)
			    {
				    if(divX2!="X")
				        iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2 + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth4 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					
				    if(divX2i!="X")
				        iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX2i + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth4i + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
			    if(draw2)
			    {
				    if(divX1!="X") 
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1 + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth2 + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
					
				    if(divX1i!="X") 
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:" + divX1i + "px;top:" + (divY2+1-divHeight) + "px;width:" + divWidth2i + "px;height:" + divHeight + "px;background-color:" + hexColor + "\"></DIV>";
			    }
		    }			
	    }
    }

    //Draw polyline connecting to the specified points.
    function drawPolyline(pen,points)
    {
        //Check arguments for null values
	    if(!pen || !points)
		    return false;

	    var polylineDiv=canvasDiv.appendChild(document.createElement("div"));

	    for(var i=1;i<points.length;i++)
	    {
		    polylineDiv.appendChild(this.drawLine(pen,points[i-1],points[i]));
	    }
	    
	    return polylineDiv;
    }

    //Draw polygon connecting to the specified points.	
    function drawPolygon(pen,points)
    {
        //Check arguments for null values
	    if(!pen || !points)
		    return false;

	    var polylineDiv=canvasDiv.appendChild(document.createElement("div"));

	    var i;	
	    for(i=1;i<points.length;i++)
	    {
		    polylineDiv.appendChild(this.drawLine(pen,points[i-1],points[i]));
	    }
	    polylineDiv.appendChild(this.drawLine(pen,points[i-1],points[0]));
    }

    //Draw polygon filled with specified color and connecting to the specified points.	
	function fillPolygon(color,points)
	{
	    //Check arguments for null values
		if(!color || !points)
		return false;

		var phPoints=new Array();
		var i;
		
		for(i=0;i<points.length;i++)
		{
			phPoints[i]=logicalToPhysicalPoint(points[i]);
		}
		
	    var polygonDiv=canvasDiv.appendChild(document.createElement("div"));
		var iHtml=new Array();
		
		var hexColor=color.getHex(); 

		var xDataArrays=new Array();
		var yMin=phPoints[0].y;
		var yMax=phPoints[0].y;
		
		var newPoints=new Array();
		var l,m,n;
		var pointsCount;

		pointsCount=phPoints.length;
		
		//Remove duplicate consecutive points
		for(i=0;i<phPoints.length;i++)
		{
			if(i!=0)
			    m=i-1;
			else
			    m=pointsCount-1;
				    
			if(!(phPoints[m].x==phPoints[i].x && phPoints[m].y==phPoints[i].y))
			{
		        newPoints[newPoints.length]=phPoints[i];
			}
		}
		phPoints=newPoints;
		newPoints=new Array();
		
		pointsCount=phPoints.length;
		
		//For consecutive horizontal points
		for(i=0;i<phPoints.length;i++)
		{
			if(i!=0)
			    m=i-1;
			else
			    m=pointsCount-1;
			    
			if(i!=pointsCount-1)
			    n=i+1;
			else
			    n=0;
		  	
			if(!(phPoints[i].y==phPoints[n].y && phPoints[i].y==phPoints[m].y))
			{
		        newPoints[newPoints.length]=phPoints[i];
			}
			else
			{
			    //For consecutive horizontal points, just draw horizontal lines
				if(phPoints[m].x<=phPoints[i].x)
				{
					iHtml[iHtml.length]="<DIV style=\"position:absolute;height:1px;overflow:hidden;left:";
					iHtml[iHtml.length]=phPoints[m].x;
					iHtml[iHtml.length]="px;top:";
					iHtml[iHtml.length]=phPoints[i].y;
					iHtml[iHtml.length]="px;width:";
					iHtml[iHtml.length]=phPoints[i].x-phPoints[m].x;
					iHtml[iHtml.length]="px;background-color:";
					iHtml[iHtml.length]=hexColor;
					iHtml[iHtml.length]="\"></DIV>";
				}
				else
				{
					iHtml[iHtml.length]="<DIV style=\"position:absolute;height:1px;overflow:hidden;left:";
					iHtml[iHtml.length]=phPoints[i].x;
					iHtml[iHtml.length]="px;top:";
					iHtml[iHtml.length]=phPoints[i].y;
					iHtml[iHtml.length]="px;width:";
					iHtml[iHtml.length]=phPoints[m].x-phPoints[i].x;
					iHtml[iHtml.length]="px;background-color:";
					iHtml[iHtml.length]=hexColor;
					iHtml[iHtml.length]="\"></DIV>";
				}
			}
		}
		phPoints=newPoints;
		
		for(i=1;i<phPoints.length;i++)
		{
			if(yMin>phPoints[i-1].y)
			{
				yMin=phPoints[i-1].y;
			}
			if(yMax<phPoints[i-1].y)
			{
				yMax=phPoints[i-1].y;
			}
			
            //Get the pixel arrays for the lines connecting polygon vertices.
			xDataArrays[i-1]=getLinePixels(phPoints[i-1],phPoints[i]);
			
			//For verices, keep only one point and not two overlapping points
			if(i<phPoints.length-1)
			{
				if((phPoints[i-1].y<phPoints[i].y && phPoints[i].y<phPoints[i+1].y) || (phPoints[i-1].y>phPoints[i].y && phPoints[i].y>phPoints[i+1].y))
				{
					xDataArrays[i-1][phPoints[i].y]=null;	
				}
			}
			else
			{
				if((phPoints[i-1].y<phPoints[i].y && phPoints[i].y<phPoints[0].y) || (phPoints[i-1].y>phPoints[i].y && phPoints[i].y>phPoints[0].y))
				{
					xDataArrays[i-1][phPoints[i].y]=null;
				}
			}
		}
		
		if(yMin>phPoints[i-1].y)
		{
			yMin=phPoints[i-1].y;
		}
		if(yMax<phPoints[i-1].y)
		{
			yMax=phPoints[i-1].y;
		}
			
		xDataArrays[i-1]=getLinePixels(phPoints[i-1],phPoints[0]);
		if((phPoints[i-1].y<phPoints[0].y && phPoints[0].y<phPoints[1].y) || (phPoints[i-1].y>phPoints[0].y && phPoints[0].y>phPoints[1].y))
		{
			xDataArrays[i-1][phPoints[0].y]=null;
		}
					
		var y;
		var divStyle="";
		var j;
		pointsCount=phPoints.length;
		var xDataArray;
		var xMin,xMax;
		var curX,curY,curWidth;
		
		for(y=yMin;y<=yMax;y++)
		{
			j=0;
			var allXDataArray=new Array();
			
			for(i=0;i<pointsCount;i++)
			{
				xDataArray=xDataArrays[i];
				if(i!=0)
				    m=i-1;
				else
				    m=pointsCount-1;
				    
				if(i!=1 && i!=0)
				    l=i-2;
				else if(i==0)
				    l=pointsCount-2;    
				else
				    l=pointsCount-1;    
				    
				if(i!=pointsCount-1)
				    n=i+1;
				else
				    n=0;
				        
				if((y==phPoints[i].y && y==phPoints[m].y && y<phPoints[l].y && y<phPoints[n].y && xDataArray[y]) || (y==phPoints[i].y && y==phPoints[m].y && y>phPoints[l].y && y>phPoints[n].y && xDataArray[y]))
				{
					allXDataArray[j]= xDataArray[y];
					j++;
				}
				if(xDataArray[y])
				{
					allXDataArray[j]= xDataArray[y];
					j++;
				}
			}
            
            //Sorting based on xMin, uses sortXDataArray function
			allXDataArray.sort(sortXDataArray);
			
			curY=y;
			for(i=0;i<allXDataArray.length;i+=2)
			{
				if(allXDataArray[i+1])
				{
					curX=allXDataArray[i].xMin;
					if(allXDataArray[i+1].xMax>allXDataArray[i].xMax)
						curWidth=allXDataArray[i+1].xMax-allXDataArray[i].xMin+1;
					else
						curWidth=allXDataArray[i].xMax-allXDataArray[i].xMin+1;
				}
				else
				{
					curX=allXDataArray[allXDataArray.length-1].xMin;
					curWidth=allXDataArray[allXDataArray.length-1].xMax-allXDataArray[allXDataArray.length-1].xMin+1;
				}
				
				iHtml[iHtml.length]="<DIV style=\"position:absolute;height:1px;overflow:hidden;left:";
				iHtml[iHtml.length]=curX;
				iHtml[iHtml.length]="px;top:";
				iHtml[iHtml.length]=curY;
				iHtml[iHtml.length]="px;width:";
				iHtml[iHtml.length]=curWidth;
				iHtml[iHtml.length]="px;background-color:";
				iHtml[iHtml.length]=hexColor;
				iHtml[iHtml.length]="\"></DIV>";
			}
		}
		
	 	polygonDiv.innerHTML=iHtml.join("");
	 	return polygonDiv;

        //Internal function: sorting based on xMin
		function sortXDataArray(a,b)
		{
			return a.xMin - b.xMin;
		}
	}

    //Draw cubic bezier curve with specified 4 points
	function drawBezier(pen,points)
	{
		//Check arguments for null values
		if(!pen || !points)
			return false;
		
		var phPoints=new Array();
		var i;
		for(i=0;i<points.length;i++)
		{
			phPoints[i]=logicalToPhysicalPoint(points[i]);
		}

        //If no of points more than 4, take only first four points.
		if(phPoints.length>4)
		{
			phPoints=new Array(phPoints[0],phPoints[1],phPoints[2],phPoints[3]);
		}
		else if(phPoints.length<4)
		{
			return false;
		}
			
		var bezierDiv=canvasDiv.appendChild(document.createElement("div"));
        var iHtml=new Array();
        
		var xMin=phPoints[0].x;
		var xMax=phPoints[0].x;
		
		for(i=1;i<phPoints.length;i++)
		{
			if(xMin>phPoints[i-1].x)
			{
				xMin=phPoints[i-1].x;
			}
			if(xMax<phPoints[i-1].x)
			{
				xMax=phPoints[i-1].x;
			}
		}
		
		var p1x,p2x,p3x,p4x,p1y,p2y,p3y,p4y;
		p1x=phPoints[0].x;
		p1y=phPoints[0].y;

		p2x=phPoints[1].x;
		p2y=phPoints[1].y;

		p3x=phPoints[2].x;
		p3y=phPoints[2].y;

		p4x=phPoints[3].x;
		p4y=phPoints[3].y;

		var x,y,xB,t;
		
		var xl=p1x-1;
		var yl=p1y-1;
		var xp,yp;
		t=0;
		var f=1;
		var penWidth=parseInt(pen.width);
		var hexColor=pen.color.getHex();
		var divWidth=penWidth;
		var divHeight=penWidth;
		xp=p1x;
		yp=p1y;
		var yStart=false;
		var xStart=false;
		var k=1.1;
		//Array to hold all points on the bezier curve
		var curvePoints=new Array();
		
		var y1,y2,x1,x2;
		y1=yp;
		y2=yp;
		x1=xp;
		x2=xp;

		while(t<=1)
		{
			x=0;
			y=0;
			x=(1-t)*(1-t)*(1-t)*p1x + 3*(1-t)*(1-t)*t*p2x + 3*(1-t)*t*t*p3x + t*t*t*p4x;
			y=(1-t)*(1-t)*(1-t)*p1y + 3*(1-t)*(1-t)*t*p2y + 3*(1-t)*t*t*p3y + t*t*t*p4y;
			x=Math.round(x);
			y=Math.round(y);

			if(x!=xl || y!=yl)
			{
				if(x-xl>1 || y-yl>1 || xl-x>1 || yl-y>1)
				{
					t-=f;
					f=f/k;
				}
				else
				{
				    curvePoints[curvePoints.length]=new jsPoint(x,y);  
					xl=x;
					yl=y;
				}
			}
			else
			{
				t-=f;
				f=f*k;
			}
			t+=f;
		}
		
		var isEliminated=new Array();
		for(var i=0;i<curvePoints.length;i++)
		{
		    var next=false;
		    x=curvePoints[i].x;
		    y=curvePoints[i].y;
		    
		    //Eliminate extra points disturbing continuity/smoothness
		    if(i!=0 && i+1<curvePoints.length)
		    {
		    if(Math.abs(curvePoints[i-1].x-curvePoints[i+1].x)==1 && Math.abs(curvePoints[i-1].y-curvePoints[i+1].y)==1)
		        {
		            if(!isEliminated[i-1])
		            {
		                next=true;
		                isEliminated[i]=true;
		            }
		        }
		    }
		    
		    //Divs optimization
		    if(!next)
		    {
	    	    if(y==yp && !xStart)
				{
					yStart=true;
				}
				if(x==xp && !yStart)
				{
					xStart=true;
				}
				
				if(x!=xp && !yStart)
				{
					if(y2==y1)
					{
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
						iHtml[iHtml.length]=xp;
						iHtml[iHtml.length]="px;top:";
						iHtml[iHtml.length]=y1;
						iHtml[iHtml.length]="px;width:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;height:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;background-color:";
						iHtml[iHtml.length]=hexColor;
						iHtml[iHtml.length]="\"></DIV>";
					}	
					else
					{
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
					    iHtml[iHtml.length]=xp;
					    iHtml[iHtml.length]="px;top:";
					    iHtml[iHtml.length]=y1;
					    iHtml[iHtml.length]="px;width:";
					    iHtml[iHtml.length]=penWidth;
					    iHtml[iHtml.length]="px;height:";
					    iHtml[iHtml.length]=y2-y1+penWidth;
					    iHtml[iHtml.length]="px;background-color:";
					    iHtml[iHtml.length]=hexColor;
					    iHtml[iHtml.length]="\"></DIV>";
					}
					
					xp=x;
					yp=y;
					y1=yp;
					y2=yp;
					
					xStart=false;
				}
				
				if(y!=yp && !xStart )
				{
					if(x2==x1)
					{
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
						iHtml[iHtml.length]=x1;
						iHtml[iHtml.length]="px;top:";
						iHtml[iHtml.length]=yp;
						iHtml[iHtml.length]="px;width:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;height:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;background-color:";
						iHtml[iHtml.length]=hexColor;
						iHtml[iHtml.length]="\"></DIV>";
					}	
					else
					{
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
						iHtml[iHtml.length]=x1;
						iHtml[iHtml.length]="px;top:";
						iHtml[iHtml.length]=yp;
						iHtml[iHtml.length]="px;width:";
						iHtml[iHtml.length]=x2-x1+penWidth;
						iHtml[iHtml.length]="px;height:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;background-color:";
						iHtml[iHtml.length]=hexColor;
						iHtml[iHtml.length]="\"></DIV>";
					}	

					xp=x;
					yp=y;
					x1=xp;
					x2=xp;
					
					yStart=false;
				}
				
				if(xStart && !yStart)
				{
					if(y<=y1)
					y1=y;
				
					if(y>y2)
					y2=y;
				}
				else
				{
					y1=y;
					y2=y;
				}
				
				if(yStart && !xStart)
				{
					if(x<=x1)
					x1=x;
				
					if(x>x2)
					x2=x;
				}
				else
				{
					x1=x;
					x2=x;
				}
				
				if(i==curvePoints.length-1) //last step in the loop
				{
					if(!xStart)
					{
						if(x2==x1)
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=x1;
							iHtml[iHtml.length]="px;top:";
							iHtml[iHtml.length]=yp;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;height:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;background-color:";
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
						else
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=x1;
							iHtml[iHtml.length]="px;top:";
							iHtml[iHtml.length]=yp;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=x2-x1+penWidth;
							iHtml[iHtml.length]="px;height:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;background-color:";
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
					}
					if(!yStart)
					{
						if(y2==y1)
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=xp;
							iHtml[iHtml.length]="px;top:";
							iHtml[iHtml.length]=y1;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;height:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;background-color:";
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
						else
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=xp;
							iHtml[iHtml.length]="px;top:";
							iHtml[iHtml.length]=y1;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=x2-x1+penWidth;
							iHtml[iHtml.length]="px;height:";
							iHtml[iHtml.length]=y2-y1+penWidth;
							iHtml[iHtml.length]="px;background-color:";
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
					}
				}
			}		
		}
        
        bezierDiv.innerHTML=iHtml.join("");
        return bezierDiv;
	}

    //Draw general (poly) bezier curve with specified points
	function drawPolyBezier(pen,points)
	{
		//Check arguments for null values
		if(!pen || !points)
			return false;
		
		if(points.length<2)
		{
			return false;
		}
		
		var phPoints=new Array();
		for(var i=0;i<points.length;i++)
		{
			phPoints[i]=logicalToPhysicalPoint(points[i]);
		}
	
	    var bezierDiv=canvasDiv.appendChild(document.createElement("div"));
        var iHtml=new Array();		
			
		var cfx=new Array();
		var cfy=new Array();

		var n=phPoints.length-1;
		for(var i=0;i<=n;i++)
		{
			cfx[i]= phPoints[i].x*fact(n)/(fact(i)*fact(n-i));
			cfy[i]= phPoints[i].y*fact(n)/(fact(i)*fact(n-i));
		}
		
		var xl=phPoints[0].x-1;
		var yl=phPoints[0].y-1;
		var xp,yp;
		t=0;
		var f=1;
		var penWidth=parseInt(pen.width);
		var hexColor=pen.color.getHex();
		var divWidth=penWidth;
		var divHeight=penWidth;
		xp=phPoints[0].x;
		yp=phPoints[0].y;
		var yStart=false;
		var xStart=false;
		var divCount=0;
		var res;
		var fct=0;
		var x;
		var y;
		var j;
		var xd,yd;
		var k=1.1;
		//Array to hold all points on the bezier curve
		var curvePoints=new Array();
		
		var y1,y2,x1,x2;
		y1=yp;
		y2=yp;
		x1=xp;
		x2=xp;
        
		while(t<=1)
		{
			x=0;
			y=0;
            
			for(var i=0;i<=n;i++)
			{
				fct=Math.pow(1-t,n-i)*Math.pow(t,i);
				x= x + cfx[i]*fct;
				y= y + cfy[i]*fct;
			}
			var xd;
			var yd;
			xd=x;
			yd=y;
			x=Math.round(x);
			y=Math.round(y);
			
			if(x!=xl || y!=yl)
			{
			    if(x-xl >1 || y-yl>1 || xl-x>1 || yl-y>1)
				{
				    t-=f;
				    f=f/k;
				}
				else
				{
				    curvePoints[curvePoints.length]=new jsPoint(x,y);  
					xl=x;
					yl=y;
				}
			}
			else
			{
			    t-=f;
				f=f*k;
			}
			t+=f;
	    }
        		
		var isEliminated=new Array();
		for(var i=0;i<curvePoints.length;i++)
		{
		    var next=false;
		    x=curvePoints[i].x;
		    y=curvePoints[i].y;
		    
		    //Eliminate extra points disturbing continuity/smoothness
		    if(i!=0 && i+1<curvePoints.length)
		    {
		        if(Math.abs(curvePoints[i-1].x-curvePoints[i+1].x)==1 && Math.abs(curvePoints[i-1].y-curvePoints[i+1].y)==1)
		        {
		            if(!isEliminated[i-1])
		            {
		                next=true;
		                isEliminated[i]=true;
		            }
		        }
		    }
		    
		    //Divs optimization		    
		    if(!next)
		    {
	    	    if(y==yp && !xStart)
				{
					yStart=true;
				}
				if(x==xp && !yStart)
				{
					xStart=true;
				}
				
				if(x!=xp && !yStart)
				{
					if(y2==y1)
					{
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
						iHtml[iHtml.length]=xp;
						iHtml[iHtml.length]="px;top:";
						iHtml[iHtml.length]=y1;
						iHtml[iHtml.length]="px;width:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;height:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;background-color:";
						iHtml[iHtml.length]=hexColor;
						iHtml[iHtml.length]="\"></DIV>";
					}	
					else
					{
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
					    iHtml[iHtml.length]=xp;
					    iHtml[iHtml.length]="px;top:";
					    iHtml[iHtml.length]=y1;
					    iHtml[iHtml.length]="px;width:";
					    iHtml[iHtml.length]=penWidth;
					    iHtml[iHtml.length]="px;height:";
					    iHtml[iHtml.length]=y2-y1+penWidth;
					    iHtml[iHtml.length]="px;background-color:";
					    iHtml[iHtml.length]=hexColor;
					    iHtml[iHtml.length]="\"></DIV>";
					}    

					xp=x;
					yp=y;
					y1=yp;
					y2=yp;
					
					xStart=false;
				}
				
				if(y!=yp && !xStart )
				{
					if(x2==x1)
					{
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
						iHtml[iHtml.length]=x1;
						iHtml[iHtml.length]="px;top:";
						iHtml[iHtml.length]=yp;
						iHtml[iHtml.length]="px;width:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;height:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;background-color:";
						iHtml[iHtml.length]=hexColor;
						iHtml[iHtml.length]="\"></DIV>";
					}	
					else
					{
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
						iHtml[iHtml.length]=x1;
						iHtml[iHtml.length]="px;top:";
						iHtml[iHtml.length]=yp;
						iHtml[iHtml.length]="px;width:";
						iHtml[iHtml.length]=x2-x1+penWidth;
						iHtml[iHtml.length]="px;height:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;background-color:";
						iHtml[iHtml.length]=hexColor;
						iHtml[iHtml.length]="\"></DIV>";
					}	

					xp=x;
					yp=y;
					x1=xp;
					x2=xp;
					
					yStart=false;
				}
				
				if(xStart && !yStart)
				{
					if(y<=y1)
					y1=y;
				
					if(y>y2)
					y2=y;
				}
				else
				{
					y1=y;
					y2=y;
				}
				
				if(yStart && !xStart)
				{
					if(x<=x1)
					x1=x;
				
					if(x>x2)
					x2=x;
				}
				else
				{
					x1=x;
					x2=x;
				}
				
				if(i==curvePoints.length-1) //last step in the loop
				{
					if(!xStart)
					{
						if(x2==x1)
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=x1;
							iHtml[iHtml.length]="px;top:";
							iHtml[iHtml.length]=yp;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;height:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;background-color:";
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
						else
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=x1;
							iHtml[iHtml.length]="px;top:";
							iHtml[iHtml.length]=yp;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=x2-x1+penWidth;
							iHtml[iHtml.length]="px;height:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;background-color:";
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
					}
					if(!yStart)
					{
						if(y2==y1)
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=xp;
							iHtml[iHtml.length]="px;top:";
							iHtml[iHtml.length]=y1;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;height:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;background-color:";
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
						else
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=xp;
							iHtml[iHtml.length]="px;top:";
							iHtml[iHtml.length]=y1;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=x2-x1+penWidth;
							iHtml[iHtml.length]="px;height:";
							iHtml[iHtml.length]=y2-y1+penWidth;
							iHtml[iHtml.length]="px;background-color:";
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
					}
				}
			}		
		}

        bezierDiv.innerHTML=iHtml.join("");
        return bezierDiv;
        
        //Internal factorial function
		function fact(n)
		{
			var res = 1;
			for(var i=1;i<= n;i++)
        	{
        		res =res * i;
    		}
	    	return res;
		}
	}

    //Draw closed curve passing through the give points with specified tension
    //This method just calls drawCurve method with parameter isClosed=true
    function drawClosedCurve(pen,points,tension) 
	{
		return this.drawCurve(pen,points,tension,true); 
	}

    //Draw curve passing through the give points with specified tension
	function drawCurve(pen,points,tension,isClosed) 
	{
		if(!pen || !points)
			return false;
			
		if(!tension)
		{
			tension=0;
		}
		if(!isClosed)
		{
			isClosed=false;
		}

		var phPoints=new Array();
		for(var i=0;i<points.length;i++)
		{
			phPoints[i]=logicalToPhysicalPoint(points[i]);
		}
		
		var newPoints=new Array();

   		//Remove duplicate consecutive points (ToDo: neccessity of this step is to be confirmed)		
        if(!isClosed || !(phPoints[0].x==phPoints[phPoints.length-1].x && phPoints[0].y==phPoints[phPoints.length-1].y))
        {
            newPoints[newPoints.length]=phPoints[0];  
        }  

		for(var i=1;i<phPoints.length;i++)
		{
		    if(!(phPoints[i].x==phPoints[i-1].x && phPoints[i].y==phPoints[i-1].y))
		    {
		        newPoints[newPoints.length]=phPoints[i];  
		    }   
		}
        phPoints=newPoints;
        
        if(phPoints.length<2)
		{
			return false;
		}
		else if(phPoints.length==2)
		{
		    //For 2 points just draw a line connecting them.
			return this.drawLine(pen,phPoints[0],phPoints[1],"physical");
		}

	    var curveDiv=canvasDiv.appendChild(document.createElement("div"));
        var iHtml=new Array();
        //Array to hold points on the curve
		var curvePoints=new Array();
		
		var n=phPoints.length-1;
		//Call drawCurveSeg method in loop to get points in curvePoints 
		//array for segment (connecting 2 points) of the curve. 
		if(!isClosed) //for open curve
		{	
			for(var i=0;i<=n-1;i++)
			{
				if(i==0)
				{
					drawCurveSeg(new Array(phPoints[0],phPoints[0],phPoints[1],phPoints[2]),tension,curvePoints);
				}
				else if(i==n-1)
				{
					drawCurveSeg(new Array(phPoints[n-2],phPoints[n-1],phPoints[n],phPoints[n]),tension,curvePoints);
				}
				else
				{
					drawCurveSeg(new Array(phPoints[i-1],phPoints[i],phPoints[i+1],phPoints[i+2]),tension,curvePoints);
				}
			}
			//Actual drawing using points data in curvePoints array
			drawAllCurvePoints(pen,curvePoints,iHtml);
		}
		else //for closed curve
		{
			for(var i=0;i<=n-1;i++)
			{
				if(i==0)
				{
					drawCurveSeg(new Array(phPoints[n],phPoints[0],phPoints[1],phPoints[2]),tension,curvePoints);
				}
				else if(i==n-1)
				{
					drawCurveSeg(new Array(phPoints[n-2],phPoints[n-1],phPoints[n],phPoints[0]),tension,curvePoints);
				}
				else
				{
					drawCurveSeg(new Array(phPoints[i-1],phPoints[i],phPoints[i+1],phPoints[i+2]),tension,curvePoints);
				}
			}
			drawCurveSeg(new Array(phPoints[n-1],phPoints[n],phPoints[0],phPoints[1]),tension,curvePoints);
			//Actual drawing using points data in curvePoints array
			drawAllCurvePoints(pen,curvePoints,iHtml);
		}
		        
		curveDiv.innerHTML=iHtml.join("");
		return curveDiv;
	}

    //Private function used by drawCurve method to get curve points 
    //(in curvePoints array) for a single curve segment (connecting 2 points)
	function drawCurveSeg(segPoints,tension,curvePoints)
	{
		var x=0;
		var y=0;
		var xl=segPoints[1].x-1;
		var yl=segPoints[1].y-1;

		var	t=0;
		var f=1;
		var k=1.1;

		var m1x=(1-tension)*(segPoints[2].x-segPoints[0].x)/2;
		var m2x=(1-tension)*(segPoints[3].x-segPoints[1].x)/2;

		var m1y=(1-tension)*(segPoints[2].y-segPoints[0].y)/2;
		var m2y=(1-tension)*(segPoints[3].y-segPoints[1].y)/2;
		
		while(t<=1)
		{
			x=0;
			y=0;

			x= (2*t*t*t-3*t*t+1)*segPoints[1].x + (t*t*t-2*t*t+t)*m1x + (-2*t*t*t+3*t*t)*segPoints[2].x + (t*t*t-t*t)*m2x;
			y= (2*t*t*t-3*t*t+1)*segPoints[1].y + (t*t*t-2*t*t+t)*m1y + (-2*t*t*t+3*t*t)*segPoints[2].y + (t*t*t-t*t)*m2y;
				
			x=Math.round(x);
			y=Math.round(y);

			if(x!=xl || y!=yl)
			{
				if(x-xl>1 || y-yl>1 || xl-x>1 || yl-y>1)
				{
					t-=f;
					f=f/k;
				}
				else
				{
	                curvePoints[curvePoints.length]=new jsPoint(x,y); 
					xl=x;
					yl=y;
	                if(t+f>1)
	                    t=1-f;
				}
			}
			else
			{
				f=f*k;
			}
			t+=f;
		}
	}
		
	//Private function used by drawCurve method to draw actual curve
	//using and processing points data in curvePoints array
	function drawAllCurvePoints(pen,curvePoints,iHtml)
	{
	var xp=curvePoints[0].x;
	var yp=curvePoints[0].y;

	var yStart=false;
	var xStart=false;

	var x1,x2,y1,y2;
	x1=xp;
	x2=xp;
	y1=yp;
	y2=yp;

				
	var penWidth=parseInt(pen.width);
	var hexColor=pen.color.getHex();
	var divWidth=penWidth;
	var divHeight=penWidth;

	var isEliminated=new Array();
	for(var i=0;i<curvePoints.length;i++)
	{
	    var next=false;
	    x=curvePoints[i].x;
	    y=curvePoints[i].y;
	    
	    //Eliminate extra points disturbing continuity/smoothness
	    if(i!=0 && i+1<curvePoints.length)
	    {
		    if(Math.abs(curvePoints[i-1].x-curvePoints[i+1].x)==1 && Math.abs(curvePoints[i-1].y-curvePoints[i+1].y)==1)
	        {
	            if(!isEliminated[i-1])
	            {
	                next=true;
	                isEliminated[i]=true;
	            }
	        }
	    }

        //Divs optimization	    
	    if(!next)
	    {
	    	    if(y==yp && !xStart)
				{
					yStart=true;
				}
				if(x==xp && !yStart)
				{
					xStart=true;
				}
				
				if(x!=xp && !yStart)
				{
					if(y2==y1)
					{
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:"
						iHtml[iHtml.length]=xp;
						iHtml[iHtml.length]="px;top:";
						iHtml[iHtml.length]=y1;
						iHtml[iHtml.length]="px;width:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;height:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;background-color:";
						iHtml[iHtml.length]=hexColor;
						iHtml[iHtml.length]="\"></DIV>";
					}	
					else
					{
					    iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
					    iHtml[iHtml.length]=xp;
					    iHtml[iHtml.length]="px;top:";
					    iHtml[iHtml.length]=y1;
					    iHtml[iHtml.length]="px;width:";
					    iHtml[iHtml.length]=penWidth;
					    iHtml[iHtml.length]="px;height:";
					    iHtml[iHtml.length]=y2-y1+penWidth;
					    iHtml[iHtml.length]="px;background-color:";
					    iHtml[iHtml.length]=hexColor;
					    iHtml[iHtml.length]="\"></DIV>";
					}    

					xp=x;
					yp=y;
					y1=yp;
					y2=yp;
					
					xStart=false;
				}
				
				if(y!=yp && !xStart )
				{
					if(x2==x1)
					{
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
						iHtml[iHtml.length]=x1;
						iHtml[iHtml.length]="px;top:";
						iHtml[iHtml.length]=yp;
						iHtml[iHtml.length]="px;width:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;height:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;background-color:";
						iHtml[iHtml.length]=hexColor;
						iHtml[iHtml.length]="\"></DIV>";
					}	
					else
					{
						iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
						iHtml[iHtml.length]=x1;
						iHtml[iHtml.length]="px;top:";
						iHtml[iHtml.length]=yp;
						iHtml[iHtml.length]="px;width:";
						iHtml[iHtml.length]=x2-x1+penWidth;
						iHtml[iHtml.length]="px;height:";
						iHtml[iHtml.length]=penWidth;
						iHtml[iHtml.length]="px;background-color:";
						iHtml[iHtml.length]=hexColor;
						iHtml[iHtml.length]="\"></DIV>";
					}
					xp=x;
					yp=y;
					x1=xp;
					x2=xp;
					
					yStart=false;
				}
				
				if(xStart && !yStart)
				{
					if(y<=y1)
					y1=y;
				
					if(y>y2)
					y2=y;
				}
				else
				{
					y1=y;
					y2=y;
				}
				
				if(yStart && !xStart)
				{
					if(x<=x1)
					x1=x;
				
					if(x>x2)
					x2=x;
				}
				else
				{
					x1=x;
					x2=x;
				}
				
				if(i==curvePoints.length-1) //last step in the loop
				{
					if(!xStart)
					{
						if(x2==x1)
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=x1;
							iHtml[iHtml.length]="px;top:";
							iHtml[iHtml.length]=yp;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;height:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;background-color:";
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
						else
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:"; 
							iHtml[iHtml.length]=x1; 
							iHtml[iHtml.length]="px;top:"; 
							iHtml[iHtml.length]=yp;
							iHtml[iHtml.length]="px;width:"; 
							iHtml[iHtml.length]=x2-x1+penWidth; 
							iHtml[iHtml.length]="px;height:"; 
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;background-color:"; 
							iHtml[iHtml.length]=hexColor; 
							iHtml[iHtml.length]="\"></DIV>";
						}	
					}
					if(!yStart)
					{
						if(y2==y1)
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=xp;
							iHtml[iHtml.length]="px;top:"; 
							iHtml[iHtml.length]=y1;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;height:"; 
							iHtml[iHtml.length]=penWidth;
							iHtml[iHtml.length]="px;background-color:"; 
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
						else
						{
							iHtml[iHtml.length]="<DIV style=\"position:absolute;overflow:hidden;left:";
							iHtml[iHtml.length]=xp;
							iHtml[iHtml.length]="px;top:";
							iHtml[iHtml.length]=y1;
							iHtml[iHtml.length]="px;width:";
							iHtml[iHtml.length]=x2-x1+penWidth;
							iHtml[iHtml.length]="px;height:"; 
							iHtml[iHtml.length]=y2-y1+penWidth; 
							iHtml[iHtml.length]="px;background-color:";
							iHtml[iHtml.length]=hexColor;
							iHtml[iHtml.length]="\"></DIV>";
						}	
					}
				}
			}	
		}		
	}
		
	//Draw color filled closed curve passing through the specified points 
	//with specified tension
	function fillClosedCurve(color,points,tension)
	{
		if(!color || !points)
			return false;
			
		if(!tension)
		{
			tension=0;
		}
		
		var phPoints=new Array();
		for(var i=0;i<points.length;i++)
		{
			phPoints[i]=logicalToPhysicalPoint(points[i]);
		}
		
		//Remove duplicate consecutive points (ToDo: neccessity of this step is to be confirmed)
		var newPoints=new Array();
	    if(!(phPoints[0].x==phPoints[phPoints.length-1].x && phPoints[0].y==phPoints[phPoints.length-1].y))
	    {
	        newPoints[newPoints.length]=phPoints[0];  
	    }   

		for(var i=1;i<phPoints.length;i++)
		{
		    if(!(phPoints[i].x==phPoints[i-1].x && phPoints[i].y==phPoints[i-1].y))
		    {
		        newPoints[newPoints.length]=phPoints[i];  
		    }   
		}
        phPoints=newPoints;
        
        if(phPoints.length<2)
		{
			return false;
		}
		else if(phPoints.length==2)
		{
		    //For 2 points just draw a line connecting them.
			return this.drawLine(pen,phPoints[0],phPoints[1],"physical");
		}
		        
	    var curveDiv=canvasDiv.appendChild(document.createElement("div"));
		var iHtml=new Array();
		
		var hexColor=color.getHex();
	
 		var xDataArray=new Array();
 		//Array to hold points on the curve
		var curvePoints=new Array();

		var yArray=new Array();
		var yMin;
		var yMax;
		var n=phPoints.length-1;
		var i;	

		//Call drawCurveSeg method in loop to get points in curvePoints 
		//array for segment (connecting 2 points) of the curve. 
		for(var i=0;i<=n-1;i++)
		{
			if(i==0)
			{
				getCurveSegPixels(new Array(phPoints[n],phPoints[0],phPoints[1],phPoints[2]),tension,curvePoints);
			}
			else if(i==n-1)
			{
				getCurveSegPixels(new Array(phPoints[n-2],phPoints[n-1],phPoints[n],phPoints[0]),tension,curvePoints);
			}
			else
			{
				getCurveSegPixels(new Array(phPoints[i-1],phPoints[i],phPoints[i+1],phPoints[i+2]),tension,curvePoints);
			}
		}

		getCurveSegPixels(new Array(phPoints[n-1],phPoints[n],phPoints[0],phPoints[1]),tension,curvePoints);
		
		//getAllCurvePointsArray function processes the points data from curvePoints
		//xDataArray is also populated by the fuction
		var allPointsResult=getAllCurvePointsArray(xDataArray,yArray,curvePoints);
		
		yMin=allPointsResult[0];
		yMax=allPointsResult[1];
		
		var y;
		var k;
		var divStyle="";
		var j;
		var pointsCount=phPoints.length;
		var curX,curY,curWidth;
		
		//Draw the actual filled curve by drawing div rectangles
		for(y=yMin;y<=yMax;y++)
		{
			j=0;
			var allXDataArray=xDataArray[y];
			//Sort allXDataArray based on xMin using sortXDataArray function
			allXDataArray.sort(sortXDataArray);
			
			curY=y;
			
			for(i=0;i<allXDataArray.length;i+=2)
			{
				if(allXDataArray[i+1])
				{
					curX=allXDataArray[i].xMin;
					if(allXDataArray[i+1].xMax>allXDataArray[i].xMax)
						curWidth=allXDataArray[i+1].xMax-allXDataArray[i].xMin+1;
					else
						curWidth=allXDataArray[i].xMax-allXDataArray[i].xMin+1;
				}
				else
				{
					curX=allXDataArray[allXDataArray.length-1].xMin;
					curWidth=allXDataArray[allXDataArray.length-1].xMax-allXDataArray[allXDataArray.length-1].xMin+1;
				}
				
				iHtml[iHtml.length]="<DIV style=\"position:absolute;height:1px;overflow:hidden;left:";
				iHtml[iHtml.length]=curX;
				iHtml[iHtml.length]="px;top:";
				iHtml[iHtml.length]=curY;
				iHtml[iHtml.length]="px;width:";
				iHtml[iHtml.length]=curWidth;
				iHtml[iHtml.length]="px;background-color:";
				iHtml[iHtml.length]=hexColor;
				iHtml[iHtml.length]="\"></DIV>";
			}
		}
		
		curveDiv.innerHTML=iHtml.join("");
		return curveDiv;

        //Internal sort function for allXDataArray array
		function sortXDataArray(a,b)
		{
			return a.xMin - b.xMin;
		}
	}

    //Private function used by fillClosedCurve method to get curve points 
    //(in curvePoints array) for a single curve segment (connecting 2 points)
	function getCurveSegPixels(segPoints,tension,curvePoints)
	{
		var x=0;
		var y=0;
		var xl=segPoints[1].x-1;
		var yl=segPoints[1].y-1;
		var	t=0;
		var f=1;
		var k=1.1;
		var penWidth=1;
		var divWidth=1;
		var divHeight=1;

		var m1x=(1-tension)*(segPoints[2].x-segPoints[0].x)/2;
		var m2x=(1-tension)*(segPoints[3].x-segPoints[1].x)/2;

		var m1y=(1-tension)*(segPoints[2].y-segPoints[0].y)/2;
		var m2y=(1-tension)*(segPoints[3].y-segPoints[1].y)/2;
		
		while(t<=1)
		{
			x=0;
			y=0;

			x= (2*t*t*t-3*t*t+1)*segPoints[1].x + (t*t*t-2*t*t+t)*m1x + (-2*t*t*t+3*t*t)*segPoints[2].x + (t*t*t-t*t)*m2x;
			y= (2*t*t*t-3*t*t+1)*segPoints[1].y + (t*t*t-2*t*t+t)*m1y + (-2*t*t*t+3*t*t)*segPoints[2].y + (t*t*t-t*t)*m2y;
				
			x=Math.round(x);
			y=Math.round(y);
		
			if(x!=xl || y!=yl)
			{
				if(x-xl>1 || y-yl>1 || xl-x>1 || yl-y>1)
				{
					t-=f;
					f=f/k;
				}
				else
				{
	                curvePoints[curvePoints.length]=new jsPoint(x,y);  
					xl=x;
					yl=y;
					if(t+f>1)
	                    t=1-f;
				}
			}
			else
			{
				f=f*k;
			}
			t+=f;
		}
    }
	
	//Private function that processes the points data from curvePoints
	//xDataArray is also populated by the fuction
	function getAllCurvePointsArray(xDataArray,yArray,curvePoints)
	{
		function xData()
		{
			this.xMax=0;
			this.xMin=0;
			this.i=0;
		}
		
		var isEliminated=new Array();
		var yMin;
		var yMax;
		var lastY;
		var firstY;
		var isFirst=true;
		var xDataArrayLast;
		var iLast=-1;
		var yTop1,yTop2;

		for(var i=0;i<curvePoints.length;i++)
		{
		    var next=false;
		    x=curvePoints[i].x;
		    y=curvePoints[i].y;

   		    //Eliminate extra points disturbing continuity/smoothness
		    if(i!=0 && i+1<curvePoints.length)
		    {
    		    if((curvePoints[i-1].x-curvePoints[i+1].x==1 || curvePoints[i+1].x-curvePoints[i-1].x==1) && (curvePoints[i-1].y-curvePoints[i+1].y==1 || curvePoints[i+1].y-curvePoints[i-1].y==1))
		        {
		            if(!isEliminated[i-1])
		            {
		                next=true;
		                isEliminated[i]=true;
		            }
		        }
		    }
		    
		    //Divs optimization
		    if(!next)
		    {
		    	if(!firstY)
		    		firstY=y;
		    		
		    	if(!yMin)
		    		yMin=y;
		    	if(!yMax)
		    		yMax=y;
	
		    	if(y<yMin)
		    		yMin=y;
		    	if(y>yMax)
		    		yMax=y;

				if(!xDataArray[y])
				{
					xDataArray[y]=new Array();
					xDataArray[y][0]=new xData();
					xDataArray[y][0].xMin=x;
					xDataArray[y][0].xMax=x;
					xDataArray[y][0].i=i;
				}
				else
				{
					xDataArrayLast=xDataArray[y][xDataArray[y].length-1];
					if(i-xDataArrayLast.i==1)
					{
						if(xDataArrayLast.xMin>x)
							xDataArrayLast.xMin=x;
						if(xDataArrayLast.xMax<x)
							xDataArrayLast.xMax=x;
							
						xDataArrayLast.i=i;
					}
					else
					{
						xDataArray[y][xDataArray[y].length]=new xData();
						xDataArray[y][xDataArray[y].length-1].xMin=x;
						xDataArray[y][xDataArray[y].length-1].xMax=x;
						xDataArray[y][xDataArray[y].length-1].i=i;
					}	
				}

				yTop1=yArray[yArray.length-1];
				yTop2=yArray[yArray.length-2];	
				
				if(yTop1 && yTop2) 
				{
					if((yTop1 > y && yTop2 < yTop1) || (yTop1 < y && yTop2 > yTop1))
					{
						xDataArray[yTop1][xDataArray[yTop1].length]=xDataArray[yTop1][xDataArray[yTop1].length-1];
					}
				}
				
				if(!yArray[0])
				{
					yArray[0]=y;
				}	
				else if(yArray[yArray.length-1]!=y)
				{
					yArray[yArray.length]=y;
				}
				
				lastY=y;
			}
		}
			
		yTop1=yArray[0];
		yTop2=yTop1;
		var i=1;
		while(yTop1==yTop2)
		{
		    yTop2=yArray[yArray.length-i];	
		    i++;
		}
			
		if(yTop1 && yTop2)
		{
			if((yTop1 > yArray[1] && yTop2 < yTop1) || (yTop1 < yArray[1] && yTop2 > yTop1))
			{
				xDataArray[yTop1][xDataArray[yTop1].length]=xDataArray[yTop1][xDataArray[yTop1].length-1];
			}
		}
		
		if(firstY==lastY)
		{
		    var firstXDataA=xDataArray[firstY][0];
		    var lastXDataA=xDataArray[lastY][xDataArray[lastY].length-1];
    		 	
		    if(lastXDataA.xMax>firstXDataA.xMax)
			    xDataArray[firstY][0].xMax=lastXDataA.xMax;
    			
		    if(lastXDataA.xMin<firstXDataA.xMin)
			    xDataArray[firstY][0].xMin=lastXDataA.xMin;
    			
		    if(xDataArray[lastY].length>1)
			    xDataArray[lastY].pop();
		    else
			    xDataArray.pop();
		}
		
		return new Array(yMin,yMax);	
	}
		
	//Draw text string at specified point with specified color,font,width & alignment	
    function drawText(text,point,font,color,width,align)
    {
		//Check arguments for null values        
    	if(!text || !point)
			return false;
			
		phPoint=logicalToPhysicalPoint(point);
		
		if(width!=null)
   		    width=Math.round(width*scale) + "px";
   		
        var textDiv=canvasDiv.appendChild(document.createElement("div"));

        textDiv.style.position="absolute";
        textDiv.style.left=phPoint.x + "px";
        textDiv.style.top=phPoint.y + "px";
        
        if(color)
	        textDiv.style.color=color.getHex();
                
        //set font
        if(font)
        {
        	if(font.family)
            	textDiv.style.fontFamily=font.family;

	        if(font.weight)
    	        textDiv.style.fontWeight=font.weight;
        
        	if(font.size)
            	textDiv.style.fontSize=font.size;
        
	        if(font.style)
    	        textDiv.style.fontStyle=font.style;
        
        	if(font.variant)
            	textDiv.style.fontVariant=font.variant;
		}
		
        if(width)
            textDiv.style.width=width;

        if(align) 
            textDiv.style.textAlign=align;

        textDiv.innerHTML=text;
        
        return textDiv;
    }
	
	//Draw image at specified point with specified width & height
    function drawImage(url,point,width,height)
    {
        if(!url || !point)
            return false;
             
        phPoint=logicalToPhysicalPoint(point);
      
        if(width!=null)
            width=Math.round(width*scale) + "px";
            
        if(height!=null)   
            height=Math.round(height*scale) + "px";

        var imgDiv=canvasDiv.appendChild(document.createElement("div"));

        imgDiv.style.position="absolute";
        imgDiv.style.left=phPoint.x + "px";
        imgDiv.style.top=phPoint.y + "px";
        //create and set img tag/element
        var img=imgDiv.appendChild(document.createElement("img"));
         
        img.src=url;
        
        if(width!=null)
        {
            img.style.width=width;
            imgDiv.style.width=width;
        }
          
        if(height!=null)
        {
            img.style.height=height;
            imgDiv.style.height=height;
        }
        
        return imgDiv;
    }
    
    //Clear the canvas div element
    function clear()
    {
    	canvasDiv.innerHTML="";
    }
}