//--------------------------------
//********************************
//******** Class point **********
//********************************
function point()
{
   this.x = 0; 
   this.y = 0;

   if (arguments.length == 2) 
   {	
      this.x = arguments[0];
      this.y = arguments[1];              	 
   }
}

function owk_point_set_xy(i_x, i_y)
{
   this.x=i_x;
   this.y=i_y;
}


function owk_point_copy(i_object)
{
   this.x=i_object.x;
   this.y=i_object.y;
}

function owk_point_is_equal(i_object)
{
   if((this.x == i_object.x) && (this.y == i_object.y))
   {
		return true;
	} 
	else
	{
		return false;
	}
}

function owk_point_rotate(i_angle, i_pivot_point)
{
    var xo = this.x;
    var yo = this.y;
    var xp = i_pivot_point.x;
    var yp = i_pivot_point.y;
    var cos_angle = Math.cos(i_angle/180*Math.PI);
    var sin_angle = Math.sin(i_angle/180*Math.PI);
    
    this.x = Math.floor(xp*1 + (xo - xp) * cos_angle - (yo - yp) * sin_angle);
    this.y = Math.floor(yp*1 + (xo - xp) * sin_angle*1 + (yo - yp) * cos_angle);   
}


function owk_point_scale(i_scale, i_fixed_x, i_fixed_y)
{
	this.x = Math.floor(this.x * i_scale + i_fixed_x * (1 - i_scale)); 
	this.y = Math.floor(this.y * i_scale + i_fixed_y * (1 - i_scale)); 
}



function owk_point_translate(i_x, i_y)
{
   this.x += i_x;
   this.y += i_y;    
}



function owk_point_not_equal(i_object)
{
	  if(!(this.x == i_object.x) || !(this.y == i_object.y))
	  {
		   return true;
	  } 
	  else
	  {
		   return false;
	  }
}  
      

//********************************
//******** Public Methods ********
//********************************
point.prototype.xy = owk_point_set_xy;
point.prototype.set_xy = owk_point_set_xy;
point.prototype.copy = owk_point_copy;
point.prototype.rotate = owk_point_rotate;
point.prototype.is_equal = owk_point_is_equal;
point.prototype.not_equal = owk_point_not_equal;
point.prototype.scale = owk_point_scale;
point.prototype.translate = owk_point_translate;




//--------------------------------
//********************************
//******** Class size **********
//********************************
//--------------------------------


//********************************
//********* Constructors *********
//********************************
function dim()
{
   this.width = 0; 
   this.height = 0;   
   
   switch (arguments.length) 
   {
		case 2 : //The constructor has 2 parameters
		{
         if((typeof arguments[0] == "number")&&(typeof arguments[1] == "number"))
         {  
            this.width = arguments[0];
            this.height = arguments[1];
            break;
         }
		 }
   }
}

function owk_dim_resize(i_width, i_height)
{
	this.width = i_width;
	this.height = i_height;
}
   
function owk_dim_copy(i_object)
{ 
	this.width = i_object.width;
	this.height = i_object.height;
}
          
function owk_dim_scale(i_scale,  i_fixed_x,  i_fixed_y)
{
	this.width  = Math.round(this.width * i_scale); 
	this.height = Math.round(this.height * i_scale); 
}  


function owk_dim_is_equal(i_object)
{
	  if((this.width == i_object.width) && (this.height == i_object.height))
	  {
		   return true;
	  } 
	  else
	  {
		   return false;
	  }
}  

function owk_dim_not_equal(i_object)
{
	  if(!(this.width == i_object.width) || !(this.height == i_object.height))
	  {
		   return true;
	  } 
	  else
	  {
		   return false;
	  }
}  

   
//********************************
//******** Public Methods ********
//********************************
dim.prototype.resize = owk_dim_resize;
dim.prototype.copy = owk_dim_copy;
dim.prototype.scale = owk_dim_scale;
dim.prototype.is_equal = owk_dim_is_equal;
dim.prototype.not_equal = owk_dim_not_equal;


//--------------------------------
//********************************
//******** rectangle    **********
//********************************
//--------------------------------


//********************************
//********* rectangle *********
//********************************
function rectangle()
{    
  this.origin = new point();
  this.size = new dim();
   
   switch (arguments.length) 
   {
      case 1 : //The constructor has 2 parameters
      {
         
         if((typeof arguments[0] == "size"))
         {  
            this.origin.x = 0;
            this.origin.y = 0;
            this.size = arguments[0];
            break;
         }

      }		 
      case 2 : //The constructor has 2 parameters
      {       
         if((typeof arguments[0] == "object")&&(typeof arguments[1] == "object"))
         {  
            this.origin = arguments[0];
            this.size = arguments[1];
            break;
         }
      }
      case 4 : //The constructor has 2 parameters
      {
         if((typeof arguments[0] == "number")&&(typeof arguments[1] == "number")&&(typeof arguments[2] == "number")&&(typeof arguments[3] == "number"))
         {  
            this.origin.x = arguments[0];
            this.origin.y = arguments[1];        
            this.size.width = ((arguments[2] - this.origin.x) + 1);
            this.size.height = ((arguments[3] - this.origin.y) + 1);
            break;
         } 
      }     
   }
}

function owk_rectangle_left()
{ 
	return this.origin.x;
}

function owk_rectangle_set_left(i_value)
{ 
	this.origin.x = i_value;
}

function owk_rectangle_right()
{ 
	return (this.origin.x*1 + this.size.width-1);
}

function owk_rectangle_set_right(i_value)
{ 
	this.size.width = ((i_value - this.origin.x) + 1);
}

function owk_rectangle_top()
{ 
	return this.origin.y;
}

function owk_rectangle_set_top(i_value)
{ 
	this.origin.y = i_value;
}

function owk_rectangle_bottom()
{ 
	return this.origin.y*1 + this.size.height-1;
}

function owk_rectangle_set_bottom(i_value)
{ 
	this.size.height = ((i_value - this.origin.y) + 1);
}

function owk_rectangle_width()
{ 
	return this.size.width;
}

function owk_rectangle_set_width(i_value)
{ 
	this.size.width = i_value;
}

function owk_rectangle_height()
{ 
	return this.size.height;
}

function owk_rectangle_set_height(i_value)
{ 
	this.size.height  = i_value;
}
      
function owk_rectangle_center_x()
{ 
	return Math.floor(this.origin.x*1 + this.size.width/2);
}

function owk_rectangle_center_y()
{ 
	return Math.floor(this.origin.y*1 + this.size.height/2);
}

//i_object : objet rectangle
function owk_rectangle_copy(i_object)
{ 
	 this.origin.copy(i_object.origin);
    this.size.copy(i_object.size);
}

function owk_rectangle_is_equal(i_object)
{
   if((this.origin.is_equal(i_object.origin)) && (this.size.is_equal(i_object.size)))
   {
		 return true;
	}
	else
	{
       return false;
	}
}

function owk_rectangle_not_equal(i_object)
{
   if(!(this.origin.is_equal(i_object.origin)) || !(this.size.is_equal(i_object.size)))
   {
		 return true;
	}
	else
	{
       return false;
	}
}

function owk_rectangle_translate(i_x, i_y)
{
   this.origin.translate(i_x, i_y);    
}

function owk_rectangle_scale(i_scale)
{
	var cx = this.center_x();
	var cy = this.center_y();

   this.size.scale(i_scale);
 	this.recenter(cx, cy);
}

function owk_rectangle_move(i_x, i_y)
{
   this.origin.x = i_x;
   this.origin.y = i_y;     
}

function owk_rectangle_recenter(i_cx, i_cy)
{
   this.origin.x = (i_cx - Math.floor(this.size.width/2)-1);
   this.origin.y = (i_cy - Math.floor(this.size.height/2)-1); 
}


//i_pt = object point
function owk_rectangle_is_point_inside(i_point) 
{  
   if ((i_point.x >= this.left()) && (i_point.x <= this.right()) && (i_point.y >= this.top()) && (i_point.y <= this.bottom()))
   { 
      return true; 
   } 
   else
   { 
     return false; 
   }          
}

function owk_rectangle_is_xy_inside(i_x, i_y) 
{
   if ((i_x >= this.left()) && (i_x <= this.right()) && (i_y >= this.top()) && (i_y <= this.bottom())) 
   { 
      return true; 
   } 
   else 
   {
      return false; 
   }  
}

function owk_rectangle_is_rect_inside(i_rect) 
{ 
   if(this.is_xy_inside(i_rect.left(), i_rect.top()) && this.is_xy_inside(i_rect.right(), i_rect.bottom())) 
   { 
      return true; 
   } 
   else 
   {  
      return false;
   }
}

function owk_is_rect_is_rect_outside(i_rect)
{ 
   if (i_rect.right() < this.left() || i_rect.left() > this.right() || i_rect.bottom() < this.top() || i_rect.top() > this.bottom()) 
   { 
      return true; 
   } 
   else 
   {
      return false; 
   }
}

function owk_is_rect_is_point_outside(i_point)
{     
      return !(this.is_point_inside(i_point));   
}

function owk_is_rect_is_outside(i_x, i_y)
{     
      return !(this.is_xy_inside(i_x, i_y));   
}

function owk_is_rect_combine(i_with_rect, o_combined_rect)
{ 
   o_combined_rect.set_left(Math.min(this.left(), i_with_rect.left()));
   o_combined_rect.set_top(Math.min(this.top(), i_with_rect.top()));
   o_combined_rect.set_right(Math.max(this.right(), i_with_rect.right()));
   o_combined_rect.set_bottom(Math.max(this.bottom(), i_with_rect.bottom()));
}


function owk_is_rect_intersect(i_with_rect, o_intersect_rect)
{
   var has_intersection = false;

   if(!(this.is_rect_outside(i_with_rect)))
   {
      has_intersection = true;
      o_intersect_rect.set_left(Math.max(this.left(), i_with_rect.left()));
      o_intersect_rect.set_top(Math.max(this.top(), i_with_rect.top()));
      o_intersect_rect.set_right(Math.min(this.right(), i_with_rect.right()));
      o_intersect_rect.set_bottom(Math.min(this.bottom(), i_with_rect.bottom()));
   }

   return has_intersection;
}

//********************************
//******** Public Methods ********
//********************************
rectangle.prototype.top = owk_rectangle_top;
rectangle.prototype.set_top = owk_rectangle_set_top;
rectangle.prototype.left = owk_rectangle_left;
rectangle.prototype.set_left = owk_rectangle_set_left;
rectangle.prototype.right = owk_rectangle_right;
rectangle.prototype.set_right = owk_rectangle_set_right;
rectangle.prototype.bottom = owk_rectangle_bottom;
rectangle.prototype.set_bottom = owk_rectangle_set_bottom;
rectangle.prototype.center_x = owk_rectangle_center_x;
rectangle.prototype.center_y = owk_rectangle_center_y;
rectangle.prototype.width = owk_rectangle_width;
rectangle.prototype.set_width = owk_rectangle_set_width;
rectangle.prototype.height = owk_rectangle_height;
rectangle.prototype.set_height = owk_rectangle_set_height;
rectangle.prototype.copy = owk_rectangle_copy;
rectangle.prototype.is_equal = owk_rectangle_is_equal;
rectangle.prototype.not_equal = owk_rectangle_not_equal;
rectangle.prototype.translate = owk_rectangle_translate;
rectangle.prototype.scale = owk_rectangle_scale;
rectangle.prototype.recenter = owk_rectangle_recenter;
rectangle.prototype.move = owk_rectangle_move;
rectangle.prototype.is_xy_inside = owk_rectangle_is_xy_inside;
rectangle.prototype.is_point_inside = owk_rectangle_is_point_inside;
rectangle.prototype.is_rect_inside = owk_rectangle_is_rect_inside;
rectangle.prototype.is_outside = owk_is_rect_is_outside;
rectangle.prototype.is_point_outside = owk_is_rect_is_point_outside;
rectangle.prototype.is_rect_outside = owk_is_rect_is_rect_outside;
rectangle.prototype.combine = owk_is_rect_combine;
rectangle.prototype.intersect = owk_is_rect_intersect;



//--------------------------------
//********************************
//******** quad **********
//********************************
//--------------------------------


//********************************
//********* quad *********
//********************************
function quad(i_rect)
{    
  this.pt1 = new point();
  this.pt2 = new point();
  this.pt3 = new point();
  this.pt4 = new point();  
   
  this.pt1.xy(i_rect.left(),  i_rect.top());
  this.pt2.xy(i_rect.right(), i_rect.top());
  this.pt3.xy(i_rect.right(), i_rect.bottom());
  this.pt4.xy(i_rect.left(),  i_rect.bottom());
        
}

function owk_quad_copy(i_object)
{
    this.pt1.copy(i_object.pt1);
    this.pt2.copy(i_object.pt2);
    this.pt3.copy(i_object.pt3);
    this.pt4.copy(i_object.pt4);
}


function owk_quad_rotate(i_angle, i_pivot)
{
   this.pt1.rotate(i_angle, i_pivot);
   this.pt2.rotate(i_angle, i_pivot);
   this.pt3.rotate(i_angle, i_pivot);
   this.pt4.rotate(i_angle, i_pivot);
}

function owk_quad_bounding_box(i_rectangle)
{    
   i_rectangle.set_left  (Math.min(Math.min(Math.min(pt1.x, pt2.x), pt3.x), pt4.x));
   i_rectangle.set_top   (Math.min(Math.min(Math.min(pt1.y, pt2.y), pt3.y), pt4.y));
   i_rectangle.set_right (Math.max(Math.max(Math.max(pt1.x, pt2.x), pt3.x), pt4.x));
   i_rectangle.set_bottom(Math.max(Math.max(Math.max(pt1.y, pt2.y), pt3.y), pt4.y));
}

quad.prototype.copy = owk_quad_copy;
quad.prototype.rotate = owk_quad_rotate;
quad.prototype.bounding_box = owk_quad_bounding_box;


//********************************
//********* rectangle_2pts *******
//********************************
function rectangle_2pts()
{    
   this.left = 0;
   this.top = 0;
   this.right = 0;   
   this.bottom = 0;

   if((typeof arguments[0] == "number")&&(typeof arguments[1] == "number")&&(typeof arguments[2] == "number")&&(typeof arguments[3] == "number"))
   {
      this.left = arguments[0];
      this.top = arguments[1];
      this.right = arguments[2];   
      this.bottom = arguments[3];
   }
}


function owk_rectangle_2pts_ltrb(i_left, i_top, i_right, i_bottom)
{    
    left = i_left; top = i_top; right = i_right; bottom = i_bottom; 
}

function owk_rectangle_2pts_copy(i_object)
{    
   this.left = i_object.left;
   this.top = i_object.top;
   this.right = i_object.right;
   this.bottom = i_object.bottom;
}

function owk_rectangle_2pts_is_equal(i_object)
{    
   if(left == i_object.left&&top == i_object.top&&right == i_object.right&&bottom == i_object.bottom)
   {
      return true;
   }
   else
   {
      return false;
   } 
}

function owk_rectangle_2pts_diff(i_object)
{    
   if(left == i_object.left&&top == i_object.top&&right == i_object.right&&bottom == i_object.bottom)
   {
      return false;
   }
   else
   {
      return true;
   } 
}
 
rectangle_2pts.prototype.ltrb = owk_rectangle_2pts_ltrb;
rectangle_2pts.prototype.copy = owk_rectangle_2pts_copy;
rectangle_2pts.prototype.is_equal = owk_rectangle_2pts_is_equal;
rectangle_2pts.prototype.diff = owk_rectangle_2pts_diff;


//********************************
//********* range        *********
//********************************
function range_value(i_min, i_max, i_value)
{    
   this.min = i_min;
   this.max = i_max;
   this.val = Math.min(Math.max(i_value, this.min), this.max); 
}

function owk_range_value_value()
{    
   return this.val; 
}

function owk_range_value_set_value(i_value)
{  
   this.val = Math.min(Math.max(i_value, this.min), this.max); 
}

function owk_range_value_val_min_max(i_value, i_min, i_max)
{
   this.val = Math.min(Math.max(i_value, i_min), i_max);
   this.min = i_min;
   this.max = i_max;
   this.on_value_change(); 
}

function convert_value(i_value, i_min, i_max)
{
   this.val = ((this.max - this.min)/(i_max - i_min)*i_value);
   this.on_value_change(); 
}



function owk_range_value_convert_from(i_min,  i_max)
{     
   return ((i_max - i_min)/(this.max - this.min)*(this.val*1-this.min*1))
}

function owk_range_value_convert_to(i_value, i_min,  i_max) {

   
   this.set_value((this.min +(this.max - this.min)/(i_max - i_min)*(i_value-i_min)));
 //  return ((i_max - i_min)/(max - min)*(value()-min));
  // return ((i_max - i_min)/(this.max - this.min)*(this.val-i_min));
   //this.val = Math.min(Math.max(this.val, this.min), this.max); 
}

function owk_range_value_on_value_change()
{

}

function owk_range_value_set_max(i_max)
{
   this.max = i_max;
   this.val = Math.min(Math.max(this.val, this.min), this.max); 
}

function owk_range_value_set_min(i_min)
{
   this.min = i_min;
   this.val = Math.min(Math.max(this.val, this.min), this.max); 
}

range_value.prototype.value = owk_range_value_value;
range_value.prototype.set_value = owk_range_value_set_value;
range_value.prototype.set_max = owk_range_value_set_max;
range_value.prototype.set_max = owk_range_value_set_max;
range_value.prototype.val_min_max = owk_range_value_val_min_max;
range_value.prototype.on_value_change = owk_range_value_on_value_change;
range_value.prototype.convert_to = owk_range_value_convert_to;
range_value.prototype.convert_from = owk_range_value_convert_from;


//********************************
//********* rectangle_2pts *******
//********************************
function rectangle_2pts()
{    
   this.left = 0;
   this.top = 0;
   this.right = 0;   
   this.bottom = 0;

   if((typeof arguments[0] == "number")&&(typeof arguments[1] == "number")&&(typeof arguments[2] == "number")&&(typeof arguments[3] == "number"))
   {
      this.left = arguments[0];
      this.top = arguments[1];
      this.right = arguments[2];   
      this.bottom = arguments[3];
   }
}


function owk_rectangle_2pts_ltrb(i_left, i_top, i_right, i_bottom)
{    
    left = i_left; top = i_top; right = i_right; bottom = i_bottom; 
}

function owk_rectangle_2pts_copy(i_object)
{    
   this.left = i_object.left;
   this.top = i_object.top;
   this.right = i_object.right;
   this.bottom = i_object.bottom;
}

function owk_rectangle_2pts_is_equal(i_object)
{    
   if(left == i_object.left&&top == i_object.top&&right == i_object.right&&bottom == i_object.bottom)
   {
      return true;
   }
   else
   {
      return false;
   } 
}

function owk_rectangle_2pts_diff(i_object)
{    
   if(left == i_object.left&&top == i_object.top&&right == i_object.right&&bottom == i_object.bottom)
   {
      return false;
   }
   else
   {
      return true;
   } 
}
 
rectangle_2pts.prototype.ltrb = owk_rectangle_2pts_ltrb;
rectangle_2pts.prototype.copy = owk_rectangle_2pts_copy;
rectangle_2pts.prototype.is_equal = owk_rectangle_2pts_is_equal;
rectangle_2pts.prototype.diff = owk_rectangle_2pts_diff;
