/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// autogenerated file with codegen.pl

#include "preextstl.h"
#include "cppunit/TestAssert.h"
#include "cppunit/TestFixture.h"
#include "cppunit/extensions/HelperMacros.h"
#include "cppunit/plugin/TestPlugIn.h"
#include "postextstl.h"

#include <basegfx/vector/b2isize.hxx>
#include <basegfx/point/b2ipoint.hxx>

#include <basebmp/color.hxx>
#include <basebmp/scanlineformats.hxx>
#include <basebmp/bitmapdevice.hxx>
#include <basebmp/debug.hxx>
#include "tools.hxx"

#include <iostream>
#include <fstream>

using namespace ::basebmp;

namespace
{
/*
  std::ofstream output("32bpp_test.dump");
  debugDump( mpDevice32bpp, output );
*/

class BasicTest : public CppUnit::TestFixture
{
public:
    void colorTest()
    {
        Color aTestColor;

        aTestColor = Color(0xDEADBEEF);
        CPPUNIT_ASSERT_MESSAGE("unary constructor",
                               aTestColor.toInt32() == 0xDEADBEEF );

        aTestColor = Color( 0x10, 0x20, 0xFF );
        CPPUNIT_ASSERT_MESSAGE("ternary constructor",
                               aTestColor.toInt32() == 0x001020FF );

        aTestColor.setRed( 0x0F );
        CPPUNIT_ASSERT_MESSAGE("setRed()",
                               aTestColor.toInt32() == 0x00F20FF );

        aTestColor.setGreen( 0x0F );
        CPPUNIT_ASSERT_MESSAGE("setGreen()",
                               aTestColor.toInt32() == 0x00F0FFF );

        aTestColor.setBlue( 0x10 );
        CPPUNIT_ASSERT_MESSAGE("setBlue()",
                               aTestColor.toInt32() == 0x00F0F10 );

        aTestColor.setGrey( 0x13 );
        CPPUNIT_ASSERT_MESSAGE("setGrey()",
                               aTestColor.toInt32() == 0x00131313 );

        aTestColor = Color( 0x10, 0x20, 0xFF );
        CPPUNIT_ASSERT_MESSAGE("getRed()",
                               aTestColor.getRed() == 0x10 );
        CPPUNIT_ASSERT_MESSAGE("getGreen()",
                               aTestColor.getGreen() == 0x20 );
        CPPUNIT_ASSERT_MESSAGE("getBlue()",
                               aTestColor.getBlue() == 0xFF );

    }

    void testConstruction()
    {
        const basegfx::B2ISize aSize(101,101);
        basegfx::B2ISize       aSize2(aSize);
        BitmapDeviceSharedPtr pDevice( createBitmapDevice( aSize,
                                                           true,
                                                           Format::ONE_BIT_MSB_PAL ));
        CPPUNIT_ASSERT_MESSAGE("right size",
                               pDevice->getSize() == aSize2 );
        CPPUNIT_ASSERT_MESSAGE("Top down format",
                               pDevice->isTopDown() == true );
        CPPUNIT_ASSERT_MESSAGE("Scanline format",
                               pDevice->getScanlineFormat() == Format::ONE_BIT_MSB_PAL );
        CPPUNIT_ASSERT_MESSAGE("Scanline len",
                               pDevice->getScanlineStride() == (aSize2.getY() + 7)/8 );
        CPPUNIT_ASSERT_MESSAGE("Palette existence",
                               pDevice->getPalette() );
        CPPUNIT_ASSERT_MESSAGE("Palette entry 0 is black",
                               (*pDevice->getPalette())[0] == Color(0) );
        CPPUNIT_ASSERT_MESSAGE("Palette entry 1 is white",
                               (*pDevice->getPalette())[1] == Color(0xFFFFFFFF) );
    }

    void testPixelFuncs()
    {
        // 1bpp
        const basegfx::B2ISize aSize(64,64);
        BitmapDeviceSharedPtr pDevice( createBitmapDevice( aSize,
                                                           true,
                                                           Format::ONE_BIT_MSB_PAL ));

        const basegfx::B2IPoint aPt(3,3);
        const Color aCol(0xFFFFFFFF);
        pDevice->setPixel( aPt, aCol, DrawMode_PAINT );
        CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #1",
                               pDevice->getPixel(aPt) == aCol);

        const basegfx::B2IPoint aPt2(0,0);
        const Color aCol2(0xFFFFFFFF);
        pDevice->setPixel( aPt2, aCol2, DrawMode_PAINT );
        CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #2",
                               pDevice->getPixel(aPt2) == aCol2);

        const basegfx::B2IPoint aPt3(aSize.getX()-1,aSize.getY()-1);
        const Color aCol3(0x00000000);
        pDevice->setPixel( aPt3, aCol3, DrawMode_PAINT );
        CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #3",
                               pDevice->getPixel(aPt3) == aCol3);

        pDevice->setPixel( aPt3, aCol2, DrawMode_PAINT );
        CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #3.5",
                               pDevice->getPixel(aPt3) == aCol2);

        const basegfx::B2IPoint aPt4(-100000,-100000);
        pDevice->setPixel( aPt4, aCol3, DrawMode_PAINT );
        const basegfx::B2IPoint aPt5(100000,100000);
        pDevice->setPixel( aPt5, aCol3, DrawMode_PAINT );

        sal_Int32 nPixel(countPixel(pDevice, aCol2));
        const basegfx::B2IPoint aPt6(aSize.getX(),aSize.getY());
        pDevice->setPixel( aPt6, aCol2, DrawMode_PAINT );
        CPPUNIT_ASSERT_MESSAGE("setPixel clipping",
                               countPixel(pDevice, aCol2) == nPixel);

        CPPUNIT_ASSERT_MESSAGE("raw pixel value #1",
                               pDevice->getBuffer()[0] == 0x80);

        // 1bit LSB
        {
            pDevice = createBitmapDevice( aSize,
                                          true,
                                          Format::ONE_BIT_LSB_PAL );

            pDevice->setPixel( aPt2, aCol, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #4",
                                   pDevice->getPixel(aPt2) == aCol);

            const basegfx::B2IPoint aPt222(1,1);
            pDevice->setPixel( aPt222, aCol, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #5",
                                   pDevice->getPixel(aPt222) == aCol);

            pDevice->setPixel( aPt3, aCol, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #6",
                                   pDevice->getPixel(aPt3) == aCol);

            CPPUNIT_ASSERT_MESSAGE("raw pixel value #2",
                                   pDevice->getBuffer()[0] == 0x01);
            CPPUNIT_ASSERT_MESSAGE("raw pixel value #3",
                                   pDevice->getBuffer()[8] == 0x02);
        }

        // 8bit alpha
        {
            pDevice = createBitmapDevice( aSize,
                                          true,
                                          Format::EIGHT_BIT_GREY );

            const Color aCol4(0x010101);
            pDevice->setPixel( aPt, aCol4, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #4",
                                   pDevice->getPixel(aPt) == aCol4);

            const Color aCol5(0x0F0F0F);
            pDevice->setPixel( aPt2, aCol5, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #5",
                                   pDevice->getPixel(aPt2) == aCol5);

            const Color aCol6(0xFFFFFF);
            pDevice->setPixel( aPt3, aCol6, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #6",
                                   pDevice->getPixel(aPt3) == aCol6);
        }

        // 16bpp
        {
            pDevice = createBitmapDevice( aSize,
                                          true,
                                          Format::SIXTEEN_BIT_LSB_TC_MASK );
            const Color aCol7(0);
            pDevice->clear( aCol7 );

            const Color aCol4(0x00101010);
            pDevice->setPixel( aPt, aCol4, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #7",
                                   pDevice->getPixel(aPt) == aCol4);

            const Color aCol5(0x00F0F0F0);
            pDevice->setPixel( aPt2, aCol5, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #8",
                                   pDevice->getPixel(aPt2) != aCol7);

            const Color aCol6(0x00FFFFFF);
            pDevice->setPixel( aPt3, aCol6, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #9",
                                   pDevice->getPixel(aPt3) == aCol6);
        }

        // 24bpp
        {
            pDevice = createBitmapDevice( aSize,
                                          true,
                                          Format::TWENTYFOUR_BIT_TC_MASK );

            const Color aCol4(0x01010101);
            pDevice->setPixel( aPt, aCol4, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #10",
                                   pDevice->getPixel(aPt) == aCol4);

            const Color aCol5(0x0F3F2F1F);
            pDevice->setPixel( aPt2, aCol5, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #11",
                                   pDevice->getPixel(aPt2) == aCol5);

            const Color aCol6(0xFFFFFFFF);
            pDevice->setPixel( aPt3, aCol6, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #12",
                                   pDevice->getPixel(aPt3) == aCol6);

            CPPUNIT_ASSERT_MESSAGE("raw pixel value #4",
                                   pDevice->getBuffer()[2] == 0x3F
                                   && pDevice->getBuffer()[1] == 0x2F
                                   && pDevice->getBuffer()[0] == 0x1F);
        }

        // 32bpp
        {
            pDevice = createBitmapDevice( aSize,
                                          true,
                                          Format::THIRTYTWO_BIT_TC_MASK );

            const Color aCol4(0x01010101);
            pDevice->setPixel( aPt, aCol4, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #13",
                                   pDevice->getPixel(aPt) == aCol4);

            const Color aCol5(0x0F0F0F0F);
            pDevice->setPixel( aPt2, aCol5, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #14",
                                   pDevice->getPixel(aPt2) == aCol5);

            const Color aCol6(0xFFFFFFFF);
            pDevice->setPixel( aPt3, aCol6, DrawMode_PAINT );
            CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #15",
                                   pDevice->getPixel(aPt3) == aCol6);
        }
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(BasicTest);
    CPPUNIT_TEST(colorTest);
    CPPUNIT_TEST(testConstruction);
    CPPUNIT_TEST(testPixelFuncs);
    CPPUNIT_TEST_SUITE_END();
};

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION(BasicTest);
}

CPPUNIT_PLUGIN_IMPLEMENT();
