#!/usr/bin/python

#   Copyright (C) 2002-2003 Yannick Gingras <ygingras@ygingras.net>
#   Copyright (C) 2002-2003 Vincent Barbin <vbarbin@openbeatbox.org>

#   This file is part of Open Beat Box.

#   Open Beat Box is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.

#   Open Beat Box is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.

#   You should have received a copy of the GNU General Public License
#   along with Open Beat Box; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


import unittest
from testsPath import *
from qt import *
from OBBGui.ImageLoader import ImageLoader
from OBBFuncts import kickApp, getImgDir, printPoint
import sys
import os
import time

TEST_IMG = "unittest.png"
TEST_IMG_PATH = os.path.join(getImgDir(), TEST_IMG)

IMG_WIDTH  = 100
IMG_HEIGHT = 100
LOS_WIDTH  = 100
LOS_HEIGHT = 100
BACK_COL  = (0, 0, 255)
FRONT_COL = (0, 255, 0)

def makeTestImage(filename):
    """create the image used by the test suite : 
    a losange on a plain background"""
    backCol = QColor(*BACK_COL)
    frontCol = QColor(*FRONT_COL)
    pixmap = QPixmap( IMG_WIDTH, IMG_HEIGHT )
    pixmap.fill(backCol)
    painter = QPainter(pixmap)

    coords = [ IMG_WIDTH/2,   IMG_HEIGHT/4,
               IMG_WIDTH*3/4, IMG_HEIGHT/2,
               IMG_WIDTH/2,   IMG_HEIGHT*3/4,
               IMG_WIDTH/4,   IMG_HEIGHT/2 ]

    pArray = QPointArray(coords)
    painter.setBrush(frontCol)
    painter.setPen(frontCol)
    painter.drawPolygon(pArray)
    painter.end()
    pixmap.save(filename, "PNG")
    

class LoaderInitTest(unittest.TestCase):
    def runTest(self):
        loader = ImageLoader()
        self.failUnless( loader != None )

class LoaderEmptyTest(unittest.TestCase):
    """raise if the image is not present"""
    def runTest(self):
        # kick the test image if present
        if os.path.exists(TEST_IMG_PATH):
            os.unlink(TEST_IMG_PATH)
        loader = ImageLoader()
        self.failUnlessRaises( Exception,
                               loader.loadPixmap,
                               TEST_IMG_PATH )

class LoaderCropTest(unittest.TestCase):
    """loaded images should be smaller the originals"""
    def runTest(self):
        loader = ImageLoader()
        makeTestImage(TEST_IMG_PATH)
        pix = loader.loadPixmap(TEST_IMG_PATH)
        orig = QPixmap(TEST_IMG_PATH)
        self.failUnless(pix.height() < orig.height())
        self.failUnless(pix.width() < orig.width())

class LoaderNoReCropTest(unittest.TestCase):
    """loaded images should not be recroped if a croped
    version is avaiable"""
    def setUp(self):
        # ensure cache is on disk
        makeTestImage(TEST_IMG_PATH)
        
        # have at least 1 sec of timestamp between cache and orig
        time.sleep(1)
        
        ImageLoader().loadPixmap(TEST_IMG_PATH)

    def runTest(self):
        loader = ImageLoader()
        mTime = os.path.getmtime(loader.makeCacheName(TEST_IMG_PATH))

        if time.time() <= mTime+1:
            # try at least 1 sec after last modification
            time.sleep(1)
            
        loader.loadPixmap(TEST_IMG_PATH)
        newMTime = os.path.getmtime(loader.makeCacheName(TEST_IMG_PATH))
        self.failUnless(newMTime == mTime)

class LoaderTimestampTest(unittest.TestCase):
    """images should be recroped if the timestamp of the original change"""
    def setUp(self):
        # ensure cache is on disk
        makeTestImage(TEST_IMG_PATH)
        ImageLoader().loadPixmap(TEST_IMG_PATH)

    def runTest(self):
        loader = ImageLoader()
        mTime = os.path.getmtime(loader.makeCacheName(TEST_IMG_PATH))

        if time.time() <= mTime+1:
            # try at least 1 sec after last modification
            time.sleep(1)

        makeTestImage(TEST_IMG_PATH)
        loader.loadPixmap(TEST_IMG_PATH)
        newMTime = os.path.getmtime(loader.makeCacheName(TEST_IMG_PATH))
        self.failUnless(newMTime > mTime)

class LoaderBrokenCacheTest(unittest.TestCase):
    """things are out of control if the croped image is bigger that
    the original"""
    def setUp(self):
        # ensure cache is on disk
        makeTestImage(TEST_IMG_PATH)
        ImageLoader().loadPixmap(TEST_IMG_PATH)

    def runTest(self):
        loader = ImageLoader()

        mTime = os.path.getmtime(loader.makeCacheName(TEST_IMG_PATH))

        if time.time() <= mTime+1:
            # try at least 1 sec after last modification
            time.sleep(1)

        pixmap = QPixmap(IMG_WIDTH*2, IMG_HEIGHT*2)
        pixmap.save(loader.makeCacheName(TEST_IMG_PATH), "PNG")
        
        self.failUnlessRaises( Exception,
                               loader.loadPixmap,
                               TEST_IMG_PATH )

def suite():
    testSuite = unittest.TestSuite()
    testSuite.addTest(LoaderInitTest())
    testSuite.addTest(LoaderEmptyTest())
    testSuite.addTest(LoaderCropTest())
    testSuite.addTest(LoaderNoReCropTest())
    testSuite.addTest(LoaderTimestampTest())
    testSuite.addTest(LoaderBrokenCacheTest())
    return testSuite

if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    runner = unittest.TextTestRunner()
    runner.run( suite() )

    kickApp(app)
