#!/usr/bin/env python
# -*- coding: utf-8 -*-

# This file is part of ROBOTGAME
#
# ROBOTGAME 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, either version 3 of the License, or (at your option) any later
# version.
#
# ROBOTGAME 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
# ROBOTGAME.  If not, see <http://www.gnu.org/licenses/>.
#
# ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
#
#                         colourboxes.py
#                     --------------------
#       date created : Wed Aug 8 2012
#          copyright : (C) 2012 Niels G. W. Serup
#      maintained by : Niels G. W. Serup <ns@metanohi.name>

"""
Colour boxes.
"""

import random

def generate_colour_boxes(nwells, nboxes):
    """
    Generate colour boxes that can be used to make all wells white.

    Arguments:
    nwells -- number of wells
    nboxes -- maximum number of boxes needed to make all wells white.

    Return [[(r, g, b)]]
      where r : 0|1,  g : 0|1,  b : 0|1
    """
    
    nbits = nwells * 3
    data = [[0 for _ in range(nboxes)] for _ in range(nbits)]

    def insert_1():
        t = random.randrange(0, nboxes)
        for y in range(t, nboxes) + range(0, t):
            if data[x][y] == 0:
                data[x][y] = 1
                break

    for x in range(len(data)):
        insert_1()
        for _ in range(random.randrange(0, (nboxes + 1) / 2)):
            insert_1()
            insert_1()

    boxes = []
    for y in range(nboxes):
        box = []
        boxes.append(box)
        for x in range(0, nbits, 3):
            r = data[x][y]
            g = data[x + 1][y]
            b = data[x + 2][y]
            box.append((r, g, b))
    return boxes

def generate_random_box(nwells):
    r = lambda: random.choice((0, 1))
    return [(r(), r(), r()) for _ in range(nwells)]

def makes_all_wells_white(boxes):
    """
    Determine if the boxes make all wells white when XOR'ed together.
    """
    
    total = 0
    for box in boxes:
        n = 0
        for r, g, b in box:
            n <<= 1
            n |= r
            n <<= 1
            n |= g
            n <<= 1
            n |= b
        total ^= n
    return total == 2**(len(boxes[0]) * 3) - 1