#!/usr/bin/env python
# -*- coding: utf8 -*-

import re
import math
import BitVector

from File import *

class GenericFile(File):

    name = "The programmer of this plugin forgot to specify" \
        + " a name."

#    __single = None
    def __init__(self, content=None):

#        if GenericFile.__single:
#            raise GenericFile.__single
#
#        GenericFile.__single = self

        if content is not None:
            self.args = int(math.log(len(content), 2))

    def char_to_value(self, char):
        if char >= 'a':
            return ord(char) - ord('a') + \
                    (ord('Z') - ord('A')) + 10
        elif char >= 'A':
                return ord(char) - ord('A') + 10
        elif char == '-':
            return -1
        else:
            return int(char)

        # raise Exception

    def value_to_char(self, value):
        if value == -1:
            return '-'
        elif value < 10:
            return str(value)
        elif value <= self.char_to_value('Z'):
            return chr(ord('A') + value)
        else:
            return chr(ord('a') + (ord('Z') - ord('A')) + 10)

    def parse_in(self, content):
        if len(content) < 3:
            #TODO: Exception?
            pass

        self.parse_header(content[:2])
        self.parse_body(content[2:])

    def parse_header(self, content):
        if self.extension is None:
            #TODO: Exception - extension not defined
            pass
        elif content[0] != self.extension:
            #TODO: Exception - bad type
            pass

        if not re.compile('^\d+ \d+ \d+$').match(content[1].lstrip()):
            #TODO: Exception - bad second line
            pass

        splitted_values = re.split(' ', content[1])
        self.args = int(splitted_values[0])
        self.in_alphabet = int(splitted_values[1])
        self.out_alphabet = int(splitted_values[2])

    def parse_out(self):
        content = self.prepare_header()
        content += self.prepare_body()

        return content

    def prepare_header(self):
        return self.extension +'\n' \
                    + str(self.args) +' ' \
                    + str(self.in_alphabet) + ' ' \
                    + str(self.out_alphabet) \
                    + '\n'

    def convert_to_FP(self):
        result = []

        values = range(0, pow(2, self.args))
        values.reverse()

        for i in values:
            bv = BitVector.BitVector(intVal=i)
            bv.pad_from_left(self.args - len(bv))
            arg = [bit for bit in bv]
            result += [self.calculate_function(arg)]

        print result
        return result

