"""
Distributes random monsters and treasure in its map.

Copyright 2001 Cabochon Technologies, Inc.
Author: Frank Sronce (Kiz)
"""

from wyvern.lib import MethodHookCallback,Range
from wyvern.lib.predicates import BlockingPredicate
from wyvern.kernel.maps import MapObject
from java.util import StringTokenizer
from wyvern.lib.properties import Invisible

class populator(MapObject,MethodHookCallback):

    def initialize(self):
        self.setIntProperty ( "invisible", Invisible.ENGINE_OBJECT );
        self.addProperty('static')
        self.addProperty('nopickup')
        self.super__initialize()
        self.list = []

    def setMap(self,map,x,y):
        map.addMethodHook(self,"done-loading")
        self.super__setMap(map,x,y)

    def methodCalled(self, hookname, map, data):

        # I added this in (stevey) for now, because it results in
        # an OutOfMemoryError (crashing the server) for sparse maps
        if map.isSparse():
            return

        self.nummonsters = Range.rollDice ( self.getProperty("num-monsters") )
        self.numitems = Range.rollDice ( self.getProperty("num-items") )
        self.samechance = self.getIntProperty("same-chance")
        self.level = Range.rollDice ( self.getProperty("level") )
        self.lastmonster = ""

        if self.level < 1:  self.level = 1
        properties = self.getProperties()
        #print "My properties are ",properties
        for prop in properties:
            if prop[0:5] == "area-":
                txt = self.getProperty(prop)
                self.addToList(txt)
        if len(self.list) == 0:
            bounds = map.getBounds()
            #self.addToList(bounds)
            x = bounds.width
            y = bounds.height
            self.addToList("%s %s %s %s" % (1,1,x-2,y-2))
            #print "Bounds = ",bounds.width,bounds.height
        #print "The list was ",self.list

        self.predicate = BlockingPredicate()

        while self.numitems > 0:
            self.placeRandomItem(map)

        while self.nummonsters > 0:
            self.placeRandomMonster(map)

        map.removeMethodHook(self, "done-loading")

    def placeRandomItem(self,map):
        if len(self.list) == 0:
            self.numitems = 0
            return
        i = Range.randomValue( len(self.list)-1 )
        t = self.list[i]
        if map.findAt(t[0],t[1],self.predicate):
            del self.list[i]
            return
        item = self.getRandomItem()
        #print "Placing",item,t
        item = Kernel.instantiate(item)
        item.setIntProperty("level",self.level)
        item = item.generate()
        item.setMap(map,t[0],t[1])
        self.numitems = self.numitems - 1

    def placeRandomMonster(self,map):
        if len(self.list) == 0:
            self.nummonsters = 0
            return
        if self.lastmonster and Range.randomValue(100) < self.samechance:
            monster = self.lastmonster
        else:
            monster = self.getRandomMonster()
            self.lastmonster = monster
        i = Range.randomValue( len(self.list)-1 )
        t = self.list[i]
        if map.findAt(t[0],t[1],self.predicate):
            del self.list[i]
            return
        #print "Placing",monster,t
        del self.list[i]
        monster_ob = Kernel.instantiate(monster)
        if monster_ob:
            #print "Got back ",monster_ob,t
            monster_ob.setMap(map,t[0],t[1])
            #monster_ob.start()
        self.nummonsters = self.nummonsters - 1

    def getRandomItem(self):
        return "random/random"
        #return "objects/food/apple"

    def getRandomMonster(self):
        #return "monsters/goblin/orc"
        return "random/monster/random_monster"

    def addToList(self,txt):
        nums = StringTokenizer(txt)
        if nums.countTokens() == 2:
            #add a single square
            x = int(nums.nextToken())
            y = int(nums.nextToken())
            self.list.append( (x,y) )
        if nums.countTokens() == 4:
            #add a rectangle
            x = int(nums.nextToken())
            y = int(nums.nextToken())
            width = int(nums.nextToken())
            height = int(nums.nextToken())
            for i in range(x,x+width):
                for j in range(y,y+height):
                    self.list.append( (i,j) )