//
//Force graphs (x - force boundary   * - force infinity)
//
//           |
//      push |
//           |
//  Elastic  +------x-.-------*--> Distance
//           |           ` .
//      pull |              `.
//           |                .
//
//
//           |
//      push |
//           |
//  Pull     +--------.---*------> Distance
//           |   . `
//      pull | .`
//           |.
//
//
//           |`
//      push | `.
//           |   ` .
//  Push     +--------`---*------> Distance
//           |
//      pull |
//           |
//
//
//           |`
//      push | `.
//           |   ` .
//  Spring   +---------x-------*-> Distance
//           |             ` .
//      pull |                `
//           |                 .
//
//
//           |`
//      push | `
//           |  .
//  Atom     +---.--x-------.--*-> Distance
//           |    .   . `
//      pull |     `.`
//           |
//
//
//           |
//      push |...................
//           |
//  Fixed    +-------------------> Distance
//           |
//      pull |
//           |
//
// Fixed forces apply a fixed amount of energy to an object.
// Relative forces apply an amount of energy to an object based on the weight of the target object
//
// (for force target types, the relative forceType is based on the weight of the moving object
//  instead of a target which means that gravity is a relative force in a fixed direction. )
//

//
// newRel=new relationship("object", objectReference, force, ["fixed"|"relative"], ["Elastic"|"Spring"|"Atomic"|"Push"|"Pull"], forceInfinity, forceBoundary );
// newRel=new relationship("direction",forceX,forceY,["fixed"|"relative"]);
//
// (for relative objects, the force is multiplied by the moving object weight)
//

function relationship_addForce(sourceObj)
{
   var calcForceX=0;
   var calcForceY=0;

   if(this.targetType=="direction")
   {
      calcForceX=this.forceX;
      calcForceY=this.forceY;
   }
   if(this.targetType=="random")
   {
      calcForceX=(this.forceX*2*Math.random())-this.forceX;
      calcForceY=(this.forceY*2*Math.random())-this.forceY;
   }
   if(this.targetType=="object")
   {
      var targetX=this.targetObject.getX();
      var targetY=this.targetObject.getY();
      var sourceX=sourceObj.getX();
      var sourceY=sourceObj.getY();
      var xComponent=targetX-sourceX;
      var yComponent=targetY-sourceY;
      var distance=Math.sqrt((xComponent*xComponent)+(yComponent*yComponent));
      var calcForce=0;

      if(this.relationshipType=="elastic")
      {
         if(distance<this.forceBoundary)
         {
            calcForce=0;
         }
         else
         {
            if(distance>this.forceInfinity)
            {
               calcForce=this.force;
            }
            else
            {
               calcForce=(this.force*(distance-this.forceBoundary))/(this.forceInfinity-this.forceBoundary);
            }
         }
      }
      if(this.relationshipType=="spring")
      {
      }
      if(this.relationshipType=="atomic")
      {
         if(distance>this.forceInfinity)
         {
            calcForce=0;
         }
         else
         {
            if(distance>this.forceBoundary)
            {
               calcForce=(this.force*(this.forceInfinity-distance))/(this.forceInfinity-this.forceBoundary);
            }
            else
            {
               calcForce=(((this.force*3)*distance)/this.forceBoundary)-(this.force*2);
            }
         }
      }
      if(this.relationshipType=="push")
      {
         if(distance>this.forceInfinity)
         {
            calcForce=0;
         }
         else
         {
            calcForce=(this.force*(this.forceInfinity-distance))/this.forceInfinity;
            calcForce=0-calcForce;
         }
      }
      if(this.relationshipType=="pull")
      {
         if(distance>this.forceInfinity)
         {
            calcForce=0;
         }
         else
         {
            calcForce=(this.force*(this.forceInfinity-distance))/this.forceInfinity;
         }
      }
      if(this.relationshipType=="constant")
      {
         calcForce=this.force;
      }
      if(this.forceType=="relative")
      {
         calcForce=calcForce*sourceObj.weight;
      }

      if(distance>0)
      {
         calcForceX=(calcForce*xComponent)/distance;
         calcForceY=(calcForce*yComponent)/distance;
      }
   }

   sourceObj.addInertia(calcForceX,calcForceY);
}


function relationship(param0,param1,param2,param3,param4,param5,param6)
{
   this.targetType=param0.toLowerCase(); // object|direction
   this.forceType=""; // fixed|relative
   this.targetX=0.0;
   this.targetY=0.0;
   this.targetObject="";
   this.force=0.0;
   this.forceBoundary=0.0;
   this.forceInfinity=0.0;
   this.forceX=0.0;
   this.forceY=0.0
   this.relationshipType=""; // elastic|pull|spring|push|atom|constant|vibrate

   if((this.targetType=="direction")||(this.targetType=="random"))
   {
      this.forceX=param1;
      this.forceY=param2;
      this.forceType=param3.toLowerCase();
   }
   if(this.targetType=="object")
   {
      this.targetObject=param1;
      this.force=param2;
      this.forceType=param3.toLowerCase();
      this.relationshipType=param4.toLowerCase();
      this.forceInfinity=param5;
      this.forceBoundary=param6;
   }

   this.addForce=relationship_addForce;
}
