#include "bilinear.h"


QImage rotate (QImage img, double psi)
{
    double ccos = cos(psi);
    double ssin = sin(psi);

    int width = img.width();
    int height = img.height();
    int xCenter =  width/2;
    int yCenter = height/2;

    QImage out(width,height,img.format());
    out.fill(qRgb(0,0,0));

    for (int i = 0; i < width; ++i)
        for (int j = 0; j < height; ++j)
        {
            if ( (i == xCenter)&&(j == yCenter) )
            {
                out.setPixel(i,j,img.pixel(i,j));
                continue;
            }

            int x = i - xCenter;
            int y = yCenter - j;

            double trueX = x*ccos - y*ssin;
            double trueY = x*ssin + y*ccos;

            trueX = trueX + xCenter;
            trueY =yCenter - trueY;

            int floorX = (int)trueX;
            int ceilX(floorX);
            if (floorX != trueX)
                ceilX++;

            int floorY = (int)trueY;
            int ceilY(floorY);
            if (floorY != trueY)
                ceilY++;


            if (ceilX==width)
            {
                trueX--;
                floorX = (int)trueX;
                ceilX=floorX;
                if (floorX != trueX)
                    ceilX++;

                floorY = (int)trueY;
                ceilY=floorY;
                if (floorY != trueY)
                    ceilY++;
            }
            if (ceilY==height)
            {
                trueY--;
                floorX = (int)trueX;
                ceilX=floorX;
                if (floorX != trueX)
                    ceilX++;

                floorY = (int)trueY;
                ceilY=floorY;
                if (floorY != trueY)
                    ceilY++;
            }

            if ( floorX < 0 || ceilX >= width || floorY < 0 || ceilY >= height )
            {

                continue;

            }



            double deltaX = trueX - (double)floorX;
            double deltaY = trueY - (double)floorY;

            QRgb clrTopLeft = img.pixel(floorX,floorY);
            QRgb clrTopRight = img.pixel(ceilX,floorY);
            QRgb clrBottomLeft = img.pixel(floorX,ceilY);
            QRgb clrBottomRight = img.pixel(ceilX,ceilY);

            double redTop = (1 - deltaX)*qRed(clrTopLeft) + deltaX*qRed(clrTopRight);
            double blueTop = (1 - deltaX)*qBlue(clrTopLeft) + deltaX*qBlue(clrTopRight);
            double greenTop = (1 - deltaX)*qGreen(clrTopLeft) + deltaX*qGreen(clrTopRight);

            double redBottom = (1 - deltaX)*qRed(clrBottomLeft) + deltaX*qRed(clrBottomRight);
            double blueBottom = (1 - deltaX)*qBlue(clrBottomLeft) + deltaX*qBlue(clrBottomRight);
            double greenBottom = (1 - deltaX)*qGreen(clrBottomLeft) + deltaX*qGreen(clrBottomRight);

            int red = (int)((1 - deltaY)*redTop + deltaY*redBottom + 0.5);
            int blue = (int)((1 - deltaY)*blueTop + deltaY*blueBottom + 0.5);
            int green = (int)((1 - deltaY)*greenTop + deltaY*greenBottom + 0.5);

            if (red < 0) red = 0;
            if (red > 255) red = 255;
            if (green < 0) green = 0;
            if (green > 255) green = 255;
            if (blue < 0) blue = 0;
            if (blue > 255) blue = 255;


            out.setPixel(i,j,qRgb(red,green,blue));
        }
    return out;
}

QImage zoom (QImage img, double mul)
{

    int width = (int)img.width()*mul;
    int height = (int)img.height()*mul;
    int xCenter =  width/2;
    int yCenter = height/2;

    QImage out(width,height,img.format());
   // out.fill(qRgb(0,0,0));

    for (int i = 0; i < width; ++i)
        for (int j = 0; j < height; ++j)
        {
           /* if ( (i == xCenter)&&(j == yCenter) )
            {
                out.setPixel(i,j,img.pixel(i,j));
                continue;
            }*/

            int x = i - xCenter;
            int y = yCenter - j;

            double trueX = x/mul;
            double trueY = y/mul;

            trueX = trueX + xCenter/mul;
            trueY =yCenter/mul - trueY;

            int floorX = (int)trueX;
            int ceilX(floorX);
            if (floorX != trueX)
                ceilX++;

            int floorY = (int)trueY;
            int ceilY(floorY);
            if (floorY != trueY)
                ceilY++;

            if ( floorX < 0 || ceilX >= width/mul || floorY < 0 || ceilY >= height/mul )
            {

                continue;

            }



            double deltaX = trueX - (double)floorX;
            double deltaY = trueY - (double)floorY;

            QRgb clrTopLeft = img.pixel(floorX,floorY);
            QRgb clrTopRight = img.pixel(ceilX,floorY);
            QRgb clrBottomLeft = img.pixel(floorX,ceilY);
            QRgb clrBottomRight = img.pixel(ceilX,ceilY);

            double redTop = (1 - deltaX)*qRed(clrTopLeft) + deltaX*qRed(clrTopRight);
            double blueTop = (1 - deltaX)*qBlue(clrTopLeft) + deltaX*qBlue(clrTopRight);
            double greenTop = (1 - deltaX)*qGreen(clrTopLeft) + deltaX*qGreen(clrTopRight);

            double redBottom = (1 - deltaX)*qRed(clrBottomLeft) + deltaX*qRed(clrBottomRight);
            double blueBottom = (1 - deltaX)*qBlue(clrBottomLeft) + deltaX*qBlue(clrBottomRight);
            double greenBottom = (1 - deltaX)*qGreen(clrBottomLeft) + deltaX*qGreen(clrBottomRight);

            int red = (int)((1 - deltaY)*redTop + deltaY*redBottom + 0.5);
            int blue = (int)((1 - deltaY)*blueTop + deltaY*blueBottom + 0.5);
            int green = (int)((1 - deltaY)*greenTop + deltaY*greenBottom + 0.5);

            if (red < 0) red = 0;
            if (red > 255) red = 255;
            if (green < 0) green = 0;
            if (green > 255) green = 255;
            if (blue < 0) blue = 0;
            if (blue > 255) blue = 255;


            out.setPixel(i,j,qRgb(red,green,blue));
        }

    return out;

}
