// ============================================================================
// File:               $File$
//
// Project:            
//
// Purpose:            
//
// Author:             Rammi
//                     This code is in the public domain.
//                     Use at own risk.
//                     No guarantees given.
//
// Copyright Notice:   (c) 2008  Rammi (rammi@caff.de)
//
// Latest change:      $Date$
//
// History:	       $Log$
//=============================================================================
package de.caff.util;

import java.awt.*;
import java.awt.geom.Point2D;

/**
 *  Useful static helper methods.
 *
 *  This class is part of a solution for a
 *  <a href="http://www.heise.de/ct/creativ/08/02/details/">competition by the German computer magazine c't</a>
 */
public class Tools
{
  /**
   * Interprete 8 bits as unsigned byte.
   * @param b incomoing byte
   * @return unsigned interpretation
   */
  public static int byteToUnsigned(byte b)
  {
    return b < 0 ? b + 256 : b;
  }

  /**
   *  Get the cross product of two vectors,
   *  @param v1 first vector
   *  @param v2 second vector
   *  @return v1 x v2
   */
  public static int crossProduct(Point v1, Point v2)
  {
    return v1.x * v2.y - v1.y * v2.x;
  }

  /**
   *  Get the cross product of two vectors,
   *  @param v1 first vector
   *  @param v2 second vector
   *  @return v1 x v2
   */
  public static double crossProduct(Point2D v1, Point2D v2)
  {
    return v1.getX() * v2.getY() - v1.getY() * v2.getX();
  }

  public static int crossProduct(int v1x, int v1y, int v2x, int v2y)
  {
    return v1x * v2y - v1y * v2x;
  }

  public static double crossProduct(double v1x, double v1y, double v2x, double v2y)
  {
    return v1x * v2y - v1y * v2x;
  }

  /**
   *  Get the scalar product of two vectors.
   *  @param v1 first vector
   *  @param v2 second vector
   *  @return scalar product
   */
  public static int scalarProduct(Point v1, Point v2)
  {
    return v1.x * v2.x + v1.y * v2.y;
  }

  public static double scalarProduct(Point2D v1, Point2D v2)
  {
    return v1.getX() * v2.getX() + v1.getY() * v2.getY();
  }

  public static int scalarProduct(int v1x, int v1y, int v2x, int v2y)
  {
    return v1x * v2x + v1y * v2y;
  }

  public static double scalarProduct(double v1x, double v1y, double v2x, double v2y)
  {
    return v1x * v2x + v1y * v2y;
  }

  /**
   *  Get the length of o vector.
   *  @param v vector
   *  @return it's length
   */
  public static double getLength(Point2D v)
  {
    double x = v.getX();
    double y = v.getY();
    return getLength(x, y);
  }

  /**
   *  Get the length of a vector.
   *  @param x vector x
   *  @param y vector y
   *  @return length of vector
   */
  public static double getLength(double x, double y)
  {
    return Math.sqrt(x * x + y * y);
  }

  /**
   *  Get the squared length of o vector.
   *  @param v vector
   *  @return it's squared length
   */
  public static double getSquaredLength(Point2D v)
  {
    double x = v.getX();
    double y = v.getY();
    return getSquaredLength(x, y);
  }

  /**
   *  Get the squared length of a vector.
   *  @param x vector x
   *  @param y vector y
   *  @return squared length of vector
   */
  public static double getSquaredLength(double x, double y)
  {
    return x * x + y * y;
  }

  /**
   *  Get the distance of two points.
   *  @param p1 first point
   *  @param p2 second point
   *  @return distancve of the two points
   */
  public static double getDistance(Point2D p1, Point2D p2)
  {
    double x = p1.getX() - p2.getX();
    double y = p1.getY() - p2.getY();
    return getLength(x, y);
  }

  /**
   *  Normalize a vector.
   *  @param v vector
   *  @return normalized vector or <code>null</code> if v is the null vector
   */
  public static Point2D normalize(Point2D v)
  {
    double x = v.getX();
    double y = v.getY();
    double len = getLength(x, y);
    return (len > 0) ?
            new Point2D.Double(x/len, y/len)  :
            null;
  }

  /**
   *  Get the manhattan distance between two points.
   *  The manhattan distance is the sum of the distances in x and y.
   *  @param p1 first point
   *  @param p2 second point
   *  @return manhattan distance
   */
  public static int getManhattanDistance(Point p1, Point p2)
  {
    return getManhattanDistance(p1.x, p1.y, p2.x, p2.y);
  }

  /**
   *  Get the manhattan distance between two points.
   *  The manhattan distance is the sum of the distances in x and y.
   *  @param p1x first point's x
   *  @param p1y first point's y
   *  @param p2x second point's x
   *  @param p2y second point's y
   *  @return manhattan distance
   */
  public static int getManhattanDistance(int p1x, int p1y, int p2x, int p2y)
  {
    return Math.abs(p1x - p2x) + Math.abs(p1y - p2y);
  }

  /**
   *  Get the square of a value.
   *  @param v value
   *  @return <code>v*v</code>
   */
  public static double square(double v)
  {
    return v*v;
  }
}
