# pygsear
# Copyright (C) 2003 Lee Harr
#
#
# This file is part of pygsear.
#
# pygsear 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 2 of the License, or
# (at your option) any later version.
#
# pygsear 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 pygsear; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


import random

from pygsear import Event, Drawable, Game
from pygsear import conf
from pygsear.locals import *



class Block(Drawable.Stationary):
    def __init__(self, layer, width, height, x, y, color='random'):
        b = Drawable.Rectangle(w=layer, width=width, height=height, color=color)
        b.set_position((x, y))

        Drawable.Stationary.__init__(self, w=layer, sprite=b)


class TankWorld:
    def __init__(self, width=2, height=1):
        self.width = width
        self.height = height
        self.screens = []
        for h in range(height):
            for w in range(width):
                n = random.randrange(5, 10)
                tws = TankWorldScreen()
                tws.make_blocks(nblocks=n)
                tws.name = w + (h * width)
                self.screens.append(tws)
                #print [screen.name for screen in self.screens]

                if h == 0:
                    tws.block_top()

                if h == height-1:
                    tws.block_bottom()

                if w == 0:
                    tws.block_left()

                if w == width-1:
                    tws.block_right()

        self.set_neighbors()

    def set_active_screen(self, screen):
        self.active_screen = screen
        self.blocks = screen.blocks
        self.blockrects = screen.blockrects
        if hasattr(self, 'blocks_drawn'):
            self.blocks_drawn.clear()
        self.blocks_drawn = Drawable.Stationary(sprite=self.active_screen)
        self.blocks_drawn.draw()

    def where_is(self, screen, other_screen):
        sx = screen.name % self.width
        sy = int(screen.name / self.width)

        osx = other_screen.name % self.width
        osy = int(other_screen.name / self.width)

        r = []
        if sx > osx:
            r.append('left')
        elif sx < osx:
            r.append('right')

        if sy > osy:
            r.append('above')
        elif sy < osy:
            r.append('below')

        return r

    def set_neighbors(self):
        width = self.width
        height = self.height
        screens = self.screens
        for h in range(height):
            for w in range(width):
                s = w + (h * width)
                #print 's', s
                screen = screens[s]
                #print screen.name
                screen.neighbors = {}
                if w < width - 1:
                    try:
                        screen.neighbors['right'] = screens[s + 1]
                    except IndexError:
                        screen.neighbors['right'] = None
                else:
                    screen.neighbors['right'] = None

                if w > 0:
                    try:
                        screen.neighbors['left'] = screens[s - 1]
                    except IndexError:
                        screen.neighbors['left'] = None
                else:
                    screen.neighbors['left'] = None

                if h < height - 1:
                    try:
                        screen.neighbors['below'] = screens[s + width]
                    except IndexError:
                        screen.neighbors['below'] = None
                else:
                    screen.neighbors['below'] = None

                if h > 0:
                    try:
                        screen.neighbors['above'] = screens[s - width]
                    except IndexError:
                        screen.neighbors['above'] = None
                else:
                    screen.neighbors['above'] = None

    def draw(self):
        self.active_screen.udraw()


    def clear(self):
        self.active_screen.uclear()

    def report(self):
        for h in range(self.height):
            for w in range(self.width):
                s = w + (h * self.width)
                screen = self.screens[s]
                print
                print 'World Report'
                for x in screen.blockinfo_list:
                    print '(%s, %s) -- [%s, %s] = %s' % (x['x'], x['y'], x['width'], x['height'], x['color'])

    def get_worldinfo(self):
        worldinfo = {}

        worldinfo['WINWIDTH'] = conf.WINWIDTH
        worldinfo['WINHEIGHT'] = conf.WINHEIGHT

        width = self.width
        height = self.height
        worldinfo['width'] = width
        worldinfo['height'] = height

        screens = []
        for h in range(height):
            for w in range(width):
                s = w + (h * width)
                screen = self.screens[s]
                screens.append(screen.blockinfo_list)
        worldinfo['screens'] = screens

        return worldinfo

    def sync(self, worldinfo):
        self.blocks_drawn.clear()

        WINWIDTH = worldinfo['WINWIDTH']
        WINHEIGHT = worldinfo['WINHEIGHT']
        if not WINWIDTH == conf.WINWIDTH or not WINHEIGHT == conf.WINHEIGHT:
            conf.window.resize(size=(WINWIDTH, WINHEIGHT))

        width = worldinfo['width']
        height = worldinfo['height']

        self.screens = []
        screens = worldinfo['screens']
        for h in range(height):
            for w in range(width):
                s = w + (h * width)
                tws = TankWorldScreen()
                blockinfo_list = screens[s]
                tws.sync(blockinfo_list)
                tws.name = w + (h * width)

                self.screens.append(tws)

        self.set_neighbors()


class TankWorldScreen(Drawable.Layer):
    def __init__(self):
        Drawable.Layer.__init__(self, size=conf.WINSIZE, color=DGREEN)
        self.blockinfo_list = []
        self.stack = Drawable.StationaryStack(w=self)
        self.blocks = Game.SpriteGroup(layer=self)
        self.blockrects = []
        self.set_position((0, 0))
        self.hidden = 0

    def make_block(self, blockinfo=None):
        if blockinfo is None:
            width = random.randrange(30, 200)
            height = random.randrange(30, 200)
            x = random.randrange(60, conf.WINWIDTH-width-60)
            y = random.randrange(60, conf.WINHEIGHT-height-60)
            color = random.choice(COLORS)
            blockinfo = {'width': width,
                            'height': height,
                            'x': x,
                            'y': y,
                            'color': color
                        }
        else:
            width = blockinfo['width']
            height = blockinfo['height']
            x = blockinfo['x']
            y = blockinfo['y']
            color = blockinfo['color']

        self.blockinfo_list.append(blockinfo)

        block = Block(layer=self, width=width, height=height, x=x, y=y, color=color)
        self.blocks.add(block)
        self.stack.push(block)
        self.blockrects.append(block.crect)

    def make_blocks(self, nblocks=9):
        self.nblocks = nblocks
        for b in range(nblocks):
            self.make_block()
        
    def block_top(self):
        w, h = conf.WINWIDTH, 5
        x, y = 0, 0
        blockinfo = {'width': w,
                        'height': h,
                        'x': x,
                        'y': y,
                        'color': LGREEN
                    }
        self.make_block(blockinfo)

    def block_bottom(self):
        w, h = conf.WINWIDTH, 5
        x, y = 0, conf.WINHEIGHT-5
        blockinfo = {'width': w,
                        'height': h,
                        'x': x,
                        'y': y,
                        'color': LGREEN
                    }
        self.make_block(blockinfo)
            
    def block_left(self):
        w, h = 5, conf.WINHEIGHT
        x, y = 0, 0
        blockinfo = {'width': w,
                        'height': h,
                        'x': x,
                        'y': y,
                        'color': LGREEN
                    }
        self.make_block(blockinfo)
            
    def block_right(self):
        w, h = 5, conf.WINHEIGHT
        x, y = conf.WINWIDTH-5, 0
        blockinfo = {'width': w,
                        'height': h,
                        'x': x,
                        'y': y,
                        'color': LGREEN
                    }
        self.make_block(blockinfo)
            
    def sync(self, blockinfo_list):
        for blockinfo in blockinfo_list:
            self.make_block(blockinfo)



def main():
    print 'testing World'
    w = TankWorld()
    print 'test complete'

if __name__ == '__main__':
    main()
