// Fonctions de dessin -------------

var vmlZoom = 4;
var miterLimit = 0;
var useVml = ie;

function initCanvasOrVML()
{
  if (useVml)
  {
    var styleSheet = (document.styleSheets.length > 0) ? document.styleSheets[0] : document.createStyleSheet();
    styleSheet.addRule('v\\:*', 'behavior:url(#default#VML); display:inline-block; position: absolute; left:0px; top:0px; width:1px; height:1px;');
  }
}

function vmlShape(path,fillcolor,opacity,strokecolor,width)
{
 var shape = document.createElement("v:shape");
 shape.coordsize = vmlZoom+","+vmlZoom;
 shape.path = path;
 
 if (fillcolor&&fillcolor!="transparent")
 {
  if (typeof fillcolor != "string")
  {
   var fill = document.createElement("v:fill");
   fill.type = "gradient";
   fill.color = fillcolor[0];
   fill.color2 = fillcolor[1];
   fill.opacity = opacity;
   fill.opacity2 = opacity;
   
   var angle = (fillcolor[2]?parseInt(fillcolor[2])%360:0);
   var f = Math.round((Math.abs(Math.sin((angle*2)*Math.PI/180)))*15);

   fill.colors = f+"% "+fillcolor[0]+", "+(100-f)+"% "+fillcolor[1];
   fill.angle = angle;
   fill.focus = "100%";
   fill.method = "sigma";
   shape.appendChild(fill);
  } else  
  if (opacity < 1)
  {
   var fill = document.createElement("v:fill");
   fill.color = fillcolor;
   fill.opacity = opacity;
   shape.appendChild(fill);
  } else shape.fillcolor = fillcolor;
 } else shape.filled = 0;
 
 if (strokecolor&&strokecolor!="transparent"&&width>0)
 {
   var stroke = document.createElement("v:stroke");
   stroke.color = strokecolor;
   stroke.weight = width+"px";
   stroke.opacity = opacity;
   if (miterLimit)
   {
    stroke.joinstyle = "miter";
    stroke.miterlimit = miterLimit;
   } else
    stroke.joinstyle = "round";   
   shape.appendChild(stroke);
 } else shape.stroked = 0;
 
 return shape;
}

function canvasGradient(ctx,x1,y1,x2,y2,color)
{
  if (typeof color == "string") return color;
  
  var angle = (color[2]?parseInt(color[2]):0)*Math.PI/180;
  var cx= (x1+x2)/2, cy= (y1+y2)/2, rx=(x2-x1)/2, ry=(y2-y1)/2, r=Math.sqrt(rx*rx+ry*ry), ca=Math.cos(angle), sa=Math.sin(angle);
  var px = rx*sa, py = ry*ca;
  var result = ctx.createLinearGradient(cx-px,cy-py,cx+px,cy+py);
  result.addColorStop(0, color[0]);
  result.addColorStop(1, color[1]);
  return result;
}

function canvasPolygon(coords,fill,opacity,stroke,width,open)
{
 var canvas = document.createElement("canvas");
 canvas.style.opacity = opacity;
 var minx=coords[0],miny=coords[1],maxx=minx,maxy=miny,x,y;
 for (var i=2; i<coords.length; i+=2)
 {
  x=coords[i]; y=coords[i+1];
  if (x<minx) minx=x; else if (x>maxx) maxx=x;
  if (y<miny) miny=y; else if (y>maxy) maxy=y;
 }
 var polybounds = [minx,miny,maxx,maxy];

 if (stroke&&stroke!="transparent")
 {
  minx -= width/2;
  miny -= width/2;
  maxx += width/2;
  maxy += width/2;
 }
 minx = Math.floor(minx);
 maxx = Math.ceil(maxx);
 miny = Math.floor(miny);
 maxy = Math.ceil(maxy);
 canvas.setAttribute("width",maxx-minx+1);
 canvas.setAttribute("height",maxy-miny+1);
 canvas.style.position = "absolute";
 canvas.style.left = minx+"px";
 canvas.style.top = miny+"px";
 var ctx = canvas.getContext("2d");
 ctx.beginPath();
 ctx.moveTo(coords[0]-minx+0.5,coords[1]-miny+0.5);
 for (var i=2; i<coords.length; i+=2)
 {
  ctx.lineTo(coords[i]-minx+0.5,coords[i+1]-miny+0.5);
 }
 if (!open) ctx.closePath();
 if (fill&&fill!="transparent")
 {
  ctx.fillStyle = canvasGradient(ctx,polybounds[0]-minx, polybounds[1]-miny, polybounds[2]-minx, polybounds[3]-miny, fill);
  ctx.fill();
 }
 if (stroke&&stroke!="transparent"&&width>0)
 {
  ctx.strokeStyle = stroke;
  ctx.lineWidth = width;
  if (miterLimit)
  {
   ctx.lineJoin = "miter";
   ctx.miterLimit = miterLimit;
  } else
   ctx.lineJoin = "round";
  ctx.stroke();
 }
 return canvas;
}

function canvasEllipse(x1,y1,x2,y2,fill,opacity,stroke,width)
{
 var canvas = document.createElement("canvas");
 canvas.style.opacity = opacity;  
 var minx = x1, maxx = x2, miny = y1, maxy = y2;
 var polybounds = [minx,miny,maxx,maxy];
 if (stroke&&stroke!="transparent")
 {
  minx -= width/2;
  miny -= width/2;
  maxx += width/2;
  maxy += width/2;
 }
 minx = Math.floor(minx);
 maxx = Math.ceil(maxx);
 miny = Math.floor(miny);
 maxy = Math.ceil(maxy);  
 canvas.setAttribute("width",maxx-minx+1);
 canvas.setAttribute("height",maxy-miny+1);
 canvas.style.position = "absolute";
 canvas.style.left = minx+"px";
 canvas.style.top = miny+"px";
 var ctx = canvas.getContext("2d");
 ctx.beginPath();
 
 var KAPPA = 4 * ((Math.sqrt(2) -1) / 3);
 var rx = (x2-x1+1)/2;
 var ry = (y2-y1+1)/2;

 var cx = rx+x1-minx; 
 var cy = ry+y1-miny;

 ctx.beginPath();
 ctx.moveTo(cx, cy - ry);
 ctx.bezierCurveTo(cx + (KAPPA * rx), cy - ry,  cx + rx, cy - (KAPPA * ry), cx + rx, cy);
 ctx.bezierCurveTo(cx + rx, cy + (KAPPA * ry), cx + (KAPPA * rx), cy + ry, cx, cy + ry);
 ctx.bezierCurveTo(cx - (KAPPA * rx), cy + ry, cx - rx, cy + (KAPPA * ry), cx - rx, cy);
 ctx.bezierCurveTo(cx - rx, cy - (KAPPA * ry), cx - (KAPPA * rx), cy - ry, cx, cy - ry);
 ctx.closePath();

 if (fill&&fill!="transparent")
 {
  ctx.fillStyle = canvasGradient(ctx,polybounds[0]-minx, polybounds[1]-miny, polybounds[2]-minx, polybounds[3]-miny, fill);
  ctx.fill();
 }
 if (stroke&&stroke!="transparent"&&width>0)
 {
  ctx.strokeStyle = stroke;
  ctx.lineWidth = width;
  ctx.lineJoin = "round";
  ctx.stroke();
 }
 return canvas;
}

function Polygon(coords,fill,opacity,stroke,width,open)
{
 if (useVml)
 {
  var path = "m"+Math.round(coords[0]*vmlZoom)+","+Math.round(coords[1]*vmlZoom);
  for (var i=2; i<coords.length; i+=2)
    path += "l"+Math.round(coords[i]*vmlZoom)+","+Math.round(coords[i+1]*vmlZoom);
  if (!open) path += "x";
  return vmlShape(path,fill,opacity,stroke,width);
 } else
 {
  return canvasPolygon(coords,fill,opacity,stroke,width);
 }  
}

function Ellipse(x1,y1,x2,y2,fill,opacity,stroke,width)
{
 if (useVml)
 {
  x1 = Math.round(x1*vmlZoom); y1 = Math.round(y1*vmlZoom);
  x2 = Math.round(x2*vmlZoom); y2 = Math.round(y2*vmlZoom);
  path = "ar"+x1+","+y1+","+x2+","+y2+","+x2+","+Math.round((y1+y2)/2)+","+x2+","+Math.round((y1+y2)/2)+"x";
  return vmlShape(path,fill,opacity,stroke,width);
 } else
 {
  return canvasEllipse(x1,y1,x2,y2,fill,opacity,stroke,width);
 }  
}

function Polyline(coords,stroke,opacity,width)
{
 if (useVml)
 {
  var path = "m"+Math.round(coords[0]*vmlZoom)+","+Math.round(coords[1]*vmlZoom);
  for (var i=2; i<coords.length; i+=2)
     path += "l"+Math.round(coords[i]*vmlZoom)+","+Math.round(coords[i+1]*vmlZoom);
  return vmlShape(path,null,opacity,stroke,width,true);
 } else
 {
  return canvasPolygon(coords,null,opacity,stroke,width,true);
 }  
}

// Elément Polygon ------------------

var ofsOmbre = 4;

function AddPolygon(id,visible,coords,c,opacity,bordersize,bordercolor,shadow,shadowcoords,anchor)
{
 if (!bordersize) { bordersize = 0; bordercolor = "transparent"; }

 var div = cE("div"), st = div.style;
 div.myAnchor = anchor;
 div.id = id;
 st.fontSize = 0;
 st.position = "absolute";
 st.overflow = "hidden";

 if (!visible) st.visibility = "hidden";

 div.myCoords = coords; div.myShadowCoords = shadowcoords; div.myColor = c;
 div.myBorderSize = bordersize; div.myBorderColor = bordercolor;
 div.myShadowOn = !!shadow; div.myOpacity = opacity;

 div.CreatePolygon = function()
 { 
  var minx=div.myCoords[0],miny=div.myCoords[1],maxx=minx,maxy=miny,x,y;
  for (var i=2; i<div.myCoords.length; i+=2)
  {
   x=div.myCoords[i]; y=div.myCoords[i+1];
   if (x<minx) minx=x; else if (x>maxx) maxx=x;
   if (y<miny) miny=y; else if (y>maxy) maxy=y;
  }
  
  if (div.myBorderSize)
  {
   minx -= div.myBorderSize/2;
   miny -= div.myBorderSize/2;
   maxx += div.myBorderSize/2;
   maxy += div.myBorderSize/2;
  }
  
  if (div.myShadowOn)
  for (var i=0; i<div.myShadowCoords.length; i+=2)
  {
   x=div.myShadowCoords[i]; y=div.myShadowCoords[i+1];
   if (x<minx) minx=x; else if (x>maxx) maxx=x;
   if (y<miny) miny=y; else if (y>maxy) maxy=y;
  }
   
  minx = Math.floor(minx);
  maxx = Math.ceil(maxx);
  miny = Math.floor(miny);
  maxy = Math.ceil(maxy); 
  
  var shadowDiv;
  if (!div.myShadowOn) shadowDiv = null; else
  {
    var coords = div.myShadowCoords.slice(0);
    for (var i=0; i<coords.length; i+=2)
    { coords[i] -= minx; coords[i+1] -= miny; }  
    shadowDiv = Polygon(coords,"black",0.3*div.myOpacity/100);
  }
    
  var coords = div.myCoords.slice(0);
  for (var i=0; i<coords.length; i+=2)
  { coords[i] -= minx; coords[i+1] -= miny; }
    
  var polygonDiv = Polygon(coords,div.myColor,div.myOpacity/100,div.myBorderColor,div.myBorderSize);
  
  if (div.myAnchor=="right") minx += support.myDeltaWidth;

  return [polygonDiv,shadowDiv, minx+"px", miny+"px", (maxx-minx+1)+"px", (maxy-miny+1)+"px"];
 }

 var divs = div.CreatePolygon();
 st.left = divs[2];
 st.top = divs[3];
 st.width = divs[4];
 st.height = divs[5];
 if (divs[1]) { div.myShadowDiv = divs[1]; div.appendChild(divs[1]); }
 div.myPolygonDiv = divs[0]; div.appendChild(divs[0]);

 div.ReplacePolygon = function()
 {
  var divs = div.CreatePolygon();
  if (divs[1]) {
   if (div.myShadowDiv) rC(divs[1],div.myShadowDiv); else
     iB(divs[1],div.myEllipseDiv);
   div.myShadowDiv = divs[1]; 
   AddStateHandler(divs[1], div);
  } else
   if (div.myShadowDiv) div.myShadowDiv.style.visibility = "hidden";
  rC(divs[0],div.myPolygonDiv);
  div.myPolygonDiv = divs[0];
  AddStateHandler(divs[0], div);
  
  div.style.left = divs[2];
  div.style.top = divs[3];
  div.style.width = divs[4];
  div.style.height = divs[5];
 }

 div.Move = function(coords,c,opacity,bordersize,bordercolor,shadow,shadowcoords)
 {
  if (!bordersize) { bordersize = 0; bordercolor = "transparent"; }
  
  if ((div.myCoords.toString() != coords.toString()) || (div.myColor.toString() != c.toString()) ||
    (div.myOpacity!= opacity) || (div.myBorderSize != bordersize) || (div.myBorderColor != bordercolor)
     || (div.myShadowOn != !!shadow))
  {
   div.myCoords = coords; div.myShadowCoords = shadowcoords; 
   div.myColor = c; div.myOpacity = opacity;
   div.myBorderSize = bordersize; div.myBorderColor = bordercolor;
   div.myShadowOn = !!shadow;
   
   div.ReplacePolygon();   
  }
  ShowElement(div);
 }

 AddStateHandler(div, div);
 aC(div);
    
 return div;
}

// Elément Ellipse (Texte) --------------

function AddEllipse(id,visible,x,y,x2,y2,c,opacity,bordersize,bordercolor,shadow,anchor)
{
 if (!bordersize) bordersize = 0;

 var div = cE("div"), st = div.style;
 div.myAnchor = anchor;
 if (div.myAnchor=="right") x += support.myDeltaWidth;
 if (div.myAnchor=="right"||div.myAnchor=="fill") x2 += support.myDeltaWidth;

 div.id = id;
 st.fontSize = 0;
 st.position = "absolute";
 st.overflow = "hidden";
 st.left = (x-Math.round(bordersize/2))+"px"; st.top = (y-Math.round(bordersize/2))+"px";
 if (!visible) st.visibility = "hidden";

 div.myX = x; div.myY = y; div.myColor = c;
 div.myBorderSize = bordersize; div.myBorderColor = bordercolor;
 div.myWidth = x2-x+1; div.myHeight = y2-y+1;
 div.myShadowOn = !!shadow; div.myOpacity = opacity;

 div.CreateEllipse = function()
 {
  var cliperror = (ie?0:0);
  var bs = div.myBorderSize;
  var shadowDiv = (!div.myShadowOn?null:Ellipse(ofsOmbre,ofsOmbre,div.myWidth-1+bs+ofsOmbre,div.myHeight-1+bs+ofsOmbre,
   "black",0.3*div.myOpacity/100));
  var ellipseDiv = Ellipse(bs/2,bs/2,div.myWidth-1+bs/2,div.myHeight-1+bs/2,div.myColor,div.myOpacity/100,div.myBorderColor,bs);
  return [ellipseDiv,shadowDiv,(div.myWidth+bs+(div.myShadowOn?ofsOmbre:0))+cliperror+"px",
              (div.myHeight+bs+(div.myShadowOn?ofsOmbre:0))+cliperror+"px"];
 }

 var divs = div.CreateEllipse();
 st.width = divs[2];
 st.height = divs[3];
 if (divs[1]) { div.myShadowDiv = divs[1]; div.appendChild(divs[1]); }
 div.myEllipseDiv = divs[0]; div.appendChild(divs[0]);

 div.ReplaceEllipse = function()
 {
  var divs = div.CreateEllipse();
  if (divs[1]) {
   if (div.myShadowDiv) rC(divs[1],div.myShadowDiv); else
     iB(divs[1],div.myEllipseDiv);
   div.myShadowDiv = divs[1]; 
   AddStateHandler(divs[1], div);
  } else
   if (div.myShadowDiv) div.myShadowDiv.style.visibility = "hidden";
  rC(divs[0],div.myEllipseDiv);
  div.myEllipseDiv = divs[0];
  AddStateHandler(divs[0], div);
  
  div.style.width = divs[2];
  div.style.height = divs[3];
 }

 div.Move = function(x,y,x2,y2,c,opacity,bordersize,bordercolor,shadow)
 {
  if (div.myAnchor=="fill") x += support.myDeltaWidth;
  if (div.myAnchor=="right") x2 += support.myDeltaWidth;
   
  if (!bordersize) bordersize = 0;
  
  if (div.myX != x || div.myBorderSize != bordersize) { div.myX = x; div.style.left = (x - Math.round(bordersize/2))+"px"; }
  if (div.myY != y || div.myBorderSize != bordersize) { div.myY = y; div.style.top = (y - Math.round(bordersize/2))+"px"; }

  var width = x2-x+1, height = y2-y+1;
  if ((div.myWidth != width) || (div.myHeight != height) || (div.myColor.toString() != c.toString()) ||
    (div.myOpacity!= opacity) || (div.myBorderSize != bordersize) || (div.myBorderColor != bordercolor)
     || (div.myShadowOn != !!shadow))
  {
   div.myWidth = width; div.myHeight = height;
   div.myColor = c; div.myOpacity = opacity;
   div.myBorderSize = bordersize; div.myBorderColor = bordercolor;
   div.myShadowOn = !!shadow;
   div.myTextDiv.style.left = Math.round(div.myBorderSize/2)+"px";
   div.myTextDiv.style.top = Math.round(div.myBorderSize/2)+"px";
   div.myTextDiv.style.width = div.myWidth+"px";
   div.myTextDiv.style.height = div.myHeight+"px";
   
   div.ReplaceEllipse();   
  }
  ShowElement(div);
 }

 var textDiv = cE("div"); st = textDiv.style;
 st.position = "absolute";
 st.overflow = "hidden";
 st.left = div.myBorderSize+"px";
 st.top = div.myBorderSize+"px";
 st.width = div.myWidth+"px";
 st.height = div.myHeight+"px";
 textDiv.innerHTML = '<table style="width:100%; height:100%; " cellpadding="0" cellspacing="0"><tr><td><div></div></td></tr></table>';
 div.myTextDiv = textDiv;
 div.appendChild(textDiv);

 AddStateHandler(div, div);
 aC(div);
    
 return div;
}

initCanvasOrVML();

