#!/usr/bin/env python
# -*- coding: utf8 -*-
from math import log
from BitVector import BitVector
#from Numeric import empty
#from Numeric import shape
from numpy import *

from GenericFile import GenericFile

class FWTChecker(GenericFile):
    name = "Szybka transformata Walsha"

    def __init__(self, content=None):
        if content is None:
            #TODO: Rzucić coś
            return None

        if (len(content) % 2) != 0:
            #TODO: Musi być parzyste
            return None

        GenericFile.__init__(self, content)

        self.init_from_content(self.convert_to_polar(content))

    def convert_to_polar(self, content):
        for i in range(0, len(content)):
            if content[i] == 0:
                 content[i] = -1

        return content

    def init_from_content(self, content):
        line_length = len(content)

        result = empty((int(math.log(line_length, 2)+1), int(line_length)), int)
        for i in range(0, line_length):
            result[0][i] = content[i]

        done = BitVector(intVal=0)
        step = 0
        for verse in range(1, shape(result)[0]):
            step = int(pow(2, verse-1))
            done = BitVector(inVal=0, size=line_length)
            for i in range(0, line_length):
                if bool(done[i]) is False:
                    result[verse][i] = \
                            result[verse-1][i] + result[verse-1][i+step]
                    result[verse][i+step] = \
                            result[verse-1][i] - result[verse-1][i+step]

                    done[i], done[i+step] = True, True

        max = 0
        for value in result[len(result)-1]:
            print value, abs(value)
            if abs(value) > max:
                max = abs(value)

        self.change_to_printable(result)
        self.calculate_nonlinearity(line_length, max)

    def calculate_nonlinearity(self, size, max):
        self.nonlinearity = (size - max) / 2
        self._function += "(%d - %d) / 2 = %d" % \
            (size, max, self.nonlinearity)

    def change_to_printable(self, function):
        self._function = ""

        for line in function:
            for value in line:
                if value >= 0:
                    self._function += ' '
                self._function += str(value) + '   '
            self._function += '\n'


    def parse_out(self):
        return self._function

