from web import Document, Template, dispatch
from bbox import BBox
from warnings import warn
from config import spatialdb 

formats = { 'text/xml': 'gml', 'application/rdf+xml': 'rdf', 'application/json':'json', 'application/atom+xml':'atom'}
bbox = BBox(spatial=spatialdb)

class Request(Document):
    # we should pass in a bbox object here, huh
    def outputformat(self):
	query = self.input
	if query.has_key('OUTPUTFORMAT'):
	    self.format = query['OUTPUTFORMAT'].value
	else:
	    self.format = 'text/xml'
	return formats[self.format]

    def bbox(self):
	return bbox

class GetFeature(Request):

    def GET(self,*args):
	"""Retrieve features from the DB. By default, returns everything,
	possibly limited in number by MAXFEATURES (what about paging?)	
	Results can be limited by BBOX and MINDATE and or MAXDATE
	and one can specify an alternative (but not optional?) OUTPUTFORMAT"""
	
	query = self.input
	features = []
	envelope = None

	box = mindate = maxdate = None
	if query.has_key('BBOX'): box = query['BBOX'].value
	if query.has_key('MINDATE'): mindate = query['MINDATE'].value
 	if query.has_key('MAXDATE'): maxdate = query['MAXDATE'].value	

	if box is not None:
	    # a simple form where there are 2 coordinates ( within_box() )
	    # a complex form where there are N points and an "optional crsuri"
	    # with no indication of how it's specified ( within_shape )
	    # plus, we may get an optional date start/end/range here.

	    points = box.split(',')
	    if len(points) is 4: 
	    	features = self.bbox().spatialStore.within_box(minx=points[0],miny=points[1],maxx=points[2],maxy=points[3],mindate=mindate,maxdate=maxdate)    
	    else:
		features = self.bbox().spatialStore.within_shape(points,mindate=mindate,maxdate=maxdate)
	elif mindate is not None or maxdate is not None:
    
	    features = self.bbox().spatialStore.within_date(mindate=mindate,maxdate=maxdate)
	if len(features) > 0:
	    
	    bounds = self.bbox().spatialStore.envelope(features)
	    envelope = ' '.join(bounds)

	format = self.outputformat()
	return self.output('feature.'+format,features = features,envelope=envelope,maintainer=self.bbox().maintainer_info())	


class DescribeFeatureType(Request):
    def GET(self, action, input):
	pass

class GetCapabilities(Request):
    def GET(self):
	keywords = []
	# what keywords would we return sensibly?
	# is it useful to human-speicify these? 
	# for some applications we can extract them from feed keywords
	# but the whole lot in response to a req. for Capabilities?
	# do keywords, to be honest even belong here?
	maintainer = self.bbox().maintainer_info()
        return self.output('capabilities.xml',maintainer= maintainer,keywords=[])

