//
//  Transform.h
//  Meteor
//
//  Created by Cesar Parent on 13/07/2015.
//  Copyright (c) 2015 Cesar Parent. All rights reserved.
//

#ifndef __Meteor__Transform__
#define __Meteor__Transform__

#include "Rect.h"
#include "Mat.h"

NS_BEGIN

class Polygon;

/**
 * @class           AffineTransform
 * @ingroup         Geometry
 * @brief           A class used to create affine transformation matrices.
 * @{
 */

struct AffineTransform {

    /**
     * @name        Creating Affine Transformation Matrices
     * @{
     */

    /*!
     * @brief       Returns a 2D rotation matrix.
     * @param       angle       Rotation angle in radians.
     * @return      3*3 rotation matrix.
     */
    static const mat33
    rotate2D(float angle);

    /*!
     * @brief       Returns a 2D translation matrix.
     * @param       dx          Translation distance along the horizontal axis.
     * @param       dy          Translation distance along the vertical axis.
     * @return      3*3 translation matrix.
     */
    static const mat33
    translate2D(float dx, float dy);

    /*!
     * @brief       Returns a 2D translation matrix.
     * @param       distance    Translation vector.
     * @return      3*3 translation matrix.
     */
    static const mat33
    translate2D(const vec2& distance);

    /*!
     * @brief       Returns a 2D scaling matrix
     * @param       sx          Scaling factor along the horizontal axis.
     * @param       sy          Scaling factor along the vertical axis.
     * @return      3*3 scaling matrix.
     */
    static const mat33
    scale2D(float sx, float sy);

    /*!
     * @brief       Returns a 2D scaling matrix
     * @param       scale       Scaling factors along the horizontal axis.
     * @return      3*3 scaling matrix.
     */
    static const mat33
    scale2D(const vec2& scale);
    
    /**
     * @}
     * @name        Extracting Values From Matrices
     * @{
     */
    
    static const mat33
    inverse(const mat33& t);
    
    static const vec2
    translationFromMatrix(const mat33& t);
    
    static const vec2
    scaleFromMatrix(const mat33& t);
    
    static const float
    rotationFromMatrix(const mat33& t);

    /**
     * @}
     * @name        Transforming Objects With Matrices
     * @{
     */

    /*!
     * @brief       Returns the given vector, transformed by a matrix.
     * @param       T           Transformation matrix.
     * @param       vector      Original vector.
     * @return      A new vector obtained by applying <code>T</code> to <code>v</code>
     */
    static const vec2
    applyTransform(const mat33& T, const vec2& vector);

    /*!
     * @brief       Returns the given rectangle, transformed by a matrix.
     * @param       T           Transformation matrix.
     * @param       rect        Original rectangle.
     * @return      A new vector obtained by applying <code>T</code> to <code>v</code>
     */
    static const Rect
    applyTransform(const mat33& T, const Rect& rect);

    /*!
     * @brief       Returns the given polygon, transformed by a matrix.
     * @param       T           Transformation matrix.
     * @param       polygon     Original polygon.
     * @return      A new vector obtained by applying <code>T</code> to <code>v</code>
     */
    static const Polygon
    applyTransform(const mat33& T, const Polygon& polygon);

};
/**
 * @}
 */


NS_END

#endif /* defined(__Meteor__Transform__) */
