#!/usr/bin/env python

# STD Python modules
# import exceptions
# import StringIO
import copy
import exceptions
import numpy
import re

# Third party modules
import pandas

# Model modules
import event

__author__ = 'sdukesy'

class Landscape(object):
    def __init__(self):
        self.data     = None
        self.columns  = None

    def copy(self, obj):
        self.data     = copy.deepcopy(obj.data)

    def read_from_stream(self, stream, numLocs=None):
        if self.data is None or stream.tell() == 0:
            self.data     = pandas.read_csv(stream, nrows=numLocs)
            self.columns  = copy.copy(self.data.columns)
        else:
            self.data     = pandas.read_csv(stream, header=0, names=self.data.columns, nrows=numLocs)

        try:
            self.data.set_index('CellID', inplace=True)
        except exceptions.ValueError:
            errMsg  = 'Landscape: Error: ValueError exception raised while reading from stream.\n'
            errMsg += 'Landscape: Error: I think this means that CellID is not defined in the file\n'
            errMsg += 'Landscape: Error: being read. Check on that and try again.\n'
            errMsg += 'Landscape: Error: Note that spaces matter, which is kind of annoying, but there it is.'
            raise exceptions.RuntimeError(errMsg)

        #if not('CELLID' in self.data.columns):
        #    msg  = 'Landscape: Error: Could not find index column \"CELLID\" in input data.\n'
        #    msg += 'Landscape: Error: This is needed to make things work. Fix it and come back later.\n'
        #    raise exceptions.RuntimeError(msg)

    def iterlocs(self):
        return self.data.iterrows()

    def write_to_stream(self, stream, header=True, time=None):
        self.data.to_csv(stream, index=False, header=header)

    def __getitem__(self, cellID):
        return self.data.loc[int(cellID)]

    def __str__(self):
        return 'Landscape.__str__() not implemented'

class WriteLandscape(event.Event):
    def __init__(self, time=(0,0), name='WriteLandscape', landscape=None, stream = None, header=True):
        event.Event.__init__(self, time, name)
        self.landscape = landscape
        self.stream    = stream
        self.header    = header

    def write(self, stream, landscape, header=True, time=None):
        landscape.write_to_stream(stream, header, time)

    def act(self):
        print( self.name)
        self.write(self.stream, self.landscape, self.header, self.time.time)

class ReadLandscape(event.Event):
    def __init__(self, time=(0,0), name='ReadLandscape', landscape = None, stream = None, numLocs = None):
        event.Event.__init__(self, time, name)
        self.landscape   = landscape
        self.stream      = stream
        self.numLocs     = numLocs

    def read(self, stream, landscape, numLocs = None):
        landscape.read_from_stream(stream, numLocs)

    def act(self):
        print(self.name)
        self.read(self.stream, self.landscape, self.numLocs)
