
import os,string,cPickle,time

import pygame
from pygame.locals import *

from common import *
import FS_file_system
import thing

import lightlevels

PATH_MAPS=os.path.join('data','maps')



class Map(FS_file_system.FS_file_system):
  def __init__(s,game):
    # sdl stuff
    s.SDL_map = game.SDL_map
    s.redraw=1
    s.SDL_bgcolor=(0,0,0)
    # game stuff
    s.game=game
    s.mapkey={}
    s.map={}
    s.size=[0,0]
    s.objects_to_load=None

  def get_light_area(s,origtile,strnum):
#    print 'need light effects for',pos
#    print 'need light effects for',lightlevels.level
#    print 'need light effects for',strnum
#    print 'need light effects for',lightlevels.level.keys()
    rv={}
    x,y=origtile.pos
    for dx,dy,str,path in lightlevels.level[strnum]:
      blocked=0
      for cx,cy in path:
        tile=s.map.get( (x+dx,y+dy), None )
        if x+dx==0:
           print 'checking sqyare',(x,y),(dx,dy),(cx,cy),tile.BLOCK_LOS,tile
        if tile is None or tile.BLOCK_LOS:
          blocked=1
          break
      if not blocked:
        tile=s.map.get( (x+dx,y+dy), None )
        if tile is not None: rv[ tile ]=str
#    print 'returing',rv
#    raise 'foo'
    return rv

  def tile_calculations(s,name,path=None):
    if path is None: path=PATH_MAPS
    fpath=s.FS_walk_and_find_file(name+'.calc',path)
    tileinfo=None
    if fpath is not None:
      try:
        tileinfo=cPickle.load( open(fpath) )
      except:
        print 'ERROR: map.tilecalc: pickle load failed',fpath
    if tileinfo is None:
      tileinfo=s.tile_calculations_generate(name,path)
    s.tile_calculations_update(tileinfo)
  def tile_calculations_update(s,tileinfo):
    for pos,data in tileinfo.items():
      sq=s.map[pos]
      sq.next_to_8=data[0]
      sq.next_to_4=data[1]
  def tile_calculations_generate(s,name,path=None):
    path=s.FS_walk_and_find_file(name,path)
    calcpath=path+'.calc'
    print 'MAP: generating map path info for',path
    squares={}
    poskeys=s.map.keys()
    for pos,square in s.map.items():
      x,y=pos
      sq=[ [], [] ]
      for dy in range(-1,2):
        for dx in range(-1,2):
          cpos=(x+dx,y+dy)
          if cpos in poskeys:
            sq[0].append( cpos )
            if abs(dx)+abs(dy)==1:
              sq[1].append( cpos )
      squares[ pos ]=sq
    print 'MAP: generated map path info'
    cPickle.dump( squares, open(calcpath,'w'), 2 )
    print 'MAP: saving map poth info',calcpath
    return squares


  def load_map(s,name,path=None):
    if path is None: path=PATH_MAPS
    fpath=s.FS_walk_and_find_file(name,path)
    if fpath==None: raise 'Map.load: couldnt find map file',name
    s.load_map_file(fpath)
    print 'MAP: loaded',s.game.tick()
    s.tile_calculations(name)
    print 'MAP: processed',s.game.tick()
  def load_map_file(s,path):
    mode=None
    x=y=0
    for l in open(path).readlines():
      sl=string.strip(l)
      if mode is None:
        if sl=='KEY':
          mode=1
      elif mode==1:  # KEYS
        if sl=='-'*len(sl) or sl=='='*len(sl):
          pass
        elif not sl:
          pass
        elif sl=='MAP':
          mode=mode+1
          s.objects_to_load=[]
        else:
          spl=string.split(string.rstrip(l),':')
          if len(spl)!=3: raise 'Map.load: key doesnt have a ":"',l
          if len(spl[0])!=1: raise 'Map.load: ":" out of place',l
          k=spl[0]
          tile=[]
          for type in string.split(spl[1],','):
#            print 'load map',spl,type
            type=string.strip(type)
            if type:
              if not s.game.fact_has_type(type):
                raise 'Map.load: cant find tile type',(type,spl)
              tile.append(type)
          objects=[]
          for type in string.split(spl[2],','):
            type=string.strip(type)
            if type:
              if not s.game.fact_has_type(type):
                raise 'Map.load: cant find object type',(type,spl)
              objects.append(type)
          s.mapkey[k]=(tile,objects)
      elif mode==2: # map
        if sl=='-'*len(sl) or sl=='='*len(sl):
          pass
        elif not sl:
          pass
        else:
          x=0
          for c in string.rstrip(l):
            if not s.mapkey.has_key( c ):
              raise 'Map.load: unknown map character',(x,y,c)
            pos=[x,y]
            tile,objects=s.mapkey[c]
            s.map[ (x,y) ] = s.game.fact_create_tile(pos, tile )
            for o in objects:
              s.objects_to_load.append( ( pos, s.map[(x,y)], [o] ) )
            x=x+1
            if x>s.size[0]: s.size[0]=x
          y=y+1
          if y>s.size[1]: s.size[1]=y
  def load_objects(s):
    for pos,tile,objs in s.objects_to_load:
      s.game.fact_create_objects( pos,tile,objs )

def main():
  m=Map('level0')

if __name__=="__main__": main()


