# Tricky Mirrors
# mirrors.py - (c) Goetz Schwandtner
# schwandtner@googlemail.com
# 07-2006, 08-2008

import appuifw
from graphics import *
import e32
from key_codes import *
import random,math

VERSION=u'1.0'

WIDTH,HEIGHT=8,10

class Keyboard(object):
    def __init__(self,onevent=lambda:None):
        self._keyboard_state={}
        self._downs={}
        self._onevent=onevent
    def handle_event(self,event):
        if event['type'] == appuifw.EEventKeyDown:
            code=event['scancode']
            if not self.is_down(code):
                self._downs[code]=self._downs.get(code,0)+1
            self._keyboard_state[code]=1
        elif event['type'] == appuifw.EEventKeyUp:
            self._keyboard_state[event['scancode']]=0
        self._onevent()
    def is_down(self,scancode):
        return self._keyboard_state.get(scancode,0)
    def pressed(self,scancode):
        if self._downs.get(scancode,0):
            self._downs[scancode]-=1
            return True
        return False
keyboard=Keyboard()

appuifw.app.screen='full'
# appuifw.app.orientation='portrait'

img=None
def handle_redraw(rect):
    if img:
        canvas.blit(img)
appuifw.app.body=canvas=appuifw.Canvas(
    event_callback=keyboard.handle_event,
    redraw_callback=handle_redraw)
img=Image.new(canvas.size)

class CoordGrid(object):
 def __init__(self,size_py,size_px,width=WIDTH,height=HEIGHT):
  self.w,self.h=width,height
  self.comp_x,self.comp_y=size_px/self.w,size_py/self.h
  self.cx,self.cy=0,0
 def isCursor(self,x,y):
  return self.cx==x and self.cy==y
 def toScrC(self,x,y):
  return x*self.comp_x,y*self.comp_y
 def l(self):
   self.cx=(self.cx-1+self.w)%self.w
 def r(self):
   self.cx=(self.cx+1+self.w)%self.w
 def u(self):
   self.cy=(self.cy-1+self.h)%self.h
 def d(self):
   self.cy=(self.cy+1+self.h)%self.h

(w,h)=canvas.size
grid=CoordGrid(h,w)

class FieldComp(object):
  _wmark,_wsel,_wtile=5,2,1
  def __init__(self,y,x,grid):
    self.x,self.y=x,y
    self.marked=False
    self._g=grid
    self._ptx,self._pty=self._g.toScrC(x,y)
    self._pbx,self._pby=self._g.toScrC(x+1,y+1)
    self.recpt=[None,None,None,None]
  def reset(self):
    pass
  def action(self,dir):
    pass
  def draw(self,img):
    img.rectangle((self._ptx+FieldComp._wtile,self._pty+FieldComp._wtile,self._pbx-FieldComp._wtile,self._pby-FieldComp._wtile), fill=0x000040)
    if self._g.isCursor(self.x,self.y):
      img.rectangle((self._ptx+FieldComp._wsel,self._pty+FieldComp._wsel,self._pbx-FieldComp._wsel,self._pby-FieldComp._wsel), fill=0x700000)    
    if self.marked:
      img.rectangle((self._ptx+FieldComp._wmark,self._pty+FieldComp._wmark,self._pbx-FieldComp._wmark,self._pby-FieldComp._wmark), fill=0x000070)

class Wall(FieldComp):
  def __init__(self,y,x,grid):
    FieldComp.__init__(self,y,x,grid)
    self.marked=False
  def draw(self,img):
    FieldComp.draw(self,img)
    img.rectangle((self._ptx+FieldComp._wmark,self._pty+FieldComp._wmark,self._pbx-FieldComp._wmark,self._pby-FieldComp._wmark), outline=0x606060,width=2*FieldComp._wmark)

class LaserColor(object):
  MINVAL=0xF0F060
  MAXVAL=0xFA0000
  INCR=0x020000-0x001808
  def __init__(self):
    self.reset()
  def reset(self):
    self.val=LaserColor.MINVAL
    self.doIncrease=False
  def inc(self):
    self.doIncrease=True
  def step(self):
    if self.doIncrease:
      self.doIncrease=False
      if self.val<LaserColor.MAXVAL:
        self.val=self.val+LaserColor.INCR
      else: return True
    else:
      if self.val>LaserColor.MINVAL:
        self.val=self.val-LaserColor.INCR
LASERCOLOR=LaserColor()

class LaserComp(FieldComp):
  _wl=8
  def __init__(self,y,x,grid):
    FieldComp.__init__(self,y,x,grid)
    self._ltx,self._lty=(self._ptx+self._pbx-LaserComp._wl)/2,(self._pty+self._pby-LaserComp._wl)/2
    self._lbx,self._lby=self._ltx+LaserComp._wl,self._lty+LaserComp._wl
    self._lcx,self._lcy=(self._ltx+self._lbx)/2,(self._lty+self._lby)/2
    self.reset()
  def reset(self):
     self.act=[False,False,False,False]
     self.perf=[False,False,False,False]
  def draw(self,img):
    FieldComp.draw(self,img)
    if self.act[0]:
      img.rectangle((self._lcx,self._lty,self._pbx,self._lby), fill=LASERCOLOR.val)
    if self.act[1]:
      img.rectangle((self._ltx,self._pty,self._lbx,self._lcy), fill=LASERCOLOR.val)
    if self.act[2]:
      img.rectangle((self._ptx,self._lty,self._lcx,self._lby), fill=LASERCOLOR.val)
    if self.act[3]:
      img.rectangle((self._ltx,self._lcy,self._lbx,self._pby), fill=LASERCOLOR.val)
  def action(self,dir):
    if not(self.perf[dir]):
      self.perf[dir]=True
      self.act[dir]=True
      newdir=(dir+2)%4
      self.act[newdir]=True
      if not self.recpt[newdir] is None:
        self.recpt[newdir].action(dir)

class Laser(LaserComp):
  _ld=8
  BACKCOLOR=0x30A030
  def __init__(self,y,x,grid,dir,acthandler=None):
    LaserComp.__init__(self,y,x,grid)
    self.dir=dir
    self._start=math.pi/2*((dir+3)%4-2)
    self._end=math.pi/2*((dir+1)%4-2)
    self.active=False
    self.recpt.append(acthandler)
  def draw(self,img):
    LaserComp.draw(self,img)
    if self.active:
      img.pieslice((self._ptx+Laser._ld,self._pty+Laser._ld,self._pbx-Laser._ld,self._pby-Laser._ld),self._end,self._start,fill=LASERCOLOR.val)
    else:
      img.pieslice((self._ptx+Laser._ld,self._pty+Laser._ld,self._pbx-Laser._ld,self._pby-Laser._ld),self._end,self._start,fill=0x606090)
    img.pieslice((self._ptx+Laser._ld,self._pty+Laser._ld,self._pbx-Laser._ld,self._pby-Laser._ld),self._start,self._end,fill=self.BACKCOLOR)
  def action(self,dir):
    if dir==4:
      self.active=True
    else:
      self.act[dir]=True
      if (dir==self.dir) and self.active:
        if not self.recpt[4] is None:
          self.recpt[4].action()
  def reactivate(self):
    if self.active:
      self.act[self.dir]=True
      if not self.recpt[self.dir] is None:
        self.recpt[self.dir].action((self.dir+2)%4)

class ALaser(Laser):
  BACKCOLOR=0x3030A0
  def auto(self):
    self.active=not self.active

class FLaser(ALaser):
  BACKCOLOR=0xA03030  
  def auto(self):
    pass

class LaserTarget(LaserComp):
  _bdr=8
  cnt=0
  COLMIN=0x204020
  COLMAX=0x20B020
  COLDECR=0x004000
  def __init__(self,y,x,grid):
    LaserComp.__init__(self,y,x,grid)
    self.destroyed=False
    self.col=LaserTarget.COLMAX
    LaserTarget.cnt=LaserTarget.cnt+1
  def draw(self,img):
    LaserComp.draw(self,img)
    if not self.destroyed:
      img.ellipse((self._ptx+LaserTarget._bdr,self._pty+LaserTarget._bdr,self._pbx-LaserTarget._bdr,self._pby-LaserTarget._bdr),fill=self.col)
  def action(self,dir):
    if self.destroyed:
      LaserComp.action(self,dir)
    else:
      self.act[dir]=True
      if self.col>LaserTarget.COLMIN:
        self.col=self.col-LaserTarget.COLDECR
      else:
        self.destroyed=True
        LaserTarget.cnt=LaserTarget.cnt-1
        LaserComp.action(self,dir)

class Bomb(LaserComp):
  COLOFF=0x707070
  COLON1=0x903030
  COLON2=0xFF5050  
  COLEX=0x000000    
  def __init__(self,y,x,grid):
    LaserComp.__init__(self,y,x,grid)
    self.ticking=-1
  def draw(self,img):
    LaserComp.draw(self,img)
    if self.ticking<0:
        col=Bomb.COLOFF
    elif self.ticking==0:
        col=Bomb.COLEX
    elif self.ticking%2==1:
        col=Bomb.COLON2
    else:
        col=Bomb.COLON1        
    if self.ticking in (0,1):
        img.rectangle((self._ptx+FieldComp._wtile,self._pty+FieldComp._wtile,self._pbx-FieldComp._wtile,self._pby-FieldComp._wtile), fill=col)
    else:
      bdr=3
      img.ellipse((self._ptx+bdr,self._pty+bdr,self._pbx-bdr,self._pby-bdr),fill=0x206020)
      img.ellipse(((self._ptx+self._pbx)/2-2*bdr,(self._pty+self._pby)/2-2*bdr,(self._ptx+self._pbx)/2+2*bdr,(self._pty+self._pby)/2+2*bdr),fill=col)
  def auto(self):
    if self.ticking==0:
        timer.destroyed=True
    elif self.ticking>0:
      self.ticking-=1
  def action(self,dir):
      self.act[dir]=True
      if self.ticking<0:
          self.ticking=5


class Teleport(LaserComp):
  _bdr=8
  def __init__(self,y,x,grid,target=None):
    LaserComp.__init__(self,y,x,grid)
    self.target=target
  def draw(self,img):
    LaserComp.draw(self,img)
    for i in range(5):
      img.ellipse((self._ptx+LaserTarget._bdr+2*i,self._pty+LaserTarget._bdr+2*i,self._pbx-LaserTarget._bdr-2*i,self._pby-LaserTarget._bdr-2*i),fill=0x6060D0-0x101020*i)
  def action(self,dir):
    self.act[dir]=True
    if not self.target is None:
      self.target.taction(dir)
  def taction(self,dir):
    if not(self.perf[dir]):
      self.perf[dir]=True
      newdir=(dir+2)%4
      self.act[newdir]=True
      if not self.recpt[newdir] is None:
        self.recpt[newdir].action(dir)

class Mirror(LaserComp):
  OUTCOLOR=0xA0A0A0
  FILLCOLOR=0x5050A0
  PINCOLOR=0x80F080
  def __init__(self,y,x,grid,dir=0):
    LaserComp.__init__(self,y,x,grid)
    self.dir=dir
  def action(self,dir):
    self.act[dir]=True
    l=self.actionlist[self.dir][dir]
    for ac in l:
      if not self.perf[ac]:
        self.perf[ac]=True
        self.act[ac]=True
        if not self.recpt[ac] is None:
          self.recpt[ac].action((ac+2)%4)
  def turn(self,dir=4):
    if dir==4:
      self.dir=(self.dir+1)%4
    elif dir==-1:
      self.dir=(self.dir+3)%4
    else:
      self.dir=dir

class FlatMirror(Mirror):
  actionlist=(((),(1,),(),(3,)),((3,),(2,),(1,),(0,)),((0,),(),(2,),()),((1,),(0,),(3,),(2,)))
  _bdr=8
  def __init__(self,y,x,grid,dir=0):
    Mirror.__init__(self,y,x,grid,dir)
    self._wx=(self._pbx-self._ptx-2*FlatMirror._bdr)*math.sqrt(.5)/2
    self._wy=(self._pby-self._pty-2*FlatMirror._bdr)*math.sqrt(.5)/2
    self._pmx,self._pmy=(self._pbx+self._ptx)/2,(self._pby+self._pty)/2
    self._mcoords=((self._ptx+FlatMirror._bdr,self._pmy,self._pbx-FlatMirror._bdr,self._pmy),(self._pmx-self._wx,self._pmy+self._wy,self._pmx+self._wx,self._pmy-self._wy),(self._pmx,self._pty+FlatMirror._bdr,self._pmx,self._pby-FlatMirror._bdr),(self._pmx-self._wx,self._pmy-self._wy,self._pmx+self._wx,self._pmy+self._wy))
  def draw(self,img):
    Mirror.draw(self,img)
    img.line(self._mcoords[self.dir],width=10,outline=self.OUTCOLOR)
    img.line(self._mcoords[self.dir],width=8,outline=self.FILLCOLOR)
    img.point((self._lcx,self._lcy),width=6,outline=self.PINCOLOR)

class FFlatMirror(FlatMirror):
  PINCOLOR=0xF08080
  def __init__(self,y,x,grid,dir=0):
    FlatMirror.__init__(self,y,x,grid,dir)
  def turn(self, dir=4):
    pass

class AFlatMirror(FlatMirror):
  PINCOLOR=0x8080F0
  def __init__(self,y,x,grid,dir=0):
    FlatMirror.__init__(self,y,x,grid,dir)
  def turn(self, dir=4):
    pass
  def auto(self, dir=4):
    FlatMirror.turn(self,dir)

class TriMirror(Mirror):
  actionlist=(((1,),(0,2),(1,),(3,)),((0,),(2,),(1,3),(2,)),((3,),(1,),(3,),(0,2)),((1,3),(0,),(2,),(0,)))
  def __init__(self,y,x,grid,dir=0):
    Mirror.__init__(self,y,x,grid,dir)
    d,x,y=8,self._lcx,self._lcy
    self._mcoords=((x,y-d,x-2*d,y+d,x+2*d,y+d),(x-d,y,x+d,y-2*d,x+d,y+2*d),(x,y+d,x+2*d,y-d,x-2*d,y-d),(x+d,y,x-d,y-2*d,x-d,y+2*d))
  def draw(self,img):
    Mirror.draw(self,img)
    img.polygon(self._mcoords[self.dir],outline=self.OUTCOLOR,fill=self.FILLCOLOR)
    img.point((self._lcx,self._lcy),width=6,outline=self.PINCOLOR)

class FTriMirror(TriMirror):
  PINCOLOR=0xF08080
  def __init__(self,y,x,grid,dir=0):
    TriMirror.__init__(self,y,x,grid,dir)
  def turn(self, dir=4):
    pass

class ATriMirror(TriMirror):
  PINCOLOR=0x8080F0
  def __init__(self,y,x,grid,dir=0):
    TriMirror.__init__(self,y,x,grid,dir)
  def turn(self, dir=4):
    pass
  def auto(self, dir=4):
    TriMirror.turn(self,dir)

class Timer(object):
  LASERINTRVL=2
  AUTOINTRVL=2
  def __init__(self):
    self.cnt=0
    self.destroyed=False
  def action(self):
    LASERCOLOR.inc()
  def step(self):
    res=False
    self.cnt=self.cnt+1
    if self.cnt%Timer.AUTOINTRVL==0:
      gf.runAutos()
      res=True    
    if self.cnt%Timer.LASERINTRVL==0:
      gf.reactivate()
      if LASERCOLOR.step():
        self.destroyed=True
      res=True
    return res
timer=Timer()

class Gamefield(object):
  NUMLEVELS=9
  def __init__(self,level=1):
    self.dirty=True
    self.fa=[[LaserComp(y,x,grid) for x in range(WIDTH)] for y in range(HEIGHT)]
    LaserTarget.cnt=0
    self.setFA(level)
    for y in range(HEIGHT):
      for x in range(WIDTH):
        self.link(x,y)
    appuifw.note(u'Level '+unicode(level)+u':\n'+self.note)
  def link(self,x,y):
    if x<WIDTH-1:
      self.fa[y][x].recpt[0]=self.fa[y][x+1]
    if y>0:
      self.fa[y][x].recpt[1]=self.fa[y-1][x]
    if x>0:
      self.fa[y][x].recpt[2]=self.fa[y][x-1]
    if y<HEIGHT-1:
      self.fa[y][x].recpt[3]=self.fa[y+1][x]
  def reset(self):
     for line in self.fa:
        for field in line:
            field.reset()
  def draw(self,img):
      self.dirty=False
      for line in self.fa:
        for field in line:
            field.draw(img)
  def reactivate(self):
    self.dirty=True
    self.reset()
    for ly,lx in self.lasers:
      self.fa[ly][lx].reactivate()
  def runAutos(self):
     for ay,ax in self.autos:
       self.fa[ay][ax].auto()
  def setFA(self,level):
    if level==1:
      self.fa[1][1]=Laser(1,1,grid,3,timer)
      self.fa[3][3]=Laser(3,3,grid,3,timer)
      self.fa[1][6]=Laser(1,6,grid,3,timer)
      self.fa[8][1]=Laser(8,1,grid,1,timer)
      for y,x in [(3,1),(5,1),(7,3),(3,6),(5,6)]:
        self.fa[y][x]=LaserTarget(y,x,grid)
      self.fa[4][1]=Wall(4,1,grid)

      self.lasers=[(1,1),(3,3),(1,6),(8,1)]
      self.autos=()
      self.note=u'Switch on all lasers by clicking them'

    elif level==2:
      self.fa[1][1]=FLaser(1,1,grid,3,timer)
      self.fa[1][1].active=True
      for y,x in [(3,1),(5,1),(3,6),(5,6)]:
        self.fa[y][x]=LaserTarget(y,x,grid)
      for y,x,d in [(8,1,1),(8,6,1)]:
        self.fa[y][x]=FlatMirror(y,x,grid,d)

      self.autos=()
      self.lasers=[(1,1)]
      self.note=u'Reflect the laser to hit all targets'

    elif level==3:
      for y,x,d in [(1,6,0),(5,0,0),(6,0,0),(7,0,0),(8,0,0)]:      
        self.fa[y][x]=Laser(y,x,grid,d,timer)
      for y,x in [(0,2),(0,3),(0,4),(0,5),(9,2),(9,5)]:
        self.fa[y][x]=LaserTarget(y,x,grid)
      for y,x,d in [(0,7,3),(3,3,1),(7,4,1),(9,3,3),(9,4,1),(9,7,1)]:
        self.fa[y][x]=FFlatMirror(y,x,grid,d)
      for y,x,d in [(1,7,1),(2,1,2),(3,1,0),(2,2,0),(3,2,2),(5,2,1),(6,3,1),(8,5,1)]:
        self.fa[y][x]=FTriMirror(y,x,grid,d)

      self.fa[7][7]=Bomb(7,7,grid)
           
      self.autos=[(7,7)]
      self.lasers=[(5,0),(6,0),(7,0),(8,0),(1,6)]
      self.note=u'Do not hit explosives!'
      
    elif level==4:
      self.fa[5][1]=FLaser(5,1,grid,0,timer)
      self.fa[5][1].active=True
      for y,x in [(1,3),(2,5),(3,5),(4,5),(5,3),(8,3),(8,2)]:
        self.fa[y][x]=LaserTarget(y,x,grid)
      for y,x,d in [(8,1,3),(8,5,1),(1,5,3)]:
        self.fa[y][x]=FFlatMirror(y,x,grid,d)
      self.fa[5][5]=TriMirror(5,5,grid,0)
      self.fa[1][1]=FlatMirror(1,1,grid,2)
      self.autos=()
      self.lasers=[(5,1)]
      self.note=u'eflecting back will destroy the laser'
      
    elif level==5:
      self.fa[5][1]=FLaser(5,1,grid,0,timer)
      self.fa[5][1].active=True
      self.lasers=[(5,1)]
      for y,x in [(0,0),(1,2),(1,7),(3,7),(5,0),(6,3),(8,2),(8,7)]:
        self.fa[y][x]=LaserTarget(y,x,grid)
      for y,x,d in [(1,0,0),(1,5,1),(3,3,3),(5,5,1),(8,0,3),(8,3,1),(8,5,1)]:
        self.fa[y][x]=FlatMirror(y,x,grid,d)
      self.autos=()
      self.note=u'Reflect the laser to hit all targets'

    elif level==6:
      self.fa[1][3]=FLaser(1,3,grid,3,timer)
      self.fa[1][3].active=True
      self.lasers=[(1,3)]
      for y,x in [(1,0),(2,3),(4,2),(6,5),(8,0)]:
        self.fa[y][x]=LaserTarget(y,x,grid)
      for y,x,d in [(4,7,2),(5,1,1),(6,1,3)]:
        self.fa[y][x]=FlatMirror(y,x,grid,d)
      for y,x,d in [(9,0,3),(9,7,1)]:
        self.fa[y][x]=FFlatMirror(y,x,grid,d)
      for y,x,d in [(5,3,3),(6,3,2)]:
        self.fa[y][x]=TriMirror(y,x,grid,d)
      self.autos=()
      self.fa[4][0]=Teleport(4,0,grid)
      self.fa[6][7]=Teleport(6,7,grid)
      self.fa[4][0].target=self.fa[6][7]
      self.fa[6][7].target=self.fa[4][0]
      self.note=u'eleporters transport laser beams'

    elif level==7:
      self.fa[2][3]=FLaser(2,3,grid,3,timer)
      self.fa[4][7]=FLaser(4,7,grid,3,timer)
      self.fa[2][3].active=True
      self.fa[4][7].active=True
      self.lasers=[(2,3),(4,7)]
      for y,x in [(0,3),(2,0),(2,5),(2,7),(4,0),(4,2),(7,0),(7,5),(7,7),(9,3)]:
        self.fa[y][x]=LaserTarget(y,x,grid)
      self.fa[4][5]=TriMirror(4,5,grid,3)
      self.fa[4][3]=ATriMirror(4,3,grid,0)
      for y,x,d in [(0,0,1),(0,7,3),(9,0,3),(9,7,1),(3,7,0)]:
        self.fa[y][x]=FFlatMirror(y,x,grid,d)
      for y in range(1,9):
        self.fa[y][1]=Wall(y,1,grid)
        self.fa[y][6]=Wall(y,6,grid)
      for x in range(2,6):
        self.fa[1][x]=Wall(1,x,grid)
        self.fa[8][x]=Wall(8,x,grid)      
      self.autos=[(4,3)]
      self.note=u'Hurry up!'

    elif level==8:
      self.fa[0][7]=Laser(0,7,grid,3,timer)
      self.fa[0][7].active=True
      for y in range(10):
        self.fa[y][6]=Wall(y,6,grid)
      for y in range(1,9):
        self.fa[y][7]=LaserTarget(y,7,grid)   
      self.fa[9][7]=Bomb(9,7,grid)
      
      for y,x,d in [(4,5,3),(5,1,3)]:
        self.fa[y][x]=FFlatMirror(y,x,grid,d)
      for y,x,d in [(1,4,3),(3,5,3),(5,2,1),(6,3,3),(6,5,1),(7,1,3)]:
        self.fa[y][x]=FlatMirror(y,x,grid,d)
      for y,x,d in [(1,1,3),(1,2,2),(1,3,1),(3,4,3),(9,2,1)]:
        self.fa[y][x]=TriMirror(y,x,grid,d)
      for y,x,d in [(7,2,2)]:
        self.fa[y][x]=FTriMirror(y,x,grid,d)
      for y,x,d in [(3,3,1),(4,0,0),(5,0,0)]:
        self.fa[y][x]=FLaser(y,x,grid,d,timer)
        self.fa[y][x].active=True
      for y,x in [(1,0),(5,4),(9,4),(7,4),(9,0),(9,5)]:
        self.fa[y][x]=LaserTarget(y,x,grid)
        
      self.autos=[(9,7)]
      self.lasers=[(0,7),(3,3),(4,0),(5,0)]
      self.note=u'The count down runs!'

    elif level==9:   
      self.fa[3][0]=Bomb(3,0,grid)
      self.fa[4][0]=Laser(4,0,grid,0,timer)
      for y,x in [(0,0),(2,0),(3,2),(4,7),(5,4),(5,7),(7,0),(7,3),(8,7),(9,0),(9,2),(9,6)]:
        self.fa[y][x]=LaserTarget(y,x,grid)      
      for y,x,d in [(0,1,1),(0,2,3),(0,3,1),(0,4,3),(0,5,1),(0,6,3),(1,0,3),(1,3,1),(1,5,1),(1,7,3),(2,4,1),(2,7,1),(4,4,3),(4,6,1),(5,3,1),(6,2,1),(6,3,3),(6,4,3),(6,5,1),(7,6,1),(8,3,3),(8,4,1),(9,1,1),(9,3,3),(9,4,1),(9,5,1),(9,7,1)]:
        self.fa[y][x]=FlatMirror(y,x,grid,d)
      for y,x,d in [(0,7,3),(2,5,1),(3,1,3),(3,5,1),(3,6,1),(3,7,3),(4,2,1),(4,5,1),(5,0,1),(5,2,1),(5,5,3),(5,6,3),(7,1,1),(7,2,3)]:
        self.fa[y][x]=FFlatMirror(y,x,grid,d)
      for y,x,d in [(1,1,0),(1,2,0),(1,4,3),(1,6,0),(2,1,0),(2,2,0),(4,1,1),(4,3,1),(5,1,0),(6,0,3),(6,6,1),(8,0,1),(8,2,3),(8,5,0)]:
        self.fa[y][x]=FTriMirror(y,x,grid,d)
      for y,x,d in [(2,3,2),(2,6,0),(3,3,0),(3,4,0),(6,1,2),(6,7,1),(7,4,0),(7,5,1),(7,7,1),(8,1,3),(8,6,1)]:
        self.fa[y][x]=TriMirror(y,x,grid,d)
        
      self.autos=[(3,0)]
      self.lasers=[(4,0)]
      self.note=u'Trial and error!'

class Main(object):
  def __init__(self):
    self.running=1
    appuifw.app.exit_key_handler=self.quit
    appuifw.app.menu=[(u"Restart Level",self.startLevel),(u"About Tricky Mirrors",self.about),(u"Select level",self.selectLevel),(u"Exit",self.quit)]
    self.level=1
#    if len(sys.argv)>1 and sys.argv[1]:
#       self.level=int(sys.argv[1])
    global gf
    self.startLevel()
  def quit(self):
    if appuifw.query(u"Quit Tricky Mirrors?",'query'):
      self.running=0
  def startLevel(self):
    global gf
    LASERCOLOR.reset()
    timer.cnt=-1
    timer.destroyed=False
    gf=Gamefield(self.level)
  def selectLevel(self):
    l=appuifw.query(u"Select level",'number',self.level)
    if not l is None:
      if l<1 or l>gf.NUMLEVELS:
        l=1
      self.level=l
      self.startLevel()
  def mainLoop(self):
    global gf
    while self.running:
      if gf.dirty:
        img.clear(0x000030)
        gf.draw(img)
      handle_redraw(())
      e32.ao_sleep(0.2)
      if LaserTarget.cnt==0:
        appuifw.note(u'Level completed! :-)')
        if self.level < gf.NUMLEVELS: 
           self.level=self.level+1
           self.startLevel()
        else:
          appuifw.note(u'You have finished the last level!')
          self.about()
          self.quit()
          if self.running:
              self.level=1
              self.startLevel()
      self.dirty=timer.step()
      if timer.destroyed:
        if appuifw.query(u'Boom!\nRestart level?','query'):
          self.startLevel()
        else:
          self.quit()          
      if keyboard.pressed(EScancodeLeftArrow):
        grid.l()
        gf.dirty=True
      if keyboard.pressed(EScancodeRightArrow): 
        grid.r()
        gf.dirty=True
      if keyboard.pressed(EScancodeDownArrow):  
        grid.d()
        gf.dirty=True
      if keyboard.pressed(EScancodeUpArrow): 
        grid.u()
        gf.dirty=True
      if keyboard.pressed(EScancodeSelect):
        fld=gf.fa[grid.cy][grid.cx]
        if isinstance(fld, Laser) and not isinstance(fld, ALaser):
          fld.active=not fld.active
          gf.reactivate()
        elif isinstance(fld, Mirror):
          fld.turn()
          gf.reactivate()
  def about(self):
    appuifw.note(u'Tricky Mirrors V'+VERSION+u' \n (c) 07-2006, 08-2008 Goetz Schwandtner\nschwandtner@googlemail.com')

#global:
m=Main()
m.mainLoop()
appuifw.app.set_exit()
