#!/usr/bin/python
# -*- utf-8 -*-

import xml.parsers.expat
import math
import time

class Node(object):
    def __init__(self, nid, lat, lon):
        self.nid = nid
        self.lat = lat
        self.lon = lon
        self.tag = dict()
        self.member_of = list()

    def __id__(self):
        return self.nid

    def __repr__(self):
        if 'name' in self.tag:
            return "Node(%ld, %s)" % (self.nid, self.name)
        else:
            return "Node(%ld)" % self.nid

    def __str__(self):
        return str(self.nid)

class Way(object):
    def __init__(self, wid):
        self.wid = wid
        self.nodes = list()
        self.tag = dict()
        self.member_of = list()

    def __id__(self):
        return self.wid

    def __repr__(self):
        if 'name' in self.tag:
            return "Way(%ld, %s)" % (self.wid, self.tag['name'])
        else:
            return "Way(%ld)" % self.wid

    def __str__(self):
        return str(self.wid)

class Relation(object):
    def __init__(self, rid):
        self.rid = rid
        self.members = list()
        self.tag = dict()

    def __id__(self):
        return self.rid

    def __str__(self):
        return str(self.rid)

class OsmParser(object):
    def __init__(self):
        self.parser = xml.parsers.expat.ParserCreate()
        self.parser.StartElementHandler = self._start_element
        self.parser.EndElementHandler = self._end_element
        #self.parser.CharacterDataHandler = self._char_data

    def _start_element(self, name, attrs):
        #print 'Start element:', name, attrs
        if name == 'tag':
            k = attrs['k']
            v = attrs['v']
            if self.current_node is not None:
                self.current_node.tag[k] = v
            elif self.current_way is not None:
                self.current_way.tag[k] = v
            elif self.current_relation is not None:
                self.current_relation.tag[k] = v
            else:
                raise Exception('Parse error: tag is not attached to either a node, way or relation')
        elif name == 'node':
            nid = long(attrs['id'])
            self.current_node = Node(nid, float(attrs['lat']), float(attrs['lon']))
            self.nodes[nid] = self.current_node
        elif name == 'nd':
            if self.current_way is not None:
                nid = long(attrs['ref'])
                node = self.nodes[nid]
                node.member_of.append(self.current_way)
                self.current_way.nodes.append(node)
        elif name == 'way':
            wid = long(attrs['id'])
            self.current_way = Way(wid)
            ts, zone = attrs['timestamp'].rsplit('+', 1)
            self.current_way.timestamp = \
                    time.mktime(time.strptime(ts, "%Y-%m-%dT%H:%M:%S"))
            if 'user' in attrs:
                self.current_way.user = attrs['user']
            else:
                self.current_way.user = None
            self.ways[wid] = self.current_way
        elif name == 'member':
            if self.current_relation is not None:
                mid = long(attrs['ref'])
                if attrs['type'] == 'way':
                    member = self.ways[mid]
                elif attrs['type'] == 'node':
                    member = self.nodes[mid]
                else:
                    raise Exception('Unknown type for member')
                member.member_of.append(self.current_relation)
                self.current_relation.members.append(member)
        elif name == 'relation':
            rid = long(attrs['id'])
            self.current_relation = Relation(rid)
            self.relations[rid] = self.current_relation
        elif name == 'bound':
            pass
        elif name == 'osm':
            if float(attrs['version']) < 0.5:
                raise Exception("file version to old (< 0.5)")

    def _end_element(self, name):
        #print 'End element:', name
        if name == 'node':
            self.current_node = None
        elif name == 'way':
            self.current_way = None
        elif name == 'relation':
            self.current_relation = None
            
    def parse_file(self, fh):
        self.nodes = {}
        self.ways = {}
        self.relations = {}
        self.current_node = None
        self.current_way = None
        self.current_relation = None
        self.parser.ParseFile(fh)

if __name__ == '__main__':
    import sys
    parser = OsmParser()
    f = file(sys.argv[1], 'r')
    parser.parse_file(f)
    f.close()

    if True:
        print "%d nodes, %d ways, %d relations" % (
                len(parser.nodes),
                len(parser.ways),
                len(parser.relations),
            )

    datets = time.mktime(time.strptime('2008-01-28 16:00', '%Y-%m-%d %H:%M'))
    result = list()
    for wid, way in parser.ways.iteritems():
        #print way.timestamp, way.user
        #if (datets < way.timestamp < (datets + 86400)) and way.user == 'mbuege':
        if (datets < way.timestamp) and way.user == 'mbuege':
            if ('highway' in way.tag) and way.tag['highway'] == "pedestrian":
                if 'name' in way.tag:
                    print way.wid, way.tag['name']
                else:
                    print way.wid, "noname!"

