#!/usr/bin/env python
# encoding: utf-8
"""
Analysis.py

Created by Brian Whitman on 2007-12-29.
Copyright (c) 2007 The Echo Nest Corporation. All rights reserved.
"""

import sys
import os
import unittest
import xml.dom.minidom

"""Class for parsing EN Analysis (v22 or higher)"""

class Analysis:
    """By default, we don't do any parse extraction, just in case you want to just pull out a little piece.
       If you set parseEverythingNow then it will place them in instance variables."""
    def __init__(self, filename, parseEverythingNow = False):
        self.filename = filename
        self.parse = xml.dom.minidom.parse(self.filename)
        if(parseEverythingNow):
            self.sections = self.getSections()
            self.segments = self.getSegments()
            self.tatums = self.getTatums()
            self.pitchMean = self.getPitchMean()
            self.timbreMean = self.getTimbreMean()
            self.tempo = self.getTempo()

    """Return a tag in the track element"""
    def getTrackTag(self, tag):
        return self.parse.childNodes[1].childNodes[3].childNodes[1].getAttribute(tag)

    """Return the tatum list as a list of floats"""
    def getTatums(self):
        return map(float,self.parse.childNodes[1].childNodes[3].childNodes[3].childNodes[0].nodeValue.split())

    """Return the list of sections as a list of dicts"""
    def getSections(self):
        sections = []
        for i in range(5,(self.getNumberOfSections()*2)+5, 2):
            section = {}
            section["start"] = float(self.parse.childNodes[1].childNodes[3].childNodes[i].getAttribute("start"))
            section["duration"] = float(self.parse.childNodes[1].childNodes[3].childNodes[i].getAttribute("duration"))
            sections.append(section)
        return sections

    """Return the segments as a list of dicts. Single #s are floats, multiples are lists of floats"""
    def getSegments(self):
        segments = []
        for i in range(5+(self.getNumberOfSections()*2),(self.getNumberOfSegments()*2)+5+(self.getNumberOfSections()*2), 2):
            segment = {}
            segment["start"] = float(self.parse.childNodes[1].childNodes[3].childNodes[i].getAttribute("start"))
            segment["duration"] = float(self.parse.childNodes[1].childNodes[3].childNodes[i].getAttribute("duration"))
            segment["loudnessBegin"] = float(self.parse.childNodes[1].childNodes[3].childNodes[i].childNodes[1].getAttribute("loudnessBegin"))
            segment["loudnessMax"] = float(self.parse.childNodes[1].childNodes[3].childNodes[i].childNodes[1].getAttribute("loudnessMax"))
            segment["loudnessEnd"] = float(self.parse.childNodes[1].childNodes[3].childNodes[i].childNodes[1].getAttribute("loudnessEnd"))
            segment["timeLoudnessMax"] = float(self.parse.childNodes[1].childNodes[3].childNodes[i].childNodes[1].getAttribute("timeLoudnessMax"))
            segment["timbreCoeff"] = map(float,self.parse.childNodes[1].childNodes[3].childNodes[i].childNodes[1].getAttribute("timbreCoeff").split())
            segment["pitches"] = map(float,self.parse.childNodes[1].childNodes[3].childNodes[i].childNodes[1].getAttribute("pitches").split())
            segments.append(segment)
        return segments

    """How many sections?"""
    def getNumberOfSections(self):
        return int(self.getTrackTag("numSections"))

    """How many segments"""
    def getNumberOfSegments(self):
        return int(self.getTrackTag("numSegments"))

    """Mean pitch of track as list of floats"""
    def getPitchMean(self):
        return map(float,self.getTrackTag("pitchMean").split())

    """Mean timbre of track as list of floats"""
    def getTimbreMean(self):
        return map(float,self.getTrackTag("timbreMean").split())

    """BPM"""
    def getTempo(self):
        return float(self.getTrackTag("tempo"))
        

class AnalysisTests(unittest.TestCase):
    def setUp(self):
        pass


if __name__ == '__main__':
    unittest.main()