/// vector2f.cpp
///
/// (c) 2008 by Carsten Busse <carsten.busse@googlemail.com>
///             Bastian Spiegel <bs@tkscript.de> (additional coding)
///     - Distributed under terms of the Lesser GNU General Public License (LGPL).
///       See COPYING and <http://www.gnu.org/licenses/licenses.html#LGPL> for further information.
///
///

#include <math.h>

#include "tkmath_yac.h"
#include "tkmath.h"
#include "vector2f.h"
#include "complexf.h"
#include "matrix2f.h"

#include "ying_Math.h"

// _Vector2f& _Vector2f::operator=(const _Vector2f& obj) {
//    floats[0]=obj.floats[0];
//    floats[1]=obj.floats[1];
//    return *this;
// }

_Vector2f::_Vector2f(void) {
   floats[0] = floats[1] = 0.0f;
}

_Vector2f::~_Vector2f() {
}

sUI _Vector2f::yacArrayGetNumElements(void) {
   return 2;
}

sUI _Vector2f::yacArrayGetMaxElements(void) {
   return 2;
}

sUI _Vector2f::yacArrayGetElementType(void) {
   return YAC_TYPE_FLOAT;
}

sUI _Vector2f::yacArrayGetElementByteSize(void) {
   return sizeof(sF32);
}

void _Vector2f::yacArraySet(YAC_ContextHandle _ctx, sUI _idx, YAC_Value *_val) {
   if(_idx < 2) 
   {
      sF32 v;
      switch(_val->type)
      {
         case YAC_TYPE_VOID:
            v = 0.0f;
            break;
         case YAC_TYPE_INT:
            v = (sF32)_val->value.int_val;
            break;
         case YAC_TYPE_FLOAT:
            v = _val->value.float_val;
            break;
         case YAC_TYPE_OBJECT:
            if(YAC_VALID(_val->value.object_val)) 
            {
               if (!_val->value.object_val->yacScanF32(&v))
               {
                  // Scan failed, silently assign 0.0f
                  v = 0.0f;
               }
            } 
            else 
            {
               // Invalid or <null> object, silently assign 0.0f
               v = 0.0f;
            }
            break;
         default:
            // Should never ever happen!
            Dyac_throw(TypeMismatch, "tkmath::Vector2f::yacArraySet: unknown type");
            v = 0.0f;
            break;
      }
      floats[_idx] = v;
   }
   else 
   {
      static char buf[256];
      sprintf(buf, "tkmath::Vector2f::yacArraySet: Index too high (%d>1)", _idx);
      Dyac_throw(WriteArrayOutOfBounds, buf);
   }
}

void YAC_VCALL _Vector2f::yacArrayGet(YAC_ContextHandle _ctx, sUI _idx, YAC_Value *_val) {
   if(_idx < 2)
   {
      _val->initFloat(floats[_idx]);
   } 
   else
   {
      static char buf[256];
      sprintf(buf, "tkmath::Vector2f::yacArrayGet: Index too high (%d>1)", _idx);
      _val->initFloat(0.0f);
      Dyac_throw(ReadArrayOutOfBounds, buf);
   }
}

void *YAC_VCALL _Vector2f::yacArrayGetPointer(void) {
   return (void*)floats;
}

sSI YAC_VCALL _Vector2f::yacTensorRank(void) {
   return YAC_TENSOR_RANK_VECTOR;
}

void YAC_VCALL _Vector2f::yacSerialize(YAC_Object *_ofs, sUI _rtti) {
   YAC_BEG_SERIALIZE();
   YAC_SERIALIZE_F32(floats[0]);
   YAC_SERIALIZE_F32(floats[1]);
}

sUI YAC_VCALL _Vector2f::yacDeserialize(YAC_Object *_ifs, sUI _rtti) {
   YAC_BEG_DESERIALIZE();
   floats[0] = YAC_DESERIALIZE_F32();
   floats[1] = YAC_DESERIALIZE_F32();
   return 1;
}

void YAC_VCALL _Vector2f::yacOperatorClamp(YAC_Object *_min, YAC_Object *_max) {
   if(YAC_CHK(_min,clid_Vector2f))
   {
      if(YAC_CHK(_max, clid_Vector2f))
      {
         _Vector2f *min = (_Vector2f*) _min;
         _Vector2f *max = (_Vector2f*) _max;
         if(floats[0] < min->floats[0]) 
         {
            floats[0] = min->floats[0];
         }
         else if(floats[0] > max->floats[0])
         {
            floats[0] = max->floats[0];
         }
         if(floats[1] < min->floats[1])
         {
            floats[1] = min->floats[1];
         }
         else if(floats[1] > max->floats[1])
         {
            floats[1] = max->floats[1];
         }
      }
      else 
      {
         Dyac_throw_def(InvalidPointer, "tkmath::Vector2f::yacOperatorClamp: invalid _max object.");
      }
   } 
   else 
   {
      Dyac_throw_def(InvalidPointer, "tkmath::Vector2f::yacOperatorClamp: invalid _min object.");
   }
}

void YAC_VCALL _Vector2f::yacOperatorWrap(YAC_Object *_min, YAC_Object *_max) {
   if(YAC_CHK(_min, clid_Vector2f))
   {
      if(YAC_CHK(_max, clid_Vector2f))
      {
         _Vector2f *min = (_Vector2f*)_min;
         _Vector2f *max = (_Vector2f*)_max;
         if(floats[0] < min->floats[0])
         {
            floats[0] += (max->floats[0] - min->floats[0]);
         }
         else if(floats[0] > max->floats[0])
         {
            floats[0] -= (max->floats[0] - min->floats[0]);
         }
         if(floats[1] < min->floats[1])
         {
            floats[1] += (max->floats[1] - min->floats[1]);
         }
         else if(floats[1] > max->floats[1])
         {
            floats[1] -= (max->floats[1] - min->floats[1]);
         }
      }
      else 
      {
         Dyac_throw_def(InvalidPointer, "tkmath::Vector2f::yacOperatorWrap: invalid _max object.");
      }
   } 
   else 
   {
      Dyac_throw_def(InvalidPointer, "tkmath::Vector2f::yacOperatorWrap: invalid _min object.");
   }
}


void YAC_VCALL _Vector2f::yacOperator(sSI _cmd, YAC_Object *_o, YAC_Value *_r) {
   if(YAC_CHK(_o, clid_Vector2f))
   {
      _Vector2f *o = (_Vector2f*) _o;
      switch (_cmd) 
      {
         case YAC_OP_CEQ:
            YAC_RETI( Dfltequal(floats[0], o->floats[0]) && 
                      Dfltequal(floats[1], o->floats[1]) );
            break;
         case YAC_OP_CNE:
            YAC_RETI( Dfltnotequal(floats[0], o->floats[0]) || 
                      Dfltnotequal(floats[1], o->floats[1]) );
            break;
         case YAC_OP_ASSIGN:
            floats[0] = o->floats[0];
            floats[1] = o->floats[1];
            break;
         case YAC_OP_ADD:
            _add_YAC_RSELF(_o);
            break;
         case YAC_OP_SUB:
            _sub_YAC_RSELF(_o);
            break;
//individual multiplication of elements at this place would only be
//irrtating, so it is currently disabled
/*         case YAC_OP_MUL:
            _mul(_o);
            break;*/
         case YAC_OP_NEG:
            floats[0] = -floats[0];
            floats[1] = -floats[1];
            break;
         case YAC_OP_INIT:
            floats[0] = 0.0f;
            floats[1] = 0.0f;
            break;
         default:
         {
            static char buf[256];
            sprintf(buf, "tkmath::Vector2f::yacOperator unsupported cmd %d", _cmd);
            Dyac_throw_def(TkMathUnsupportedOperator, buf);
         }
         return;
      }
   } 
   else if(YAC_Is_FloatArray(_o)) 
   {
      YAC_FloatArray *o = (YAC_FloatArray*) _o;
      switch (_cmd) 
      {
         case YAC_OP_ASSIGN:
            assignFloatArray(o);
            break;
         default:
         {
            // Construct temporary Vector2f object
            _Vector2f t;
            t.class_ID = clid_Vector2f;
            t.assignFloatArray(o);
            
            // Recursively call yacOperator
            //just handle it like a vector2f
            yacOperator(_cmd, &t, _r);
         }
         break;
      }
   }
   else if(YAC_VALID(_o))
   {
      sF32 val;
      if (_o->yacScanF32(&val)) {
         yacOperatorF32(_cmd, val, _r);
      } else
      // Handle generic array object
      switch(_cmd)
      {
         case YAC_OP_ASSIGN:
            assignGeneric(NULL, _o);
            break;

         default:
         {
/*            // Construct temporary Vector2f object
            _Vector2f t;
            t.class_ID = clid_Vector2f;
            t.assignGeneric(NULL, _o);*/
            
            // Recursively call yacOperator
            YAC_Object::yacOperator(_cmd, _o, _r);
         }
         break;
      }
   }
   else 
   {
      switch (_cmd) {
         case YAC_OP_NEG:
	    floats[0]=-floats[0];
	    floats[1]=-floats[1];
	    break;
	 default:
      // Not a valid Object (e.g. <null>)
            YAC_Object::yacOperator(_cmd,_o,_r);
      }
   }
}

void _Vector2f::yacOperatorI(sSI _cmd, sSI val, YAC_Value *_r) {
   yacOperatorF32(_cmd, (sF32)val, _r);
}

void _Vector2f::yacOperatorF32(sSI _cmd, sF32 val, YAC_Value *_r) {
   switch (_cmd) {
      case YAC_OP_MUL:
         _mulf_YAC_RSELF(val);
	 break;
      case YAC_OP_DIV:
         if (Dfltnonzero(val)) {
	    _mulf_YAC_RSELF(1.0f/val);
	 } else {
	    Dyac_throw_def(TkMathDivisionByZero, "tkmath::Vector2f::yacOperatorF32 OP_DIV Cannot divide by zero");
	 }
         break;
      default:
         char buf[256];
	 sprintf(buf,"tkmath::Vector2f::yacOperatorF32 Operator not supported %d",_cmd);
	 Dyac_throw_def(TkMathUnsupportedOperator,buf);
   }
}

void _Vector2f::assignFloats(sF32 *_fv, sUI _ne) {
   if(_ne <= 2) {
      // Copy as much elements from array as possible but never more than 2
      sUI i;
      for(i=0; i<_ne; i++) {
         floats[i] = _fv[i];
      }
      // Fill the rest with 0.0f
      for(; i<2; i++) {
         floats[i] = 0.0f;
      }
   } else {
      // Copy two elements
      floats[0] = _fv[0];
      floats[1] = _fv[1];
   }
}

void _Vector2f::assignFloatArray(YAC_FloatArray *_fa) {
   assignFloats(_fa->elements, _fa->num_elements);
}

void _Vector2f::assignGeneric(YAC_ContextHandle _ctx, YAC_Object *_o) {
   sUI ne = _o->yacArrayGetNumElements();
   if(ne > 0)
   {
      if(YAC_TYPE_FLOAT == _o->yacArrayGetElementType())
      {
         sF32 *fv = (sF32*) _o->yacArrayGetPointer();
         if(NULL != fv)
         {
            // Copy fast
            assignFloats(fv, ne);
            return;
         }
         else
         {
            // Retrieve individual float elements and assign
            YAC_Value v;
            sUI i;
            for(i=0; (i<2) && (i<ne); i++)
            {
               _o->yacArrayGet(_ctx, i, &v);
               floats[i] = v.value.float_val;
            }
            // Fill the rest with 0.0f
            for(; i<2; i++)
            {
               floats[i] = 0.0f;
            }
         }
      }
      else
      {
         // Retrieve individual elements, typecast to float and assign
         YAC_Value v;
         sUI i;
         for(i=0; (i<2) && (i<ne); i++)
         {
            _o->yacArrayGet(_ctx, i, &v);
            v.typecast(YAC_TYPE_FLOAT);
            floats[i] = v.value.float_val;
            v.unset();
         }
         // Fill the rest with 0.0f
         for(; i<2; i++)
         {
            floats[i] = 0.0f;
         }
      }
   }
   else
   {
      // Other array is empty or no array. Silently assign 0.0f
      floats[0] = floats[1] = 0.0f;
   }
}


//direct access to elements methods
void _Vector2f::_setX(sF32 x) {
   floats[0] = x;
}

void _Vector2f::_setY(sF32 y) {
   floats[1] = y;
}

sF32 _Vector2f::_getX(void) {
   return floats[0];
}

sF32 _Vector2f::_getY(void) {
   return floats[1];
}

//generate string representation
sBool YAC_VCALL _Vector2f::yacToString(YAC_String *s) const {
   s->yacArrayAlloc(128, 0,0,0);
   s->printf("(%g, %g)", floats[0], floats[1]);
   s->fixLength();
   return 1;
}

//create string object and fill with string representation
void _Vector2f::_getString(YAC_Value *_r) const {
   YAC_String *s = (YAC_String*) YAC_NEW_CORE_POOLED(YAC_CLID_STRING128);
   yacToString(s);
   YAC_RETS(s, 1);
}

void _Vector2f::_add_YAC_RSELF(YAC_Object *_o) {
   if(YAC_CHK(_o, clid_Vector2f)) 
   {
//add two vector2f
      _Vector2f *o = (_Vector2f*) _o;
      floats[0] += o->floats[0];
      floats[1] += o->floats[1];
   } else {
      Dyac_throw_def(NativeClassTypeMismatch,"tkmath::Vector2f::add_SELF: invalid Vector2f object");
   }
// i decided against this
/*   else 
   {
      // Add generic Object
      YAC_Value r;
      yacOperator(YAC_OP_ADD, _o, &r);
   }*/
}

void _Vector2f::_add_YAC_RVAL(YAC_Object *_o, YAC_Value *_r) {

   if(YAC_CHK(_o, clid_Vector2f)) 
   {
//add two vector2f
      _Vector2f *o = (_Vector2f*) _o;
      _Vector2f *r = YAC_NEW_POOLED(Vector2f);
      r->floats[0] = floats[0] + o->floats[0];
      r->floats[1] = floats[1] + o->floats[1];
      _r->initObject(r,1);
   } else {
      Dyac_throw_def(NativeClassTypeMismatch,"tkmath::Vector2f::add_VAL: invalid Vector2f object");
   }
// i decided against this
/*   else 
   {
      // Add generic Object
      YAC_Value r;
      yacOperator(YAC_OP_ADD, _o, &r);
   }*/
}

void _Vector2f::_add_YAC_RARG(YAC_Object *_o, YAC_Object *_r) {
   if(YAC_CHK(_o, clid_Vector2f)&&YAC_CHK(_r, clid_Vector2f)) 
   {
//add two vector2f
      _Vector2f *o = (_Vector2f*) _o;
      _Vector2f *r = (_Vector2f*) _r;
      r->floats[0] = floats[0] + o->floats[0];
      r->floats[1] = floats[1] + o->floats[1];
   } else {
      Dyac_throw_def(NativeClassTypeMismatch,"tkmath::Vector2f::add_ARG: invalid Vector2f object");
   }
// i decided against this
/*   else 
   {
      // Add generic Object
      YAC_Value r;
      yacOperator(YAC_OP_ADD, _o, &r);
   }*/
}

void _Vector2f::_sub_YAC_RSELF(YAC_Object *_o) {
   if(YAC_CHK(_o, clid_Vector2f)) 
   {
//sub two vector2f
      _Vector2f *o = (_Vector2f*) _o;
      floats[0] -= o->floats[0];
      floats[1] -= o->floats[1];
   } else {
      Dyac_throw_def(NativeClassTypeMismatch,"tkmath::Vector2f::sub_SELF Invalid Vector2f object");
   }

/*   else 
   {
      // Subtract generic Object
      YAC_Value r;
      yacOperator(YAC_OP_SUB, _o, &r);
   }*/
}

void _Vector2f::_sub_YAC_RVAL(YAC_Object *_o, YAC_Value *_r) {
   if(YAC_CHK(_o, clid_Vector2f)) 
   {
//sub two vector2f
      _Vector2f *o = (_Vector2f*) _o;
      _Vector2f *r = YAC_NEW_POOLED(Vector2f);
      r->floats[0] = floats[0] - o->floats[0];
      r->floats[1] = floats[1] - o->floats[1];
      _r->initObject(r,1);

   } else {
      Dyac_throw_def(NativeClassTypeMismatch,"tkmath::Vector2f::sub_VAL invalid Vector2f object");
   }

/*   else 
   {
      // Subtract generic Object
      YAC_Value r;
      yacOperator(YAC_OP_SUB, _o, &r);
   }*/
}

void _Vector2f::_sub_YAC_RARG(YAC_Object *_o, YAC_Object *_r) {
   if(YAC_CHK(_o, clid_Vector2f)&&YAC_CHK(_r, clid_Vector2f)) 
   {
//sub two vector2f
      _Vector2f *o = (_Vector2f*) _o;
      _Vector2f *r = (_Vector2f*) _r;
      r->floats[0] = floats[0] - o->floats[0];
      r->floats[1] = floats[1] - o->floats[1];
   } else {
      Dyac_throw_def(NativeClassTypeMismatch,"tkmath::Vector2f::sub: invalid Vector2f object");
   }

/*   else 
   {
      // Subtract generic Object
      YAC_Value r;
      yacOperator(YAC_OP_SUB, _o, &r);
   }*/
}

sF32 _Vector2f::_dot(YAC_Object *_o) {
   if (YAC_CHK(_o,clid_Vector2f)) 
   {
      _Vector2f *o = (_Vector2f*)_o;
      return (floats[0] * o->floats[0] + floats[1] * o->floats[1]);
   } else {
      Dyac_throw_def(NativeClassTypeMismatch, "tkmath::Vector2f::dot: invalid Vector2f object");
      return 0.0f;
   }
//there is no such thing like a dot product from a vector2f with a generic object!
/*   else 
   {
      // Dot product with generic Object
      _Vector2f t;
      t.assignGeneric(NULL, _o);
      return (floats[0] * t.floats[0] + floats[1] * t.floats[1]);
   }*/

}

void _Vector2f::_tensor_YAC_RVAL(YAC_Object *_o, YAC_Value *_r) {
   if(YAC_CHK(_o, clid_Vector2f))
   {
      _Matrix2f *m = YAC_NEW_POOLED(Matrix2f);
      _Vector2f *o=(_Vector2f*)_o;
      o = (_Vector2f*) _o;
      m->floats[0] = floats[0] * o->floats[0];
      m->floats[1] = floats[0] * o->floats[1];
      m->floats[2] = floats[1] * o->floats[0];
      m->floats[3] = floats[1] * o->floats[1];
      _r->initObject(m,1);
   }
   else 
   {
      Dyac_throw_def(NativeClassTypeMismatch, "tkmath::Vector2f::tensor_VAL Invalid Vector2f object");
   }
}

void _Vector2f::_tensor_YAC_RARG(YAC_Object *_o, YAC_Object *_m) {
   if(YAC_CHK(_m, clid_Matrix2f))
   {
      _Vector2f t;
      _Matrix2f *m = (_Matrix2f*) _m;
      _Vector2f *o;
      if(YAC_CHK(_o, clid_Vector2f)) 
      {
         o = (_Vector2f*) _o;
         m->floats[0] = floats[0] * o->floats[0];
         m->floats[1] = floats[0] * o->floats[1];
         m->floats[2] = floats[1] * o->floats[0];
         m->floats[3] = floats[1] * o->floats[1];
      
/*      else
      {
         t.assignGeneric(NULL, _o);
         o = &t;
      }*/
      } else {
         Dyac_throw_def(NativeClassTypeMismatch, "tkmath::Vector2f::tensor_ARG Invalid Vector2f object");
      }

   }
   else 
   {
      Dyac_throw_def(NativeClassTypeMismatch, "tkmath::Vector2f::tensor_ARG: Invalid Matrix2f return object");
   }
}

//multiply vector2f with scalar
void _Vector2f::_mulf_YAC_RSELF(sF32 s) {
   floats[0] *= s;
   floats[1] *= s;
}

void _Vector2f::_mulf_YAC_RVAL(sF32 s, YAC_Value *_r) {
   _Vector2f *r=YAC_NEW_POOLED(Vector2f);
   r->floats[0] = floats[0] * s;
   r->floats[1] = floats[1] * s;
   _r->initObject(r,1);
}

void _Vector2f::_mulf_YAC_RARG(sF32 s, YAC_Object *_r) {
   if (YAC_CHK(_r, clid_Vector2f)) {
      _Vector2f *r=(_Vector2f*)_r;
      r->floats[0] = floats[0] * s;
      r->floats[1] = floats[1] * s;
   } else {
      Dyac_throw_def(NativeClassTypeMismatch, "tkmath::Vector2f::mulf_ARG Return object not of type Vector2f");
   }
}

//multiply both elements of each vector2f
void _Vector2f::_mul_YAC_RSELF(YAC_Object *_o) {
   if(YAC_CHK(_o, clid_Vector2f)) 
   {
      _Vector2f *o = (_Vector2f*) _o;
      floats[0] *= o->floats[0];
      floats[1] *= o->floats[1];
   } else {
      Dyac_throw_def(NativeClassTypeMismatch,"tkmath::vector2f::mul_SELF Invalid Vector2f object");
   }
/*   else 
   {
      // Multiply by generic Object
      YAC_Value r;
      yacOperator(YAC_OP_MUL, _o, &r);
   }*/
}

void _Vector2f::_mul_YAC_RVAL(YAC_Object *_o, YAC_Value *_r) {
   if(YAC_CHK(_o, clid_Vector2f)) 
   {
      _Vector2f *o = (_Vector2f*) _o;
      _Vector2f *r = YAC_NEW_POOLED(Vector2f);
      r->floats[0] = floats[0] * o->floats[0];
      r->floats[1] = floats[1] * o->floats[1];
      _r->initObject(r,1);
   } else {
      Dyac_throw_def(NativeClassTypeMismatch,"tkmath::vector2f::mul_VAL Invalid Vector2f object");
   }
/*   else 
   {
      // Multiply by generic Object
      YAC_Value r;
      yacOperator(YAC_OP_MUL, _o, &r);
   }*/
}

void _Vector2f::_mul_YAC_RARG(YAC_Object *_o, YAC_Object *_r) {
   if(YAC_CHK(_o, clid_Vector2f)&&YAC_CHK(_r, clid_Vector2f)) 
   {
      _Vector2f *o = (_Vector2f*) _o;
      _Vector2f *r = (_Vector2f*) _r;
      r->floats[0] = floats[0] * o->floats[0];
      r->floats[1] = floats[1] * o->floats[1];
   } else {
      Dyac_throw_def(NativeClassTypeMismatch,"tkmath::vector2f::mul_ARG Invalid Vector2f object");
   }
/*   else 
   {
      // Multiply by generic Object
      YAC_Value r;
      yacOperator(YAC_OP_MUL, _o, &r);
   }*/
}

//return length of vector2f
//could use math.h hypoth function instead
sF32 _Vector2f::_getAbs(void) {
   return sqrtf(floats[0]*floats[0] + floats[1]*floats[1]);
}

//return squared length of vector2f - faster and does the job as well as getAbs
//in many circumstances
sF32 _Vector2f::_getAbsSqr(void) {
   return (floats[0] * floats[0] + floats[1] * floats[1]);
}

//scale vector2f to length 1.0f
void _Vector2f::_unit_YAC_RSELF(void) {
   sF32 absval = _getAbs();
   if(Dfltnonzero(absval)) 
   {
      absval=1.0f/absval;
      floats[0] *= absval;
      floats[1] *= absval;
   } 
   else 
   {
      Dyac_throw_def(TkMathDivisionByZero, "tkmath::Vector2f::unit_SELF Zero Vector cannot be normalized");
   }
}

void _Vector2f::_unit_YAC_RVAL(YAC_Value *_r) {
   sF32 absval = _getAbs();
   if(Dfltnonzero(absval)) 
   {
      _Vector2f *r=YAC_NEW_POOLED(Vector2f);
      absval=1.0f/absval;
      r->floats[0] = floats[0] * absval;
      r->floats[1] = floats[1] * absval;
      _r->initObject(r,1);
   } 
   else 
   {
      Dyac_throw_def(TkMathDivisionByZero, "tkmath::Vector2f::unit_VAL Zero Vector cannot be normalized");
   }
}

void _Vector2f::_unit_YAC_RARG(YAC_Object *_r) {
   if (YAC_CHK(_r, clid_Vector2f)) {
      sF32 absval = _getAbs();
      if(Dfltnonzero(absval)) 
      {
         _Vector2f *r=(_Vector2f*)_r;
         absval=1.0f/absval;
         r->floats[0] = floats[0] * absval;
         r->floats[1] = floats[1] * absval;
      } 
      else 
      {
         Dyac_throw_def(TkMathDivisionByZero, "tkmath::Vector2f::unit_ARG Zero Vector cannot be normalized");
      }
   } else {
      Dyac_throw_def(NativeClassTypeMismatch, "tkmath::Vector2f::unit_ARG Return object not of type Vector2f");
   }
}

//scale vector2f to length s
void _Vector2f::_unitScale_YAC_RSELF(sF32 s) {
   sF32 absval = _getAbs();
   if(Dfltnonzero(absval)) 
   {
      absval = s / absval;
      floats[0] *= absval;
      floats[1] *= absval;
   }
   else 
   {
      Dyac_throw_def(TkMathDivisionByZero, "tkmath::Vector2f::unitScale_SELF Zero Vector cannot be normalized");
   }
}

void _Vector2f::_unitScale_YAC_RVAL(sF32 s, YAC_Value *_r) {
   sF32 absval = _getAbs();
   if(Dfltnonzero(absval)) 
   {
      _Vector2f *r=YAC_NEW_POOLED(Vector2f);
      absval = s / absval;
      r->floats[0] = floats[0] * absval;
      r->floats[1] = floats[1] * absval;
   }
   else 
   {
      Dyac_throw_def(TkMathDivisionByZero, "tkmath::Vector2f::unitScale_VAL Zero Vector cannot be normalized");
   }
}

void _Vector2f::_unitScale_YAC_RARG(sF32 s, YAC_Object *_r) {
   if (YAC_CHK(_r, clid_Vector2f)) {
      sF32 absval = _getAbs();
      if(Dfltnonzero(absval)) 
      {
         _Vector2f *r=(_Vector2f*)_r;
         absval = s / absval;
         r->floats[0] = floats[0] * absval;
         r->floats[1] = floats[1] * absval;
      }
      else 
      {
         Dyac_throw_def(TkMathDivisionByZero, "tkmath::Vector2f::unitScale_ARG Zero Vector cannot be normalized");
      }
   } else {
      Dyac_throw_def(NativeClassTypeMismatch, "tkmath::Vector2f::unitScale_ARG Return object not of type Vector2f");
   }
}

//initialise vector2f value methods

//init both elements with individual values
void _Vector2f::_init(sF32 x, sF32 y) {
   floats[0] = x;
   floats[1] = y;
}

//init with a directional vector _o and length _s
void _Vector2f::_initScalef(YAC_Object *_o, sF32 _s) {
   if(YAC_CHK(_o, clid_Vector2f))
   {
      _Vector2f *o = (_Vector2f*) _o;

      floats[0] = o->floats[0] * _s;
      floats[1] = o->floats[1] * _s;
   }
   else
   {
      Dyac_throw_def(InvalidPointer, "tkmath::Vector2f::initScalef: invalid object parameter");
   }
}

void _Vector2f::_New(sF32 x, sF32 y, YAC_Value *_r) {
   _Vector2f *r=YAC_NEW_POOLED(Vector2f);
   r->_init(x,y);
   _r->initObject(r,1);
}

void YAC_CALL _vector2f(sF32 x, sF32 y,YAC_Value *_r) {
   _Vector2f *r=YAC_NEW_POOLED(Vector2f);
   r->_init(x,y);
   _r->initObject(r,1);
}
