#!BPY

""" Registration info for Blender menus:
Name: 'BZFlag'
Blender: 233
Group: 'Import'
Tip: 'Import from BZFlag World (.bzw) format.'
"""

import Blender
from math import pi

template='/home/yann/Blender/bzflag.blend'

def getmesh(name):
  '''Returns the given mesh, loading it from library if necessary'''
  mesh=Blender.NMesh.GetRaw(name)
  if mesh is None:
    Blender.Library.Load(name, 'Mesh')
    mesh=Blender.NMesh.GetRaw(name)
  return mesh

class object:
  def name(self, args):
    self._name=args[0]
  def end(self, args):
    try:
      self._obj.name=self._name
    except AttributeError:
      pass
    Blender.Scene.GetCurrent().link(self._obj)
    raise StopIteration

def ensureWorld():
  scene=Blender.Scene.GetCurrent()
  try:
    Blender.Object.Get('BZWorld')
  except AttributeError:
    world=Blender.Object.New('Mesh')
    world.name='BZWorld'
    world.link(getmesh('BZWorld'))
    world.size=(400.0, 400.0, 1.0)
    scene.link(world)
  try:
    Blender.Object.Get('flagHeight')
  except AttributeError:
    fh=Blender.Object.New('Empty')
    fh.name='flagHeight'
    # Draw the name for this Empty.
    fh.drawMode=fh.drawMode|8
    scene.link(fh)

class world:
  def __init__(self):
    self._obj=Blender.Object.Get('BZWorld')
  def size(self, args):
    size=float(args[0])
    self._obj.size=(size, size, 1.0)
  def flagHeight(self, args):
    fh=Blender.Object.Get('flagHeight')
    fh.loc=(0.0, 0.0, float(args[0]))
  def name(self, args):
    self._obj.name=args[0]
  def end(self, args):
    raise StopIteration

class positioned(object):
  # Shared list, do not modify.
  _position=(0.0, 0.0, 0.0)
  _rotation=0.0
  def position(self, args):
    self._position=map(float, args)
  def rotation(self, args):
    self._rotation=float(args[0])
  def end(self, args):
    self._obj.loc=self._position
    self._obj.RotZ=self._rotation*pi/180.0
    object.end(self, args)

class sized(positioned):
  # Default sizes differ. Define them in each class.
  def size(self, args):
    self._size=tuple(map(float, args))
  def end(self, args):
    self._obj.size=self._size
    positioned.end(self, args)

class simplemesh(sized):
  def end(self, args):
    self._obj=Blender.Object.New('Mesh')
    self._obj.link(getmesh(self._type))
    try:
      self._name
    except AttributeError:
      self._name=self._type
    sized.end(self, args)

class box(simplemesh):
  _size=(30.0, 30.0, 9.42)
  _type='Box'

class pyramid(simplemesh):
  _size=(8.2, 8.2, 10.25)
  _type='Pyramid'
  def end(self, args):
    if self._size[2] < 0:
      self._position=self._position[0:2]+[self._position[2]-self._size[2]]
    simplemesh.end(self, args)

class base(simplemesh):
  _size=(30.0, 30.0, 0.0)
  def color(self, args):
    colors={'1': 'RedBase', '2': 'GreenBase',
    	'3': 'BlueBase', '4': 'PurpleBase'}
    self._type=colors[args[0]]

def loadobject(obj, file):
  line=file.readline()
  while line:
    if line[0]=='#' or line[0]=="\n":
      line=file.readline()
      continue
    line=line.split()
    try:
      getattr(obj, line[0])(line[1:])
    except StopIteration:
      return
    except AttributeError:
      pass
    line=file.readline()

objtypes={ 'box': box, 'pyramid': pyramid, 'world': world,
	'base': base }

def bzflag_import(filename):
  Blender.Library.Open(template)
  file=open(filename)
  ensureWorld()
  line=file.readline()
  while line:
    line=line.strip()
    try:
      loadobject(objtypes[line](), file)
    except KeyError:
      pass
    line=file.readline()
  Blender.Library.Close()

Blender.Window.FileSelector(bzflag_import, "Import BZFlag World")
#bzflag_import('/home/yann/Blender/hix.bzw')

