#include <amscppimglib4/amscppimglib4.hpp>
#include <amscppimglib4/amscppimglib4_intlutil.hpp>

namespace ams
{

    amsbitplane::amsbitplane() : Nx(0), Ny(0), data(NULL), width(Nx), height(Ny)
    {
        return;
    }

    amsbitplane::~amsbitplane()
    {
        if(data!=NULL) {delete[] data; data=NULL;}
        Nx = 0;
        Ny = 0;
        return;
    }

    amsbitplane::amsbitplane(const amsbitplane& other) : Nx(0), Ny(0), data(NULL), width(Nx), height(Ny)
    {
        int res;
        if(this!=&other)
        {
            res = this->resize(Nx,Ny);
            if(res==amsimage_success)
            {
                imglib4::amsimage_plane_copy(
                    this->data, 0, 1, Nx, Ny,
                    other.data, 0, 1, other.Nx, other.Ny,
                    0,0
                );
            }
        }
        return;
    }

    amsbitplane::amsbitplane(amsbitplane&& other) noexcept : Nx(0), Ny(0), data(NULL), width(Nx), height(Ny)
    {
        if(this!=&other)
        {
            this->Nx = other.Nx;
            this->Ny = other.Ny;
            this->data = other.data;

            other.Nx = 0;
            other.Ny = 0;
            other.data = NULL;
        }
        return;
    }
    
    amsbitplane& amsbitplane::operator=(const amsbitplane& other)
    {
        int res;
        if(this!=&other)
        {
            res = this->resize(Nx,Ny);
            if(res==amsimage_success)
            {
                imglib4::amsimage_plane_copy(
                    this->data, 0, 1, Nx, Ny,
                    other.data, 0, 1, other.Nx, other.Ny,
                    0,0
                );
            }
        }
        return *this;
    }
    
    amsbitplane& amsbitplane::operator=(amsbitplane&& other) noexcept
    {
        if(this!=&other)
        {
            if(this->data!=NULL) {delete[] this->data; this->data=NULL;}
            this->Nx = 0; this->Ny = 0;

            this->Nx = other.Nx;
            this->Ny = other.Ny;
            this->data = other.data;

            other.Nx = 0;
            other.Ny = 0;
            other.data = NULL;
        }
        return *this;
    }

    int amsbitplane::resize(int _Nx, int _Ny)
    {
        int ret = amsimage_success;
        
        uint8_t *newdata = NULL;

        _Nx = (_Nx<0) ? 0 : _Nx;
        _Ny = (_Ny<0) ? 0 : _Ny;

        if(_Nx == Nx && _Ny == Ny)
        {
            return ret; //no resize necessary
        }

        if(_Nx==0 || _Ny == 0)
        {
            //zero size image
            if(data!=NULL) {delete[] data; data=NULL;}
            Nx = 0;
            Ny = 0;
            return ret;
        }
        
        newdata = new(std::nothrow) uint8_t[_Nx*_Ny];
        if(newdata==NULL)
        {
            ret = amsimage_failure;
            return ret;
        }

        imglib4::amsimage_planeregion_set(
            newdata,
            1,_Nx,_Ny,0,
            0,0,_Nx,_Ny,
            0
        );

        if(data!=NULL)
        {
            imglib4::amsimage_plane_copy(
                newdata,0,1,_Nx,_Ny,
                data,0,1,Nx,Ny,
                0,0
            );
        }

        if(data!=NULL) {delete[] data; data=NULL;}
        data = newdata;
        Nx = _Nx;
        Ny = _Ny;

        return ret;
    }



};