#include <amsculib3/amsculib3.hpp>

namespace amscuda
{

//////////////////
// Vector Class //
//////////////////

__host__ __device__ cuvec2i::cuvec2i() 
{
    x = 0; y = 0; 
    return;
}

__host__ __device__ cuvec2i::~cuvec2i() 
{
    x = 0; y = 0; 
    return;
}

__host__ __device__ cuvec2i::cuvec2i(const int32_t &_x, const int32_t &_y) 
{
    x = _x; y = _y; 
    return;
}

__host__ __device__ int32_t& cuvec2i::operator[](const int &I)
{
    switch(I)
    {
        case 0:
            return x;
        case 1:
            return y;
    }

    return x;
}

__host__ __device__ const int32_t& cuvec2i::operator[](const int &I) const
{
    switch(I)
    {
        case 0:
            return x;
        case 1:
            return y;
    }

    return x;
}

__host__ __device__ cuvec2i cuvec2i::operator+(const cuvec2i& rhs) const
{
    cuvec2i ret;
    ret.x = x + rhs.x;
    ret.y = y + rhs.y;
    return ret;
}

__host__ __device__ cuvec2i cuvec2i::operator-(const cuvec2i& rhs) const
{
    cuvec2i ret;
    ret.x = x - rhs.x;
    ret.y = y - rhs.y;
    return ret;
}

__host__ __device__ cuvec2i cuvec2i::operator*(const cuvec2i& rhs) const
{
    //Elementwise product
    cuvec2i ret;
    ret.x = x * rhs.x;
    ret.y = y * rhs.y;
    return ret;
}

__host__ __device__ cuvec2i cuvec2i::operator/(const cuvec2i& rhs) const
{
    //Elementwise division
    cuvec2i ret;
    ret.x = x / rhs.x;
    ret.y = y / rhs.y;
    return ret;
}

__host__ __device__ cuvec2i operator*(const cuvec2i& lhs, const int32_t& rhs)
{
    cuvec2i ret;
    ret.x = lhs.x*rhs;
    ret.y = lhs.y*rhs;
    return ret;
}

__host__ __device__ cuvec2i operator*(const int32_t& lhs, const cuvec2i& rhs)
{
    cuvec2i ret;
    ret.x = lhs*rhs.x;
    ret.y = lhs*rhs.y;
    return ret;
}

__host__ __device__ cuvec2i operator/(const cuvec2i& lhs, const int32_t& rhs)
{
    cuvec2i ret;
    ret.x = lhs.x/rhs;
    ret.y = lhs.y/rhs;
    return ret;
}

__host__ __device__ cuvec2i operator/(const int32_t& lhs, const cuvec2i& rhs)
{
    cuvec2i ret;
    ret.x = lhs/rhs.x;
    ret.y = lhs/rhs.y;
    return ret;
}

__host__ __device__ cuvec2i operator-(const cuvec2i& other)
{
    cuvec2i ret;
    ret.x = -other.x;
    ret.y = -other.y;
    return ret;
}

__host__ __device__ cuvec2i& cuvec2i::operator+=(const cuvec2i& rhs)
{
    x += rhs.x;
    y += rhs.y;
    return *this;
}

__host__ __device__ cuvec2i& cuvec2i::operator-=(const cuvec2i& rhs)
{
    x -= rhs.x;
    y -= rhs.y;
    return *this;
}

__host__ __device__ cuvec2i& cuvec2i::operator*=(const int32_t& rhs)
{
    x *= rhs;
    y *= rhs;
    return *this;
}

__host__ __device__ cuvec2i& cuvec2i::operator/=(const int32_t& rhs)
{
    x /= rhs;
    y /= rhs;
    return *this;
}



//////////////////////
// Standalone Funcs //
//////////////////////


///////////
// Tests //
///////////

};