###############################################################################
##                                                                           ##
##                        ALEXANDRIA DIGITAL LIBRARY                         ##
##                 University of California at Santa Barbara                 ##
##                                                                           ##
## ------------------------------------------------------------------------- ##
##                                                                           ##
##     Copyright (c) 2005 by the Regents of the University of California     ##
##                            All rights reserved                            ##
##                                                                           ##
## Redistribution and use in source and binary forms, with or without        ##
## modification, are permitted provided that the following conditions are    ##
## met:                                                                      ##
##                                                                           ##
##     1. Redistributions of source code must retain the above copyright     ##
##        notice, this list of conditions, and the following disclaimer.     ##
##                                                                           ##
##     2. Redistributions in binary form must reproduce the above copyright  ##
##        notice, this list of conditions, and the following disclaimer in   ##
##        the documentation and/or other materials provided with the         ##
##        distribution.                                                      ##
##                                                                           ##
##     3. All advertising materials mentioning features or use of this       ##
##        software must display the following acknowledgement: This product  ##
##        includes software developed by the Alexandria Digital Library,     ##
##        University of California at Santa Barbara, and its contributors.   ##
##                                                                           ##
##     4. Neither the name of the University nor the names of its            ##
##        contributors may be used to endorse or promote products derived    ##
##        from this software without specific prior written permission.      ##
##                                                                           ##
## THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY ##
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ##
## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE   ##
## DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR  ##
## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL    ##
## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS   ##
## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)     ##
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,       ##
## STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN  ##
## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           ##
## POSSIBILITY OF SUCH DAMAGE.                                               ##
##                                                                           ##
###############################################################################

# $Header: /export/home/gjanee/mm/bucket_types/RCS/spatial.py,v 1.1 2005/02/10 23:54:10 gjanee Exp $

# DESCRIPTION
#
#     The "spatial" bucket type.
#
# AUTHOR
#
#     Greg Janee
#     gjanee@alexandria.ucsb.edu
#
# HISTORY
#
#     $Log: spatial.py,v $
#     Revision 1.1  2005/02/10 23:54:10  gjanee
#     Initial revision
#

from ADL_mapper import bucketType, fatal
from bucket_types.utils import checkValue, encodeField, fieldErrorClause

def _validate (bucket, field, value, strict):
    value = checkValue(bucket, "spatial", ["!!", "!!!!"], field, value, strict)
    if value == None: return None
    newValue = []
    for i, v in enumerate(value):
        v = _validateCoordinate(bucket, field, v,
            90.0 + (2*i/len(value))*90.0, strict)
        if v == None: return None
        newValue.append(v)
    value = newValue
    if len(value) == 4:
        if value[0] < value[1]:
            if strict:
                fatal(("invalid value mapped to spatial bucket '%s'%s:" +\
                    " north < south: %s < %s") % (bucket,
                    fieldErrorClause(field), str(value[0]), str(value[1])))
            else:
                return None
        if value[0] == value[1] and value[2] == value[3]:
            value = [value[0], value[2]]
    return (field, tuple(value))

def _validateCoordinate (bucket, field, coord, limit, strict):
    try:
        v = float(coord)
    except ValueError:
        if strict:
            fatal(("invalid value mapped to spatial bucket '%s'%s:" +\
                " invalid number: %s") % (bucket, fieldErrorClause(field),
                coord))
        else:
            return None
    if abs(v) > limit:
        if strict:
            fatal(("invalid value mapped to spatial bucket '%s'%s:" +\
                " coordinate out of range: %s") % (bucket,
                fieldErrorClause(field), coord))
        else:
            return None
    return v

def _encode (document, field, value):
    sv = document.createElement("spatial-value")
    encodeField(document, sv, field)
    if len(value) == 2:
        p = document.createElement("point")
        elementNames = ["latitude", "longitude"]
    else:
        p = document.createElement("box")
        elementNames = ["north", "south", "east", "west"]
    for n, v in zip(elementNames, value):
        e = document.createElement(n)
        e.appendChild(document.createTextNode(str(v)))
        p.appendChild(e)
    sv.appendChild(p)
    return sv

bucketType("spatial", _validate, _encode)
