/**
 * CLASS vector
 */

var vectorDrawWidth=3;
var vctrSizeable=true;
var vctrRotatable=true;
var coordLocked=true;

var NRed=0;
var NGreen=0;
var NBlue=255;

var wRed=75;
var wGreen=0;
var wBlue=130;

var FRed=0;
var FGreen=160;
var FBlue=0;

var TRed=170;
var TGreen=93;
var TBlue=105;

var TRed=255;
var TGreen=0;
var TBlue=0;

var visibilityThreshold=0.01;

function vector(left,top,newValue,newMaxValue,cntx,sizeable,rotatable,lockedX,lockedY,unit){
	this.cntx=cntx;
    this.left=left;
    this.top=top;
    this.vecRed=0;
    this.vecGreen=0;
    this.vecBlue=0;
    this.visible=false;
    this.value=newValue;
    this.maxValue=newMaxValue;
    this.valueX=0;
    this.valueY=0;
    this.showValue=false;
    this.grabbed=false;
    this.length;
    //this.orientation=0;
    this.showOrientation=false;
    this.orientationPercent=0.3;
    this.drawWidth=1;
    this.showXComponent=false;
    this.showYComponent=false;
    this.showSelectedComponent=false;
    this.selectedComponentOrientation=0;
    this.sizeable=sizeable;
    this.rotatable=rotatable;
    this.lockedX=lockedX;
    this.lockedY=lockedY;
    this.linked=false;
    this.szHover=false;
    this.mvHover=false;
    this.unit=unit;
    
    var arrSize=5;
    var orientation=0;
    
    this.move=function(newLeft,newTop, forceMovement){
      if(this.movable() || this.linked || forceMovement){
          this.left=newLeft;
          this.top=newTop;
      }
    };
    
    this.movable=function(){
      return !(this.lockedX && this.lockedY);  
    };
    
    this.setOrientation=function(newOrientation){
    	orientation=2*Math.PI-newOrientation;	
    };

    this.getOrientation=function(){
    	return 2*Math.PI-orientation;
    };

    this.setValue=function(newVal){
        /*if(newVal>=0){
            orientation=3*Math.PI/2;
        }
        else{
            orientation=Math.PI/2;
        }*/
        this.value=newVal;
    };
    
    this.getVectorEnd=function(){
    	var x2=this.left+this.rotate(this.value,0,orientation).x2;
    	var y2=this.top+this.rotate(this.value,0,orientation).y2;
        return {
            endX: x2,
            endY: y2
        };
    };

    this.render=function(){
    	var X1,Y1,X2,Y2;
    	if (this.visible && this.value>0){
    		this.cntx.lineWidth=1;
        	X1=this.left;
        	Y1=this.top;
        	X2=this.left+this.rotate(this.value,0,orientation).x2;
        	Y2=this.top+this.rotate(this.value,0,orientation).y2;
            //Σχεδίαση συνδετικής γραμμής σε επιλεγμένη κατεύθυνση
        	if(this.showSelectedComponent){
        	    var SelX,SelY,SelXX,SelYY;
        		this.cntx.strokeStyle="rgb(0,0,0)";
        		this.cntx.setLineDash([1,2]);
        		//ΠΡΩΤΗ ('Y') ΣΥΝΙΣΤΩΣΑ
        		//1. Σχεδίαση συνδετικής γραμμης
                this.cntx.lineWidth=1;
        		SelX=this.value*Math.cos(orientation-this.selectedComponentOrientation);
        		SelY=0;
        		SelXX=this.left+SelX*Math.cos(this.selectedComponentOrientation)-SelY*Math.sin(this.selectedComponentOrientation);
        		SelYY=this.top+SelX*Math.sin(this.selectedComponentOrientation)+SelY*Math.cos(this.selectedComponentOrientation);
        		this.cntx.beginPath();
        		this.cntx.moveTo(X2,Y2);
        		this.cntx.lineTo(SelXX,SelYY);
        		this.cntx.stroke();
                //2. Σχεδίαση συνιστώσας
                this.cntx.lineWidth=this.drawWidth;
                cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
                this.cntx.setLineDash([]);
                this.cntx.beginPath();
                this.cntx.moveTo(X1,Y1);
                this.cntx.lineTo(SelXX,SelYY);
                this.cntx.stroke();
                var componentValue=Math.sqrt(Math.pow(SelXX-X1,2)+Math.pow(SelYY-Y1,2));
                if(componentValue>visibilityThreshold){
                    var AngleYcomponent=Math.PI*this.wholeAngle(SelXX-X1,SelYY-Y1)/180;
                    this.renderArrowHead(componentValue,X1,Y1,SelXX,SelYY,AngleYcomponent);
                }
                //3. Εμφάνιση μέτρου
                this.cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
                if(this.showValue && this.valueX!=0){
                    this.cntx.fillText(parseInt(100*Math.abs(this.valueX))/100+" "+this.unit,SelXX+10,SelYY+10);
                }

        		//ΔΕΥΤΕΡΗ ('X') ΣΥΝΙΣΤΩΣΑ
        		//1. Σχεδίαση συνδετικής γραμμης
                this.cntx.lineWidth=1;
        		SelX=0;
        		SelY=this.value*Math.sin(orientation-this.selectedComponentOrientation);
        		SelXX=this.left+SelX*Math.cos(this.selectedComponentOrientation)-SelY*Math.sin(this.selectedComponentOrientation);
        		SelYY=this.top+SelX*Math.sin(this.selectedComponentOrientation)+SelY*Math.cos(this.selectedComponentOrientation);
        		this.cntx.beginPath();
        		this.cntx.moveTo(X2,Y2);
        		this.cntx.lineTo(SelXX,SelYY);
        		this.cntx.stroke();
                //2. Σχεδίαση συνιστώσας
                this.cntx.lineWidth=this.drawWidth;
                cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
                this.cntx.setLineDash([]);
                this.cntx.beginPath();
                this.cntx.moveTo(X1,Y1);
                this.cntx.lineTo(SelXX,SelYY);
                this.cntx.stroke();
                var componentValue=Math.sqrt(Math.pow(SelXX-X1,2)+Math.pow(SelYY-Y1,2));
                if(componentValue>visibilityThreshold){
                    var AngleXcomponent=Math.PI*this.wholeAngle(SelXX-X1,SelYY-Y1)/180;
                    this.renderArrowHead(componentValue,X1,Y1,SelXX,SelYY,AngleXcomponent);
                }
                //3. Εμφάνιση μέτρου
                this.cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
                if(this.showValue && this.valueY!=0){
                    this.cntx.fillText(parseInt(100*Math.abs(this.valueY))/100+" "+this.unit,SelXX+10,SelYY+10);
                }
        	}
        	//Σχεδίαση Y-συνιστώσας
        	if(this.showYComponent && this.valueY!=this.value){
        	    //1. Σχεδίαση συνιστώσας
        	    this.cntx.lineWidth=this.drawWidth;
        		cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
        		this.cntx.setLineDash([]);
        		this.cntx.beginPath();
        		this.cntx.moveTo(X1,Y1);
        		this.cntx.lineTo(X1,Y2);
        		this.cntx.stroke();
        		var AngleYcomponent=Math.PI*this.wholeAngle(0,Y2-Y1)/180;
        		if(Math.abs(Y1-Y2)>visibilityThreshold)this.renderArrowHead(Math.abs(this.value*Math.sin(orientation)),X1,Y1,X1,Y2,AngleYcomponent);

        		//2. Σχεδίαση συνδετικής γραμμης
        		this.cntx.lineWidth=1;
        		this.cntx.beginPath();
        		this.cntx.strokeStyle="rgb(0,0,0)";
        		this.cntx.setLineDash([1,2]);
        		this.cntx.moveTo(X2,Y2);
        		this.cntx.lineTo(X1,Y2);
        		this.cntx.stroke();
                //3. Εμφάνιση μέτρου
                this.cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
                if(this.showValue && this.valueY!=0){
                    this.cntx.fillText(parseInt(100*this.valueY)/100+" "+this.unit,X1+10,Y2);
                }
        	}
        	//Σχεδίαση X-συνιστώσας
        	if(this.showXComponent && this.valueX!=this.value){
        	    //1. Σχεδίαση συνιστώσας
        	    this.cntx.lineWidth=this.drawWidth;
        		cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
        		this.cntx.setLineDash([]);
        		this.cntx.beginPath();
        		this.cntx.moveTo(X1,Y1);
        		this.cntx.lineTo(X2,Y1);
        		this.cntx.stroke();
                var AngleXcomponent=Math.PI*this.wholeAngle(X2-X1,0)/180;
                if(Math.abs(X1-X2)>visibilityThreshold)this.renderArrowHead(Math.abs(this.value*Math.cos(orientation)),X1,Y1,X2,Y1,AngleXcomponent);
        		
        		//2. Σχεδίαση συνδετικής γραμμης
        		this.cntx.lineWidth=1;
        		this.cntx.beginPath();
        		this.cntx.strokeStyle="rgb(0,0,0)";
        		this.cntx.setLineDash([1,2]);
        		this.cntx.moveTo(X2,Y2);
        		this.cntx.lineTo(X2,Y1);
        		this.cntx.stroke();
                //3. Εμφάνιση μέτρου
                this.cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
                if(this.showValue && this.valueX!=0){
                    this.cntx.fillText(parseInt(100*this.valueX)/100+" "+this.unit,X2,Y1+15);
                }
        	}
        	//ΣΧΕΔΙΑΣΗ ΔΙΑΝΥΣΜΑΤΟΣ
    		//1.Σχεδίαση ευθύγραμμου τμήματος
    		this.cntx.lineWidth=this.drawWidth;
        	this.cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
    		this.cntx.setLineDash([]);
    		this.cntx.beginPath();
    		this.cntx.moveTo(X1,Y1);
    		this.cntx.lineTo(X2,Y2);
    		this.cntx.stroke();
    		this.cntx.lineWidth=1;
    		//2.Σχεδίαση αιχμής
    		this.renderArrowHead(this.value,X1,Y1,X2,Y2,orientation);
    		//3. Εμφάνιση μέτρου
        	this.cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
    		if(this.showValue){
    			this.cntx.fillText(parseInt(100*this.value)/100+" "+this.unit,X2+5,Y2+15);
    		}
    		//4. Εμφάνιση κατεύθυνσης
    		if(this.showOrientation){
    			this.cntx.fillStyle="rgba("+this.vecRed+","+this.vecGreen+","+this.vecBlue+",0.3)";
    			this.cntx.beginPath();    			
    			this.cntx.moveTo(this.left,this.top);//Η μετακίνηση χρειάζεται για το ορθό γέμισμα
    			var orientationRadius=this.orientationPercent*this.value;
    			orientationRadius=10;
    			this.cntx.arc(this.left,this.top,orientationRadius,0,orientation,true);
    			this.cntx.fill();
    			this.cntx.stroke();
    		}
    		//5. Εμφάνιση χειριστηρίου μετακίνησης
        	if(this.movable()){
        		var szRed=255;
        		var szGreen=255;
        		var szBlue=255;
                var handleRadius=3;
                if(this.mvHover){
                    szRed=0;
                    szGreen=255;
                    szBlue=0;
                    handleRadius=5;
                }
    			this.cntx.fillStyle="rgba("+szRed+","+szGreen+","+szBlue+",0.8)";
    			this.cntx.beginPath();    			
    			this.cntx.moveTo(this.left,this.top);//Η μετακίνηση χρειάζεται για το ορθό γέμισμα
    			this.cntx.arc(this.left,this.top,handleRadius,0,2*Math.PI,true);
    			this.cntx.fill();
    			this.cntx.stroke();
        	}
            //6. Εμφάνιση χειριστηρίου τροποποίησης μεγέθους
            if(this.sizeable){
                var szRed=255;
                var szGreen=255;
                var szBlue=255;
                var handleRadius=3;
                if(this.szHover){
                    szRed=255;
                    szGreen=255;
                    szBlue=0;
                    handleRadius=5;
                }
                this.cntx.strokeStyle="rgba(0,0,0)";
                this.cntx.fillStyle="rgba("+szRed+","+szGreen+","+szBlue+",0.8)";
                this.cntx.beginPath();              
                this.cntx.moveTo(X2,Y2);//Η μετακίνηση χρειάζεται για το ορθό γέμισμα
                this.cntx.arc(X2,Y2,handleRadius,0,2*Math.PI,true);
                this.cntx.fill();
                this.cntx.stroke();
            }
    	}
    };
    
    this.renderArrowHead=function(vectorVal,X1,Y1,X2,Y2,angle){
        //2.Σχεδίαση αιχμής
        if(this.value!=0 || this.sizeable){
            this.cntx.strokeStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
            var arrLeftX,arrLeftY,arrRightX,arrRightY;
            arrLeftX=this.rotate(vectorVal-arrSize,-arrSize,angle).x2+X1;
            arrLeftY=this.rotate(vectorVal-arrSize,-arrSize,angle).y2+Y1;
            arrRightX=this.rotate(vectorVal-arrSize,arrSize,angle).x2+X1;
            arrRightY=this.rotate(vectorVal-arrSize,arrSize,angle).y2+Y1;

            this.cntx.fillStyle="rgb("+this.vecRed+","+this.vecGreen+","+this.vecBlue+")";
            this.cntx.beginPath();
            this.cntx.moveTo(X2,Y2);
            this.cntx.lineTo(arrLeftX,arrLeftY);
            this.cntx.stroke();
            this.cntx.lineTo(arrRightX,arrRightY);
            this.cntx.stroke();
            this.cntx.closePath();
            this.cntx.fill();
            this.cntx.stroke();
        }
    };

    this.wholeAngle=function(dx,dy){
        var angle;
        if(dx>0) {
            angle=Math.atan(dy/dx);     
        }
        else if(dx==0){
            if(dy>0){
                angle=Math.PI/2;
            }
            else if(dy==0){
                angle=0;
            }
            else{
                angle=3*Math.PI/2;
            }
        }
        else {
            angle=Math.atan(dy/dx)+Math.PI;
        }
        return angle*180/Math.PI;   
    };    

    this.rotate=function(X1,Y1,angle){
    	var X2,Y2;
    	X2=X1*Math.cos(angle)-Y1*Math.sin(angle);
        Y2=X1*Math.sin(angle)+Y1*Math.cos(angle);
        return{
        	x2 : X2,
        	y2 : Y2
        };
    };
}