#! /usr/bin/python
# (c) Stephen Henrichsen JUN-2010
# Converts to int to avoid floating point errors.
#
class Point:
    def __init__(self, lat, lon):
        # Resolution  0.00001  --> self.Q = 100000
        #             0.000001 --> self.Q = 1000000
        self.Q = 100000 # IF CHANGED FIX BELOW
        self.MAXLON = 17999999 # 179 * self.Q
        self.MAXLAT =  8999999 #  89 * self.Q
        self.OUTLON = 18000000 # 180 * self.Q
        self.OUTLAT =  9000000 #  90 * self.Q
        
        self.ilat = int(lat*self.Q)
        self.ilon = int(lon*self.Q)

    def setLon(self, lon):
        self.ilon = int(lon*self.Q)

    def setLat(self, lat):
        self.ilat = int(lat*self.Q)

    def getLat(self):
        return float(self.ilat) / self.Q

    def getLon(self):
        return float(self.ilon) / self.Q

    def getX(self):
        if self.ilat >= 0:
            return '1' if self.ilon >= 0 else '7'
        return '3' if self.ilon >= 0 else '5'

    def getY(self, latdigit, londigit):
        if latdigit < 5:
            return '1' if londigit < 5 else '2'
        return '3' if londigit < 5 else '4'
             

    def getCSquare(self, res):
        res = int(res * self.Q)
        if res < 1:
            res = 1
        sb = [self.getX()]
        llat = abs(self.ilat)
        llon = abs(self.ilon)

        if llat >= self.OUTLAT:
            llat= self.MAXLAT

        if llon >= self.OUTLON:
            llon = self.MAXLON

        q = 10*self.Q
        i = llat / q
        j = llon / q
        sb.append(str(i))
        sb.append("%02d" % j)

        curr = 10*self.Q

        while curr > res:
            llat = llat - i*q
            llon = llon - j*q
            q /= 10
            i = llat / q
            j = llon / q
            curr /= 2 # 5 0.5 0.05 0.005 etc.

            sb.append(':')
            sb.append(self.getY(i,j))
            if curr > res:
                sb.append(str(i))
                sb.append(str(j))
                curr /= 5 # 1, 0.1 0.01 0.001 etc.

        return "".join(sb)

    def __str__(self):
        return "lat=%7.5f:lon=%7.5f c-square=%s" % (self.getLat(), self.getLon(), self.getCSquare(0.005))


if __name__ == '__main__':
    pt = Point(50.935789, -114.014351)
    print pt
    print pt.getCSquare(0.00001)
    pt = Point(-34.576123, -58.432261)
    print pt
    print pt.getCSquare(0.00001)
    pt = Point(-42.8, 147.3)
    print pt
    print pt.getCSquare(0.00001)

