# -*- coding:latin1 -*-

# Copyright (c) 2004 by Intevation GmbH
# Authors:
# Jan Schüngel <jschuengel@intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with Thuban for details.

"""
Tests for UMN Mapserver extension.
"""

__version__ = "$Revision: 2858 $"
# $Source$
# $Id: test_mapserver.py 2858 2008-07-29 06:17:34Z elachuni $

# Import the testmodul from python
import unittest

import mapscript
from mapscript import mapObj

# Import  necessary classes from Thuban
from Thuban.Model.color import Color, Transparent

from Thuban.Model.proj import Projection

# Import the Classes to test
from Extensions.umn_mapserver.mapfile import MF_Color, \
    MF_Rectangle, MF_Style, MF_Map, MF_Projection, \
    MF_Class, MF_Layer, MF_Metadata, MF_Outputformat, \
    MF_Symbol, MF_SymbolSet, MF_Scalebar, \
    MF_Label, MF_Legend, MF_Web

from Extensions.umn_mapserver.mapfile import shp_type

from Extensions.umn_mapserver.mf_import import create_rangeexpression

class mapserver_generalClasses(unittest.TestCase):

    def setUp(self):
        """
        Running this funktion befor each test
        """
        # using the sample map
        testMapfile = 'test.map'
        self.testMap = mapObj(testMapfile)
        self.eq = self.assertEquals


    def test_MF_Color(self):
        """
        Testing Color Objects from MapServer.
        """
        # IMAGECOLOR  255 255 255
        testcolor = MF_Color(self.testMap.imagecolor)
        self.eq(testcolor.get_red(), 255)
        self.eq(testcolor.get_green(), 255)
        self.eq(testcolor.get_blue(), 255)
        
        # set Color with Thuban color obj
        testthubancolor = Color(0.5,1,0)
        testcolor.set_thubancolor(testthubancolor)
        self.eq(testcolor.get_red(),127)
        self.eq(testcolor.get_green(),255)
        self.eq(testcolor.get_blue(),0)
        
        # check if Thubancolor is set correct
        testtbcolor = testcolor.get_thubancolor()
        self.eq(testtbcolor.red, 0.5)
        self.eq(testtbcolor.green, 1)
        self.eq(testtbcolor.blue, 0)


    def test_MF_Rectangle(self):
        """
        Testing rectangle objects by example like
        the mapfile parameter extent.
        """
        # EXTENT  622877.17 7019306.94 1095667.78 7447709.31 
        testrect = MF_Rectangle(self.testMap.extent)        
        self.eq(testrect.get_minx(), 622877.17)
        self.eq(testrect.get_miny(), 7019306.94)
        self.eq(testrect.get_maxx(), 1095667.78)
        self.eq(testrect.get_maxy(), 7447709.31)
        
        # Set a new Rectangle and test if is set correctly
        testrect.set_rect(50,50,200,200)
        self.eq(testrect.get_rect(), (50,50,200,200))
        self.eq(testrect.get_minx(), 50)
        self.eq(testrect.get_miny(), 50)
        self.eq(testrect.get_maxx(), 200)
        self.eq(testrect.get_maxy(), 200)


    def test_MF_Metadata(self):
        """
        Testing the meta data
        """
        # set up to keys to test
        testmetadata = MF_Metadata(self.testMap)
        self.eq(self.testMap.getMetaData("titel"), "Iceland Test")
        testmetadata.add_metadata("test", "test eintrag")
        self.eq(testmetadata.get_metadatabykey("test"),"test eintrag")
        
        # generate the MetaData from the testMap
        testMap2 = MF_Map(self.testMap)
        testmetadata = testMap2.get_metadata()
        self.eq(testmetadata.get_metadatabykey("titel"),"Iceland Test")


class mapserver_Classes(unittest.TestCase):

    def setUp(self):
        """
        Running this funktion befor each test
        """
        # using the sample map
        testMapfile = 'test.map'
        self.testMap = mapObj(testMapfile)
        self.eq = self.assertEquals


    def test_MF_OutputFormat(self):
        """
        Testing the outputformat object
        """
        testoutputformat = MF_Outputformat(self.testMap.getOutputFormatByName("png"))
        self.eq(testoutputformat.get_name(),"png")


    def test_MF_Symbolset(self):
        """
        Testing the symbolset
        """
        testsymbolset = MF_SymbolSet(self.testMap.symbolset)
        self.eq(testsymbolset.get_symbol(1).get_name(), "circle") 


    def test_MF_Symbol(self):
        """
        Testing the symbol object
        """
        testsymbol = MF_Symbol(self.testMap.symbolset.getSymbolByName("circle"))
        self.eq(testsymbol.get_name(), "circle")
        assert(testsymbol.get_symbolObj(), self.testMap.symbolset.getSymbolByName("circle"))
        
        testsymbol.set_filled(True)
        self.eq(testsymbol.get_filled(), True)
        
        testsymbol.set_type(4)
        self.eq(testsymbol.get_type(), 4)


    def test_MF_Class(self):
        """
        Testing the class object.
        """        
        # only test the number of styles at the moment
        testclass = MF_Class(self.testMap.getLayer(0).getClass(0))
        self.eq (len(testclass.get_styles()), self.testMap.getLayer(0).getClass(0).numstyles)

        # check the name
        self.eq(testclass.get_name(), "testclass")
        testclass.set_name("checkout")
        self.eq(testclass.get_name(), "checkout")

        # check the expressionstring
        testclass = MF_Class(self.testMap.getLayer(2).getClass(0))
        self.eq(testclass.get_expressionstring(), '"9"')
        testclass.set_expressionstring("3")
        self.eq(testclass.get_expressionstring(), '"3"')


    def test_MF_Layer(self):
        """
        Testing the layer object with some
        sample data and classes.
        """
        testlayer = MF_Layer(self.testMap.getLayer(2))
        # NAME 'political' only from layer 1
        self.eq(testlayer.get_name(), 'cultural')
        testlayer.set_name('checkout')
        self.eq(testlayer.get_name(), 'checkout')        
        # check number of classes
        self.eq(len(testlayer.get_classes()), self.testMap.getLayer(2).numclasses)
        # check classitem
        self.eq(testlayer.get_classitem(), "CLPOINT_")
        testlayer.set_classitem("CLCHECK")
        self.eq(testlayer.get_classitem(), "CLCHECK")
        # check data
        self.eq(testlayer.get_data(), "cultural_landmark-point")
        testlayer.set_data("test.shp")
        # .shp will be cutted becouse the source is always a .shp,
        # or maybe a grafik
        self.eq(testlayer.get_data(), "test")
        # check projection (used the pojection obj a little bit)
        self.eq(testlayer.get_projection().get_projection(), "+proj=latlong +ellps=clrk66")
        # TYPE POLYGON
        self.eq(testlayer.get_type(), "point")
        testlayer.set_type("circle")
        self.eq(testlayer.get_type(), "circle")
        # Check status
        # 0 = off, 1 = on, 2 = default
        self.eq(testlayer.get_status(), True)
        testlayer.set_status(False)
        self.eq(testlayer.get_status(), False)


    def test_MF_Map(self):
        """
        Testing the mapfile object with samples.
        """
        testMapp = MF_Map(self.testMap)
        # NAME 'ISLAND'
        self.eq(testMapp.get_name(), 'ISLAND')
        self.eq(len(testMapp.get_layers()), self.testMap.numlayers)
    
        # test see in test_MF_Projection
        testproj = Projection(['proj=utm', 'ellps=clrk66', 'zone=26', 'north'])
        testMapp.set_projection(testproj)
        self.eq(testMapp.get_projection().get_params(), ['proj=utm', 'ellps=clrk66', 'zone=26', 'north'])
        
        self.eq(testMapp.get_size(), (600,450))
        testMapp.set_size(500,600)
        self.eq(testMapp.get_size(), (500,600))


    def test_MF_Scalebar(self):
        """
        Test the Scalebarobj from the testfile
        """
        testscalebar = MF_Scalebar(self.testMap.scalebar)
        self.eq(testscalebar.get_position(mode="string"),"ll")
        self.eq(testscalebar.get_position(), mapscript.MS_LL)
        self.eq(testscalebar.get_intervals(), 4)
        self.eq(testscalebar.get_status(mode="string"), "OFF")


    def test_MF_Label(self):
        """
        Test a Label object. In this test use the Label from 
        from the Scalebarobj in the testfile
        """
        testlabel = MF_Label(self.testMap.scalebar.label)
        self.eq(testlabel.get_force(), False)
        self.eq(testlabel.get_buffer(),0)
        self.eq(testlabel.get_type(), "bitmap") 


    def test_MF_Legend(self):
        """
        test the legend object from the testfile
        """
        testlegend = MF_Legend(self.testMap.legend)
        self.eq(testlegend.get_status(), False)
        testlegend.set_status(True)
        self.eq(testlegend.get_status(), True)
        testlegend.set_position("ul")
        self.eq(testlegend.get_position(mode="string"), "ul")
        testlegend.set_keyspacing(4,5)
        self.eq(testlegend.get_keyspacing(), (4,5))
        testlegend.set_keysize(6,7)
        self.eq(testlegend.get_keysize(), (6,7))


    def test_MF_Projection(self):
        """
        Projection object is tested with parameters
        and an epsg code.
        """
        # proj=utm
        # ellps=clrk66
        # zone=26
        # north
        testproj = MF_Projection(self.testMap.getProjection())
        if testproj.get_params():
            self.eq(testproj.get_params(), ['proj=utm','ellps=WGS84','zone=26','north']) 
        
        #"init=epsg:26915"
        if testproj.get_epsgcode():
            self.eq(testproj.get_epsgcode(), '26915') 


    def test_MF_Style(self):
        """
        Tests a style object with all parameters.
        """
        teststyle = MF_Style(self.testMap.getLayer(0).getClass(0).getStyle(0))
        # OUTLINECOLOR 0 0 0
        self.eq(teststyle.get_outlinecolor().get_red(), 0)
        # COLOR 100 200 100
        self.eq(teststyle.get_color().get_red(), 100)
        self.eq(teststyle.get_color().get_green(), 200)
        self.eq(teststyle.get_color().get_blue(), 100)
        # SIZE 2
        self.eq(teststyle.get_size(), 2)


    def test_MF_Web(self):
        """
        Tests a web object
        """
        testweb = MF_Web(self.testMap.web)
        self.eq(testweb.get_imagepath(), "/tmpimg/")
        testweb.set_imagepath("/tmppathset/")
        self.eq(testweb.get_imagepath(), "/tmppathset/")
        self.eq(testweb.get_imageurl(),"/tmpurl/")
        testweb.set_imageurl("/tmpurlset/")
        self.eq(testweb.get_imageurl(), "/tmpurlset/")


class mapserver_mf_import(unittest.TestCase):

    def setUp(self):
        """
        Running this funktion befor each test
        """
        # using the sample map
        testMapfile = 'test.map'
        self.testMap = mapObj(testMapfile)
        self.eq = self.assertEquals


    def test_create_rangeexpression(self):
        """
        testing the range expression creation from the code in the mapfile
        """
        # the expressions to test
        # these expresions are like in thuban
        test1 = "([ATTR] >= 1 AND [ATTR] <= 100)" # [min,max]
        code,expr = create_rangeexpression(test1[1:-1])
        self.eq(code, "ATTR")
        self.eq(expr,"[1;100]")
        test2 = "([ATTR] >= 1 AND [ATTR] < 100)" # [min,max[
        code,expr = create_rangeexpression(test2[1:-1])
        self.eq(code, "ATTR")
        self.eq(expr,"[1;100[")
        test3 = "([ATTR] > 1 AND [ATTR] <= 100)" # ]min,max]
        code,expr = create_rangeexpression(test3[1:-1])
        self.eq(code, "ATTR")
        self.eq(expr,"]1;100]")
        test4 = "([ATTR] > 1 AND [ATTR] < 100)" # ]min,max[
        code,expr = create_rangeexpression(test4[1:-1])
        self.eq(code, "ATTR")
        self.eq(expr,"]1;100[")
        
        test5 = "([ATTR] <= 100)" # [-oo,max] , ]-oo,max]
        code,expr = create_rangeexpression(test5[1:-1])
        self.eq(code, "ATTR")
        self.eq(expr,"[-oo;100]")
        test6 = "([ATTR] < 100)" # [-oo,max[ , ]-oo,max[
        code,expr = create_rangeexpression(test6[1:-1])
        self.eq(code, "ATTR")
        self.eq(expr,"[-oo;100[")
        test7 = "([ATTR] >= 1)" # [min,oo] , [min, oo[
        code,expr = create_rangeexpression(test7[1:-1])
        self.eq(code, "ATTR")
        self.eq(expr,"[1;oo]")
        test8 = "([ATTR] > 1)" # ]min,oo] , ]min, oo[
        code,expr = create_rangeexpression(test8[1:-1])
        self.eq(code, "ATTR")
        self.eq(expr,"]1;oo]")
        
        # value equal, works but is not really usefull
        test9= "([ATTR] < 1 AND [ATTR] >= 1)"
        code,expr = create_rangeexpression(test9[1:-1])
        self.eq(code, "ATTR")
        self.eq(expr,"[1;1[")
        
        # works but must be changed the order
        test10= "([ATTR] <= 100 AND [ATTR] >= 1)"
        code,expr = create_rangeexpression(test10[1:-1])
        self.eq(code, "ATTR")
        self.eq(expr,"[1;100]")
        
        #singleton not implemented yet
        test11 = "([ATTR] = 1)"
        code,expr = create_rangeexpression(test11[1:-1])
        self.eq(code, None)
        self.eq(expr,"singleton creation not implemented yet")

        # Attributes not equal
        test12= "([ATTR] < 100 AND [ATTR2] >= 1)"
        code,expr = create_rangeexpression(test12[1:-1])
        self.eq(code, None)
        self.eq(expr,"Attributes not equal")
        # dont works, is not supported by thuban
        test13="([ATTR] > 100 AND [ATTR] < 1)"
        code,expr = create_rangeexpression(test13[1:-1])
        self.eq(code, None)
        self.eq(expr,"values are wrong")


if __name__ == '__main__':
    unittest.main()
