function Entite()
{
	// Propriétés
	this.typeCouche=-1;
	this.segsX=new Array();
	this.segsY=new Array();
	this.segsXGeo=new Array();
	this.segsYGeo=new Array();
	this.saisieEnCours=false;
	this.saisieTerminee=false;
	this.selectPts=false;
	this.selectSegs=false;
	this.ptSelectionne=-1;
	this.segSelectionne=-1;

	this.largeurTraits=2;
	this.couleur='#0000FF';
	this.couleurSelection='#FF0000';
	this.demiLargeurCarreSelection=4;


	this.rayonPoints=0; // 0=>croix (ci-dessous); >0=>cercle
	this.demiLargeurCroixPoint=8;
	this.rCercleFinPoly=5;
	
	this.fill = false;
	this.opacity = 100;

	// Méthodes
	this.RAZ=Entite_RAZ;
	this.AjoutPt=Entite_AjoutPt;
	this.TerminerSaisie=Entite_TerminerSaisie;
	this.Dessiner=Entite_Dessiner;
	this.AnnulerDernierPt=Entite_AnnulerDernierPt;
	this.SupprimerPtSelectionne=Entite_SupprimerPtSelectionne;
	this.ScinderSegSelectionne=Entite_ScinderSegSelectionne;
	this.MouseClick=Entite_MouseClick;
	this.MouseMove=Entite_MouseMove;
	this.Deplacer=Entite_Deplacer;
	this.SupprimerSegSelectionne=Entite_SupprimerSegSelectionne;
	this.GetTexte=Entite_GetTexte;
	this.GetLongueur=Entite_GetLongueur;
	this.GetSurface=Entite_GetSurface;
	this.PtInterieur=Entite_PtInterieur;
}

function Entite_RAZ()
{
	this.segsX.length=0;
	this.segsY.length=0;
	this.segsXGeo.length=0;
	this.segsYGeo.length=0;
	this.saisieTerminee=false;
	this.saisieEnCours=false;
	this.selectPts=false;
	this.selectSegs=false;
	this.ptSelectionne=-1;
	this.segSelectionne=-1;
}

function Entite_AjoutPt(xPix, yPix, xGeo, yGeo)
{
	if (this.saisieTerminee)
		this.RAZ();

	var nb=this.segsX.length;
	if ((xPix!=this.segsX[nb-1])||(yPix!=this.segsY[nb-1]))
	{
		this.segsX.push(xPix);
		this.segsY.push(yPix);
		this.segsXGeo.push(xGeo);
		this.segsYGeo.push(yGeo);
	}

	this.saisieEnCours=(this.typeCouche!=COUCHE_PT);
	this.saisieTerminee=!this.saisieEnCours;
}

function Entite_AnnulerDernierPt()
{
	this.segsX.pop();
	this.segsY.pop();
	this.segsXGeo.pop();
	this.segsYGeo.pop();
}

function Entite_SupprimerPtSelectionne()
{
	if (this.ptSelectionne!=-1)
	{
		if ((this.typeCouche==COUCHE_POLY)&&(this.ptSelectionne==this.segsX.length-1))
			this.ptSelectionne=0;
		for (i=this.ptSelectionne; i<this.segsX.length-1; i++)
		{
			this.segsX[i]=this.segsX[i+1];
			this.segsY[i]=this.segsY[i+1];
			this.segsXGeo[i]=this.segsXGeo[i+1];
			this.segsYGeo[i]=this.segsYGeo[i+1];
		}
		this.segsX.pop();
		this.segsY.pop();
		this.segsXGeo.pop();
		this.segsYGeo.pop();
		if (this.typeCouche==COUCHE_POLY)
		{
			this.segsX[this.segsX.length-1]=this.segsX[0];
			this.segsY[this.segsY.length-1]=this.segsY[0];
			this.segsXGeo[this.segsXGeo.length-1]=this.segsXGeo[0];
			this.segsYGeo[this.segsYGeo.length-1]=this.segsYGeo[0];
		}
	}
	this.ptSelectionne=-1;
}

function Entite_SupprimerSegSelectionne()
{
	if (this.segSelectionne==-1)
		return;

	this.ptSelectionne=this.segSelectionne;
	this.SupprimerPtSelectionne();
	this.ptSelectionne=this.segSelectionne;
	this.SupprimerPtSelectionne();

	this.segSelectionne=-1;
}


function Entite_ScinderSegSelectionne()
{
	if (this.segSelectionne!=-1)
	{
		for (i=this.segsX.length; i>this.segSelectionne+1;  i--)
		{
			this.segsX[i]=this.segsX[i-1];
			this.segsY[i]=this.segsY[i-1];
			this.segsXGeo[i]=this.segsXGeo[i-1];
			this.segsYGeo[i]=this.segsYGeo[i-1];
		}
		this.segsX[this.segSelectionne+1]=(this.segsX[this.segSelectionne] + this.segsX[this.segSelectionne+1]) / 2;
		this.segsY[this.segSelectionne+1]=(this.segsY[this.segSelectionne] + this.segsY[this.segSelectionne+1]) / 2;
		this.segsXGeo[this.segSelectionne+1]=(this.segsXGeo[this.segSelectionne] + this.segsXGeo[this.segSelectionne+1]) / 2;
		this.segsYGeo[this.segSelectionne+1]=(this.segsYGeo[this.segSelectionne] + this.segsYGeo[this.segSelectionne+1]) / 2;
	}
}

function Entite_TerminerSaisie()
{
	if (this.typeCouche==COUCHE_POLY)
	{
		this.segsX[this.segsX.length]=this.segsX[0];
		this.segsY[this.segsY.length]=this.segsY[0];
		this.segsXGeo[this.segsXGeo.length]=this.segsXGeo[0];
		this.segsYGeo[this.segsYGeo.length]=this.segsYGeo[0];
	}
	this.saisieTerminee=true;
	this.saisieEnCours=false;
}

function Entite_Dessiner(jg, x, y)
{
	if ((!jg)||(this.segsX.length==0)) return;

	jg.setStroke(this.largeurTraits);
	jg.setColor(this.couleur);

	if (this.typeCouche==COUCHE_PT)
	{		
		if(this.fill)
			jg.fillRect(this.segsX[0]-this.demiLargeurCroixPoint, this.segsY[0]-this.demiLargeurCroixPoint, 20, 20, this.opacity);
		else
		{
			if (this.rayonPoints>0)
				jg.drawEllipse(this.segsX[0]-this.rayonPoints, this.segsY[0]-this.rayonPoints, 2*this.rayonPoints, 2*this.rayonPoints);
			else
			{
				jg.drawLine(this.segsX[0]-this.demiLargeurCroixPoint, this.segsY[0], this.segsX[0]+this.demiLargeurCroixPoint, this.segsY[0], this.opacity);
				jg.drawLine(this.segsX[0], this.segsY[0]-this.demiLargeurCroixPoint, this.segsX[0], this.segsY[0]+this.demiLargeurCroixPoint, this.opacity );
			}
		}

		if (this.ptSelectionne==0)
		{
			jg.setColor(this.couleurSelection);

			jg.drawRect(this.segsX[0] - this.demiLargeurCarreSelection, this.segsY[0] - this.demiLargeurCarreSelection,
				2*this.demiLargeurCarreSelection, 2*this.demiLargeurCarreSelection);
		}

		return;
	}

	if (this.typeCouche==COUCHE_POLY && this.fill)
	{
		jg.fillPolygon(this.segsX,this.segsY, this.opacity);
		return;
	}
	
	if (this.segSelectionne==-1)
	{
		jg.drawPolyline(this.segsX, this.segsY, this.opacity);
		if ((!this.saisieTerminee)&&(x!=-1))
			jg.drawLine(this.segsX[this.segsX.length-1], this.segsY[this.segsY.length-1], x, y, this.opacity);
	}
	else
	{
		for (i=0; i<this.segsX.length-1; i++)
		{
			jg.setColor(i==this.segSelectionne ? this.couleurSelection : this.couleur);
			jg.drawLine(this.segsX[i], this.segsY[i], this.segsX[i+1], this.segsY[i+1], this.opacity);
			/*if(this.opacity!=0)
			{
				jg.drawLine(this.segsX[i], this.segsY[i], this.segsX[i+1], this.segsY[i+1], this.opacity);
				jg.drawLine(this.segsX[i], this.segsY[i], this.segsX[i+1], this.segsY[i+1], this.opacity);
			}*/
		}
	}
	if (this.selectPts)
	{
		for (i=0; i<this.segsX.length; i++)
		{
			jg.setColor(i==this.ptSelectionne ? this.couleurSelection : this.couleur);
			jg.drawRect(this.segsX[i] - this.demiLargeurCarreSelection, this.segsY[i] - this.demiLargeurCarreSelection,
				2*this.demiLargeurCarreSelection, 2*this.demiLargeurCarreSelection);
		}
	}

	if (this.saisieEnCours)
	{
		if (((this.typeCouche==COUCHE_POLY)&&(this.segsX.length>2))||
			((this.typeCouche==COUCHE_LIN)&&(this.segsX.length>0)))
		{
			var ptRefX, ptRefY;
		  if (this.typeCouche==COUCHE_POLY) {
	      ptRefX=this.segsX[0]; ptRefY=this.segsY[0];
			}
			else {
	      ptRefX=this.segsX[this.segsX.length-1]; ptRefY=this.segsY[this.segsX.length-1];
		}
		  var dxFP=x-ptRefX;
		  var dyFP=y-ptRefY;
		  dFP=Math.sqrt(dxFP*dxFP+dyFP*dyFP);
		  if (dFP<this.rCercleFinPoly) {
		    jg.setStroke(1);
		    jg.drawEllipse(ptRefX-this.rCercleFinPoly, ptRefY-this.rCercleFinPoly, 2*this.rCercleFinPoly, 2*this.rCercleFinPoly);
			}
		}
	}
}

function Entite_MouseClick(x, y, xGeo, yGeo)
{
	if (this.saisieEnCours) {
	  var ajout=true;
		if (((this.typeCouche==COUCHE_POLY)&&(this.segsX.length>2))||
			((this.typeCouche==COUCHE_LIN)&&(this.segsX.length>0)))
		{
			var ptRefX, ptRefY;
		  if (this.typeCouche==COUCHE_POLY) {
	      ptRefX=this.segsX[0]; ptRefY=this.segsY[0];
			}
			else {
	      ptRefX=this.segsX[this.segsX.length-1]; ptRefY=this.segsY[this.segsX.length-1];
	  	}
		  var dxFP=x-ptRefX;
		  var dyFP=y-ptRefY;
		  dFP=Math.sqrt(dxFP*dxFP+dyFP*dyFP);
		  if (dFP<this.rCercleFinPoly) {
		    ajout=false;
		    this.TerminerSaisie();
			}
		}
		if (ajout) pts.AjoutPt(x, y, xGeo, yGeo);
		return;
	}

	if (this.selectPts)
	{
		this.ptSelectionne=-1;
		depart=(this.typeCouche==COUCHE_POLY ? 1 : 0); // Si polygone, dernierPt=premierPt, par convention on ne peut prendre que dernierPt
		for (i=depart; i<this.segsX.length; i++)
		{
			var seg_dx=Math.abs(this.segsX[i] - x);
			var seg_dy=Math.abs(this.segsY[i] - y);
			if ((seg_dx <= this.demiLargeurCarreSelection)&&(seg_dy <= this.demiLargeurCarreSelection))
			{
				this.ptSelectionne=i;
				return;
			}
		}
	}
	else if (this.selectSegs)
	{
		var xmin = 0;
		var xmax = 0;
		var ymin = 0;
		var ymax = 0;
		
		this.segSelectionne=-1;
		for (i=0; i<this.segsX.length-1; i++)
		{									
			var x1 = this.segsX[i];
			var x2 = this.segsX[i+1];
			var y1 = this.segsY[i];
			var y2 = this.segsY[i+1];
			
			if (x1==x2)
			{
				if(Math.abs(x1-x)<1.1)
				{
					this.segSelectionne=i;
					return;
				}
			}			
			
			if(x1<x2)
			{
				xmin = x1;
				xmax = x2;
			}			
			if(x1>x2)
			{
				xmin = x2;
				xmax = x1;
			}					
			if(y1<y2)
			{
				ymin = y1;
				ymax = y2;
			}		
			if(y1>y2)
			{
				ymin = y2;
				ymax = y1;
			}

			if(x>=xmin && x<=xmax && y>=ymin && y<=ymax)
			{			
				a=(y2 - y1) / (x2 - x1);
				b=-1;
				c=(-a*x1) + y1;

				d=Math.abs(a*x + b*y + c) / Math.sqrt(a*a + b*b);
				if (d<=this.demiLargeurCarreSelection)
				{
					this.segSelectionne=i;
					return;
				}
			}
		}
	}
}

function Entite_MouseMove(xPix, yPix, xGeo, yGeo)
{
	if (this.ptSelectionne!=-1)
	{
		this.segsX[this.ptSelectionne]=xPix;
		this.segsY[this.ptSelectionne]=yPix;
		this.segsXGeo[this.ptSelectionne]=xGeo;
		this.segsYGeo[this.ptSelectionne]=yGeo;
		if ((this.typeCouche==COUCHE_POLY)&&(this.ptSelectionne==this.segsX.length-1))
		{
			this.segsX[0]=xPix;
			this.segsY[0]=yPix;
			this.segsXGeo[0]=xGeo;
			this.segsYGeo[0]=yGeo;
		}
	}
}

function Entite_Deplacer(dxPix, dyPix, dxGeo, dyGeo)
{
	for (i=0; i<this.segsXGeo.length; i++) {
		this.segsX[i]+=dxPix;
		this.segsY[i]+=dyPix;
		this.segsXGeo[i]+=dxGeo;
		this.segsYGeo[i]+=dyGeo;
	}
}

function Entite_GetTexte()
{
	t="";
	for (i=0; i<this.segsXGeo.length; i++)
	{
		t+=this.segsXGeo[i] + " " + this.segsYGeo[i];
		if (i!=this.segsXGeo.length-1)
			t+=",";
	}
	return t;
}

function Entite_GetLongueur(x, y)
{
	if (this.segsX.length==0)
		return 0;

	var lg=0;
	var i, dx_seg, dy_seg;
	for (i=1; i<this.segsX.length; i++)
	{
		dx_seg=this.segsXGeo[i] - this.segsXGeo[i-1];
		dy_seg=this.segsYGeo[i] - this.segsYGeo[i-1];
		lg+=Math.sqrt((dx_seg*dx_seg) + (dy_seg*dy_seg));
	}
	if (x >= 0)
	{
		dx_seg=(x - this.segsX[this.segsX.length-1])*echellex;
		dy_seg=(y - this.segsY[this.segsY.length-1])*echelley;
		lg+=Math.sqrt((dx_seg*dx_seg) + (dy_seg*dy_seg));
	}

	return lg;
}

function Entite_GetSurface()
{
	if (this.segsX.length<3)
		return 0;

	var surf=0;
	for (var i=0; i<this.segsX.length-1; i++)
		surf+=(this.segsXGeo[i]*this.segsYGeo[i+1]) - (this.segsYGeo[i]*this.segsXGeo[i+1]);
	return Math.abs(surf / 2);
}

function Entite_PtInterieur(x, y)
{
	// comptage du nb d'intersections d'1 demi-droite avec les segments du poly : si impair, point est intérieur
	var i, nb=0;
	var xa, ya, xb, yb;

	if (this.typeCouche==COUCHE_POLY)
	{
		for (i=0; i<this.segsX.length-1; i++)
		{
			if (this.segsX[i]<this.segsX[i+1])
			{
				xa=this.segsX[i];
				ya=this.segsY[i];
				xb=this.segsX[i+1];
				yb=this.segsY[i+1];
			}
			else
			{
				xb=this.segsX[i];
				yb=this.segsY[i];
				xa=this.segsX[i+1];
				ya=this.segsY[i+1];
			}

			if ((xa==x)||(xb==x))
				x+=x/1000000000;

			if ((xa!=xb)&&(xa<x)&&(xb>x)&&((ya-yb)/(xa-xb)*(x-xb)+yb>y))
				nb++;
		}
		return ((nb % 2)!=0);
	}
	else if (this.typeCouche==COUCHE_LIN)
	{
		epaisseur=3;
		tmp=new Entite();
		tmp.typeCouche=COUCHE_POLY;
		for (i=0; i<this.segsX.length-1; i++)
		{
			tmp.RAZ();
			xa=this.segsX[i];
			ya=this.segsY[i];
			xb=this.segsX[i+1];
			yb=this.segsY[i+1];

			var dx_seg=xb-xa;
			var dy_seg=yb-ya;
			l=Math.sqrt(dx_seg*dx_seg + dy_seg*dy_seg);
			if (l>0)
			{
				ux=dx_seg / l;
				uy=dy_seg / l;

				tmp.AjoutPt(xa-uy*epaisseur, ya+ux*epaisseur, 0, 0);
				tmp.AjoutPt(xa+uy*epaisseur, ya-ux*epaisseur, 0, 0);
				tmp.AjoutPt(xb+uy*epaisseur, yb-ux*epaisseur, 0, 0);
				tmp.AjoutPt(xb-uy*epaisseur, yb+ux*epaisseur, 0, 0);
				tmp.TerminerSaisie();
				res=tmp.PtInterieur(x, y);
			}
			else
				res=false;
			if (res) {
				delete tmp;
				return true;
			}
		}
		delete tmp;
	}
	return false;
}
