from __future__ import division
from perlin import Perlin
from biomes import biomes
import time, random

def generate(master, chunk):
    chunk.terrain = generate_terrain(
        chunk.position[0],
        chunk.position[1],
        master.seed,
        master.quality,
        master.minz,
        master.maxz
    )

    chunk.biomes = generate_biomes(
        chunk.get_real_pos(),
        master
    )

    pl = Perlin()
    it = 3
    sr = ((-1, -1), (0, -1), (1, -1),
          (-1, 0), (1, 0),
          (-1, 1), (0, 1), (1, 1))

    for x in range(16):
        for y in range(16):
            z = chunk.terrain[(x, y)]
            r = z
            u = 0

            while z >= 0:
                dt = master.quality + master.seed
                de = 0

                for j in range(it):
                    de += pl.noise(
                        (x / master.seed) / dt,
                        (y / master.seed) / dt,
                        (z / master.seed) / dt
                    ) * dt
                    dt *= 4

                if de <= 14:
                    bt = chunk.biomes[x, y].get_dbt(x, y, z, r)
                else:
                    bt = 0

                chunk[x, y, z] = bt
                z -= 1

    return True

def generate_terrain(cx, cy, seed, quality, minz, maxz):
    dt = quality + seed # Modulator.
    pl = Perlin()       # Generator.
    op = {}             # Output.

    for x in range(16):
        for y in range(16):
            z = pl.noise((x / seed) / dt, (y / seed) / dt, 0)

            if z < 0.0:
                z = 0.0

            if z > 1.0:
                z = 1.0

            z = int(round((z * (maxz - minz)) + minz))
            op[(x, y)] = z

    return op

def generate_biomes(rp, master):
    op = {}
    bm = {}

    for x in range(16):
        for y in range(16):
            bn = 'forest'
            rx = rp[0] + x
            ry = rp[1] + y
            
            temp = master.get_temperature(rx, ry)
            humi = master.get_humidity(rx, ry)

            if temp < 0.0: temp = 0.0
            if humi < 0.0: humi = 0.0
            if temp > 1.0: temp = 1.0
            if humi > 1.0: humi = 1.0

            for sbn, sbv in biomes.iteritems():
                stc = sbv[0][0]
                shc = sbv[0][1]

                if temp >= stc[0] and temp <= stc[1] \
                   and humi >= shc[0] and humi <= shc[1]:
                    bn = sbn
                    break

            ob = bm.setdefault(bn, biomes[bn][1]())
            op[(x, y)] = ob

    return op

if __name__ == '__main__':
    add = 0.0
    cnt = 0
    seed = random.random()
    
    for i in range(32):
        start = time.clock()
        generate_terrain(0, 0, seed, 256, 63, 119)
        
        add += time.clock() - start
        cnt += 1
    
    print '%s chunks generated in %ss; average time is %ss.' % (cnt, add, add / cnt)
