import os
from random import choice

class Pixel(object):
    def __init__( _ ):
        pass

class VM(object):
    def __init__( _, rna ):
        _.bucket = Bucket()
        _.pos = Pos()
        _.mark = Pos()
        _.bitmaps = [Bitmap()]
        _.rna = rna
    def currentPixel( _ ):
        return _.bucket.currentPixel()
    def build( _ ):
        for r in _.rna:
            if r == 'PIPIIIC': _.bucket.addColor(0,0,0)
            elif r == 'PIPIIIP': _.bucket.addColor(255,0,0)
            elif r == 'PIPIICC': _.bucket.addColor(0,255,0)
            elif r == 'PIPIICF': _.bucket.addColor(255,255,0)
            elif r == 'PIPIICP': _.bucket.addColor(0,0,255)
            elif r == 'PIPIIFC': _.bucket.addColor(255,0,255)
            elif r == 'PIPIIFF': _.bucket.addColor(0,255,255)
            elif r == 'PIPIIPC': _.bucket.addColor(255,255,255)
            elif r == 'PIPIIPF': _.bucket.addOpac(0)
            elif r == 'PIPIIPP': _.bucket.addOpac(255)
            elif r == 'PIIPICP': _.bucket.reset()
            elif r == 'PIIIIIP': _.pos.move()
            elif r == 'PCCCCCP': _.pos.turnCounterClockwise()
            elif r == 'PFFFFFP': _.pos.turnClockwise()
            elif r == 'PCCIFFP': _.mark.mark(_.pos.pos())
            elif r == 'PFFICCP': _.bitmaps[0].line(_.pos.pos(), _.mark.pos(), _.currentPixel())
            elif r == 'PIIPIIP': _.bitmaps[0].tryfill(_.pos.pos(), _.currentPixel())
            elif r == 'PCCPFFP': _.addBitmap(Bitmap())
            elif r == 'PFFPCCP': _.compose()
            elif r == 'PFFICCF': _.clip()
            else: pass
    def compose( _ ):
        if len(_.bitmaps) >= 2:
            a = _.bitmaps.pop(0)
            b = _.bitmaps.pop(0)
            _.addBitmap(b.compose(a))
    def clip( _ ):
        if len(_.bitmaps) >= 2:
            a = _.bitmaps.pop(0)
            b = _.bitmaps.pop(0)
            _.addBitmap(b.clip(a))
    def addBitmap( _, bitmap ):
        if len(_.bitmaps) < 10:
            _.bitmaps = [bitmap] + _.bitmaps

class Pos(object):
    def __init__( _ ):
        _.x = 0
        _.y = 0
        _.dir = 0 # 0:East 1:South 2:West 3:North
    def move( _ ):
        if _.dir == 0: _.x = (_.x + 1) % 600
        elif _.dir == 2: _.x = (_.x - 1) % 600
        elif _.dir == 1: _.y = (_.y + 1) % 600
        elif _.dir == 3: _.y = (_.y - 1) % 600
    def turnClockwise( _ ):
        _.dir = (_.dir + 1) % 4
    def turnCounterClockwise( _ ):
        _.dir = (_.dir - 1) % 4
    def mark( _, pos ):
        _.x, _.y = pos
    def pos( _ ):
        return _.x, _.y

class Bucket(object):
    def __init__( _ ):
        _.reset()
    def reset( _ ):
        _.r = _.g =_.b = _.o = _.c_num = _.o_num = 0
    def currentPixel( _ ):
        r = g = b = 0
        o = 255
        if _.c_num:
            r = _.r / _.c_num
            g = _.g / _.c_num
            b = _.b / _.c_num
        if _.o_num:
            o = _.o / _.o_num
        return r*o/255, g*o/255, b*o/255, o
    def addColor( _, *color ):
        r, g, b = color
        _.r += r
        _.g += g
        _.b += b
        _.c_num += 1
    def addOpac( _, opac ):
        _.o += opac
        _.o_num += 1
    def __str__( _ ):
        return str(_.currentPixel())

class Bitmap(object):
    def __init__( _ ):
        _.bitmap = [[(0,0,0,0)for x in xrange(600)]for x in xrange(600)]
    def __str__( _ ):
        ppm = ''
        for raw in _.bitmap:
            try:
             ppm += ''.join('%c%c%c'%(r,g,b)for r,g,b,a in raw)
            except:print raw
        return 'P6 600 600 255 ' + ppm
    def setPixel( _, pos, pixel ):
        x, y = pos
        _.bitmap[y][x] = pixel
    def getPixel( _, pos ):
        x, y = pos
        return _.bitmap[y][x]
    def line( _, pos0, pos1, pixel ):
        x0, y0 = pos0
        x1, y1 = pos1
        dx, dy = x1 - x0, y1 - y0
        d = max([abs(dx), abs(dy)])
        c = dx*dy <= 0
        x = d*x0 + (d - c)/2
        y = d*y0 + (d - c)/2
        for i in xrange(d):
            _.setPixel((x/d, y/d), pixel)
            x+=dx
            y+=dy
        _.setPixel((x1, y1), pixel)
    def tryfill( _, pos, pixel):
        old = _.getPixel(pos)
        if old != pixel:
            print pos,old,pixel
            _.fill(pos, pixel, old)
    def fill( _, pos, pixel, initial ):
        x, y = pos
        try:
            if _.getPixel(pos) == initial:
                _.setPixel(pos, pixel)
                if x>0  :_.fill((x-1,y), pixel, initial)
                if x<599:_.fill((x+1,y), pixel, initial)
                if y>0  :_.fill((x,y-1), pixel, initial)
                if y<599:_.fill((x,y+1), pixel, initial)
        except:pass
    def compose( _, a ):
        for x in xrange(600):
            for y in xrange(600):
                r0,g0,b0,a0 = _.bitmap[y][x]
                r1,g1,b1,a1 = a.bitmap[y][x]
                _.bitmap[y][x] = (r1 + r0*(255 - a1)/255,
                                  g1 + g0*(255 - a1)/255,
                                  b1 + b0*(255 - a1)/255,
                                  a1 + a0*(255 - a1)/255)
        return _
    def clip( _, a ):
        for x in xrange(600):
            for y in xrange(600):
                r0,g0,b0,a0 = _.bitmap[y][x]
                r1,g1,b1,a1 = a.bitmap[y][x]
                _.bitmap[y][x] = (r0*(a1/255),
                                  g0*(a1/255),
                                  b0*(a1/255),
                                  a0*(a1/255))
        return _

if __name__ == '__main__':
    import sys
    print sys.argv[1]
    rna = open(sys.argv[1]).read().split()
    vm = VM(rna)
    vm.build()
    print vm.bitmaps[0].bitmap[0][:10]
    print vm.bitmaps[0].bitmap[1][:10]
    open('test2.ppm','w').write(str(vm.bitmaps[0]))
    os.system('convert test2.ppm test2.png')