# Copyright 2015-2016 Allen Institute for Brain Science
# This file is part of Allen SDK.
#
# Allen SDK is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# Allen SDK is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Allen SDK.  If not, see <http://www.gnu.org/licenses/>.

import csv
import copy
import math
from allensdk.internal.morphology.morphology import *
from allensdk.internal.morphology.node import Node

########################################################################
def read_swc(file_name):
    """  
    Read in an SWC file and return a Morphology object.

    Parameters
    ----------
    file_name: string
        SWC file name.

    Returns
    -------
    Morphology
        A Morphology instance.
    """
    nodes = []
    line_num = 1
    try:
        with open(file_name, "r") as f:
            for line in f:
                # remove comments
                if line.lstrip().startswith('#'):
                    continue
                # read values. expected SWC format is:
                #   ID, type, x, y, z, rad, parent
                # x, y, z and rad are floats. the others are ints
                toks = line.split()
                vals = Node(
                        n =  int(toks[0]),
                        t =  int(toks[1]),
                        x =  float(toks[2]),
                        y =  float(toks[3]),
                        z =  float(toks[4]),
                        r =  float(toks[5]),
                        pn = int(toks[6].rstrip())
                    )
                # store this node
                nodes.append(vals)
                # increment line number (used for error reporting only)
                line_num += 1
    except ValueError:
        err = "File not recognized as valid SWC file.\n"
        err += "Problem parsing line %d\n" % line_num
        if line is not None:
            err += "Content: '%s'\n" % line
        raise IOError(err)

    return Morphology(node_list=nodes)    


########################################################################
class Marker( dict ): 
    """ Simple dictionary class for handling reconstruction marker objects. """

    SPACING = [ .1144, .1144, .28 ]

    CUT_DENDRITE = 10 
    NO_RECONSTRUCTION = 20

    def __init__(self, *args, **kwargs):
        super(Marker, self).__init__(*args, **kwargs)

        # marker file x,y,z coordinates are offset by a single image-space pixel
        self['x'] -= self.SPACING[0]
        self['y'] -= self.SPACING[1]
        self['z'] -= self.SPACING[2]
        


def read_marker_file(file_name):
    """ read in a marker file and return a list of dictionaries """

    with open(file_name, 'r') as f:
        rows = csv.DictReader((r for r in f if not r.startswith('#')), 
                              fieldnames=['x','y','z','radius','shape','name','comment',
                                          'color_r','color_g','color_b'])

        return [ Marker({ 'x': float(r['x']), 
                          'y': float(r['y']), 
                          'z': float(r['z']), 
                          'name': int(r['name']) }) for r in rows ]

