/*

*/

class funcXY{
public:
    virtual unsigned int operator() (unsigned int, unsigned int);
    virtual unsigned int operator() (unsigned int i);
    virtual unsigned int size();
    virtual unsigned int w();
    virtual unsigned int h();
};

//release index from XY
class fXY:public funcXY{
    unsigned int _w,
                 _h;
public:
    fXY(unsigned int w, unsigned int h);
    unsigned int operator() (unsigned int x, unsigned int y);
    unsigned int size();
    unsigned int w();
    unsigned int h();
};

//release index from sub windows of XY
class fXYsub:public funcXY{
    funcXY * _from;
    unsigned int _x,
                 _y,
                 _w,
                 _h;
public:
    fXYsub(funcXY * from, unsigned int x, unsigned int y, unsigned int w, unsigned int h);
    unsigned int operator() (unsigned int x, unsigned int y);
    unsigned int operator() (unsigned int i);
    unsigned int size();
    unsigned int w();
    unsigned int h();
};

//rotate cw
//rotate ccw
//rotate 180
//vertical mirror
//horizontal mirror

//===========================================================================================

//base functor
unsigned int funcXY::operator() (unsigned int, unsigned int)
{
    return 0;
}

unsigned int funcXY::operator() (unsigned int i)
{
    return 0;
}

unsigned int funcXY::size()
{
    return 0;
}

unsigned int funcXY::w()
{
    return 0;
}

unsigned int funcXY::h()
{
    return 0;
}

//coordinate
fXY::fXY(unsigned int w, unsigned int h)
{
    _w = w;
    _h = h;
}

unsigned int fXY::operator() (unsigned int x, unsigned int y)
{
    if (x<_w && y<_h)
        return x + (y*_w);
    return _w*_h;
}

unsigned int fXY::size()
{
    return _w*_h;
}

unsigned int fXY::w()
{
    return _w;
}

unsigned int fXY::h()
{
    return _h;
}

//sub windows
fXYsub::fXYsub(funcXY * from, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
    _from = from;
    _x = x;
    _y = y;
    _w = w;
    _h = h;
}

unsigned int fXYsub::operator() (unsigned int x, unsigned int y)
{
    if (x < _w && y < _h)
        return x+_x + ((y+_y)*_w);
    return _w*_h;
}

unsigned int fXYsub::operator() (unsigned int i)
{
    return operator()(i%_w, i/_w);
}

unsigned int fXYsub::size()
{
    return _w*_h;
}

unsigned int fXYsub::w()
{
    return _w;
}

unsigned int fXYsub::h()
{
    return _h;
}

//not sure how to handle the following
class fup{
};

class fdown{
};

class fleft{
};

class fright{
};
