#!/usr/bin/python 

"""
The Python Imlac emulator (pymlac).

Console-only version
"""

import sys
import os
import wx 

from Globals import *
import Imlac

import Memory
import Ptr
import Ptp
import MainCPU
import Trace


# map ROM name to type
RomTypeMap = {'ptr': ROM_PTR,
              'tty': ROM_TTY,
              'none': ROM_NONE}

count = 1

def abort(msg):
    """Handle a terminal problem."""

    print(msg)
    sys.exit(1)

def check_int(value, msg):
    """Check that a value is a valid 16 bit positive value.
   
    We allow decimal and octal number representations.
    """

    try:
        if str(value)[0] == '0':
            data = int(value, 8)
        else:
            data = int(value)
    except:
        abort(msg)
    if data < 0 or data > 0177777:
        abort(msg)

    return data

def get_next(options, index, msg):
    """If possible, get next arg in list."""

    if index < len(options):
        next_arg = options[index]
    else:
        abort(msg)

    return next_arg

def handle_options():
    """Routine to analyse command line options.

    Returns a list of operation objects which are tuples:
        (OPERATION, ARGS)
    """

    options = sys.argv[1:]

    index = 0
    result = []
    boot_rom = 'ptr'

    while index < len(options):
        arg = options[index]
        index += 1

        if arg[0] == '-':
            if arg == '-b':
                next_arg = get_next(options, index,
                                    "-b option must be 'ptr' or 'tty' or 'none'")
                index += 1
                next_arg = next_arg.lower()
                #next_arg = RomTypeMap.get(next_arg, False)

                if next_arg:
                    op = ('boot', next_arg)
                    boot_rom = next_arg
                else:
                    abort("-b option must be 'ptr', 'tty' or 'none'")
            elif arg == '-c':
                op = ('clear', boot_rom)
            elif arg == '-d':
                next_arg = get_next(options, index,
                                    "-d option must be data switch value, positive & max 16 bits")
                index += 1
                data = check_int(next_arg,
                                 "-d option must be data switch value, positive & max 16 bits")
                op = ('data', data)
            elif arg == '-h':
                usage()
            elif arg == '-ptp':
                next_arg = get_next(options, index,
                                    "-ptp option must be papertape punch file")
                index += 1
                if not os.path.isfile(next_arg):
                    abort("File %s isn't a papertape file" % next_arg)
                op = ('load_ptp', next_arg)
            elif arg == '-ptr':
                next_arg = get_next(options, index,
                                    "-ptr option must be papertape reader file")
                index += 1
                if not os.path.isfile(next_arg):
                    abort("File %s isn't a papertape file" % next_arg)
                op = ('load_ptr', next_arg)
            elif arg == '-r':
                next_arg = get_next(options, index,
                                    "-r option must be 'PC' or run address, positive & max 16 bits")
                index += 1
                next_arg = next_arg.lower()
                if next_arg == 'pc':
                    op = ('run', None)
                else:
                    address = check_int(next_arg,
                                        "-r option must be 'PC' or run address, positive & max 16 bits")
                    op = ('run', address)
            elif arg == '-s':
                next_arg = get_next(options, index,
                                    "-s option must be set file")
                index += 1
                if not os.path.isfile(next_arg):
                    abort("File %s isn't a 'set' file" % next_arg)
                op = ('set', next_arg)
            elif arg == '-t':
                next_arg = get_next(options, index,
                                    "-t option must be trace range")
                index += 1
                addr = next_arg.split(',')
                if len(addr) == 1:
                    trace1 = addr[0]
                    if trace1.lower() == 'off':
                        trace1 = None
                    else:
                        trace1 = check_int(trace1,
                                           "-t option must be trace range")
                    trace2 = None
                elif len(addr) == 2:
                    trace1 = check_int(addr[0], "-t option must be trace range")
                    trace2 = check_int(addr[1], "-t option must be trace range")
                else:
                    abort("-t option must be trace range")
                op = ('trace', (trace1, trace2))
            elif arg == '-ttyin':
                next_arg = get_next(options, index,
                                    "-ttyin option must be teletype input file")
                index += 1
                if not os.path.isfile(next_arg):
                    abort("File %s isn't a teletype file" % next_arg)
                op = ('load_ttyin', next_arg)
            elif arg == '-ttyout':
                next_arg = get_next(options, index,
                                    "-ttyout option must be teletype output file")
                index += 1
                if not os.path.isfile(next_arg):
                    abort("File %s isn't a teletype file" % next_arg)
                op = ('load_ttyout', next_arg)
            elif arg == '-v':
                next_arg = get_next(options, index,
                                    "-v option must be view file")
                index += 1
                if not os.path.isfile(next_arg):
                    abort("File %s isn't a 'view' file" % next_arg)
                op = ('view', next_arg)
            elif arg == '-w':
                next_arg = get_next(options, index,
                                    "-W option must be ON|OFF")
                index += 1
                next_arg = next_arg.lower()
                if next_arg in ['on', 'off']:
                    op = ('write', next_arg)
                else:
                    abort("-w option must be 'ON' or 'OFF'")
            else:
                usage()
        else:
            usage()

        result.append(op)
    return result

def usage():
    """Help for befuddled user."""

    print('Usage:\n')
    print('pymlac [-b (ptr|tty|none)] [-c] [-t [<a>[,<b>]]] [-r <address>] [<imlacfile>]\n')
    print('where -b (ptr|tty|none)           sets the bootstrap ROM code, if no device disable ROM')
    print('      -c                          clear core, except bootstrap ROM')
    print('      -d <value>                  set data switches')
    print('      -h                          prints this help')
    print('      -ptp <file>                 mount <file> on the papertape punch')
    print('      -ptr <file>                 mount <file> on the papertape reader')
    print('      -r (<address>|PC)           execute from the <address>, no address runs from current PC')
    print('      -s <setfile>                sets memory values from file')
    print('      -t (<addr1>[,<addr2>]|off)  controls trace:')
    print('                                    -t 100     trace from address 0100')
    print('                                    -t 100,200 traces between addresses 100 and 200')
    print('                                    -t off     trace OFF')
    print('      -ttyin <file>               mount <file> on the teletype reader')
    print('      -ttyout <file>              mount <file> on the teletype writer')
    print('      -v <viewfile>               prints memory locations from file')
    print('      -w (on|off)                 turn ROM writability ON or OFF')
    sys.exit()


def main():
    """Start of the Imlac emulator."""

    # get operations list
    ops = handle_options()

    # Initialize the emulator.
    boot_rom = 'ptr'    # default ROM loader
    Imlac.init(0, TRACE_FILENAME, None, None, boot_rom, CORE_FILENAME)

    # now perform operations
    for (operation, args) in ops:
        if operation == 'boot':
            Memory.set_ROM(args)
            Trace.comment('Bootstrap ROM set to %s' % args.upper())
        elif operation == 'clear':
            Memory.clear_core()
            Trace.comment('Core cleared')
        elif operation == 'load_ptp':
            Ptp.mount(args)
            Trace.comment("File '%s' mounted on PTP" % args)
        elif operation == 'load_ptr':
            Ptr.mount(args)
            Trace.comment("File '%s' mounted on PTR" % args)
        elif operation == 'data':
            MainCPU.DS = args
            Trace.comment('Dataswitch value set to %06o' % args)
        elif operation == 'run':
            MainCPU.PC = args
            Trace.comment('Running from address %06o' % args)
            if Imlac.tracestart:
                Trace.comment('DPC\tDisplay\t\tPC\tMain\t\tRegs')
                Trace.comment('------  -------------   ------  --------------  '
                              '-----------------------')
            Imlac.run()
            Trace.comment('Imlac halted')
        elif operation == 'set':
            Trace.comment("Setting memory from file '%s'" % args)
        elif operation == 'trace':
            if args == 'off':
                Imlac.tracestart = None
                Imlac.traceend = None
            else:
                (start, end) = args
                Imlac.tracestart = start
                Imlac.traceend = end
            tstart = Imlac.tracestart
            if tstart is not None:
                tstart = '%06o' % tstart
            tend = Imlac.traceend
            if tend is not None:
                tend = '%06o' % tend
            Trace.comment('Trace set to (%s, %s)' % (tstart, tend))
        elif operation == 'ttyin':
            TtyIn.mount(args)
            Trace.comment("File '%s' mounted on TTYIN" % args)
        elif operation == 'ttyout':
            TtyOut.mount(args)
            Trace.comment("File '%s' mounted on TTYOUT" % args)
        elif operation == 'view':
            Trace.comment("Viewing memory from file '%s'" % args)
        elif operation == 'write':
            if args == 'on':
                Memory.using_rom = True
            elif args == 'off':
                Memory.using_rom = False
            else:
                abort("Invalid view arg: %s" % args)
            Trace.comment('ROM write protect set %s' % args.upper())
        else:
            abort('Invalid internal operation: %s' % operation)

    Imlac.close(CORE_FILENAME)

class Led_1(object):
    def __init__(self, parent, label, x, y, off, on):
        wx.StaticText(parent, -1, label, pos=(x, y))
        y += 15
        wx.StaticBitmap(parent, -1, off, pos=(x-1, y))
        self.led = wx.StaticBitmap(parent, -1, on, pos=(x-1, y))
        self.set_value(0)

    def set_value(self, value):
        if value:
            self.led.Enable()
        else:
            self.led.Disable()
        

class Led_16(object):
    def __init__(self, parent, label, x, y, off, on):
        led_width = off.GetWidth()
        led_height = off.GetHeight()
        wx.StaticText(parent, -1, label, pos=(x, y))
        y += 15
        self.leds = []
        mark_count = 2
        ticks = [(x-17+led_width,y+led_height/2+5)]
        dc = wx.PaintDC(parent)
        for i in range(16):
            wx.StaticBitmap(parent, -1, off, pos=(x-1+i*17, y))
            led = wx.StaticBitmap(parent, -1, on, pos=(x-1+i*17, y))
            self.leds.append(led)
            mark_count += 1
            if mark_count >= 3:
                mark_count = 0
                ticks.append((x+i*17 + led_width, y+led_height/2+5))

        self.set_value(0)
        self.ticks = ticks

    def set_value(self, value):
        mask = 0x8000
        for l in self.leds:
            if value & mask:
                l.Enable()
            else:
                l.Disable()
            mask = mask >> 1
        

class MyFrame(wx.Frame): 
    """a frame with two panels"""

    WIDTH_SCREEN = 1024
    HEIGHT_SCREEN = 1024
    WIDTH_CONSOLE = 330 # 400 # 256
    HEIGHT_CONSOLE = HEIGHT_SCREEN

    SCREEN_COLOUR = (0, 0, 0)
    CONSOLE_COLOUR = (255, 223, 169)
    PHOSPHOR_COLOUR = '#F0F000'	# yellow
    #PHOSPHOR_COLOUR = '#40FF40'	# green

    V_MARGIN = 20
    CTL_MARGIN = 15
    LED_MARGIN = 5

    IMAGE_LED_OFF = 'images/led_off.png'
    IMAGE_LED_ON = 'images/led_on.png'

    INC = 0.01

    def __init__(self, parent=None, id=-1, title=None): 
        wx.Frame.__init__(self, parent, id, title) 

        self.make_gui()
        self.run()

    def make_gui(self):
        self.screen = wx.Panel(self,
                               size=(self.WIDTH_SCREEN, self.HEIGHT_SCREEN),
                               pos=(0,0)) 
        self.screen.SetBackgroundColour(self.SCREEN_COLOUR)
        self.screen.Bind(wx.EVT_PAINT, self.on_paint) 
        self.console = wx.Panel(self, style=wx.SIMPLE_BORDER,
                                size=(self.WIDTH_CONSOLE, self.HEIGHT_SCREEN),
                                pos=(self.WIDTH_SCREEN,0)) 
        self.console.SetBackgroundColour(self.CONSOLE_COLOUR)
        self.console.Bind(wx.EVT_PAINT, self.on_paint) 

        python_png = wx.Image('images/PythonPowered.png',
                              wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        python_height = python_png.GetHeight()
        python_width = python_png.GetWidth()

        wxpython_png = wx.Image('images/wxPython2.png',
                                wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        wxpython_height = wxpython_png.GetHeight()
        wxpython_width = wxpython_png.GetWidth()

        h_margin = (self.WIDTH_CONSOLE - wxpython_width - python_width) / 3

        png_height = max(python_height, wxpython_height) + self.V_MARGIN

        v_margin = (png_height - python_height)/2
        python_ypos = self.HEIGHT_CONSOLE - png_height + v_margin
        v_margin = (png_height - wxpython_height)/2
        wxpython_ypos = self.HEIGHT_CONSOLE -  png_height + v_margin

        wx.StaticBitmap(self.console, -1, python_png,
                        pos=(h_margin, python_ypos))
        wx.StaticBitmap(self.console, -1, wxpython_png,
                        pos=(python_width + 2*h_margin, wxpython_ypos))

        self.png_height = png_height

        led_off = wx.Image('images/led_off.png',
                           wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        led_on = wx.Image('images/led_on.png',
                          wx.BITMAP_TYPE_PNG).ConvertToBitmap()

        y_pos = 8
        self.led_l = Led_1(self.console, 'l', self.CTL_MARGIN, y_pos,
                           led_off, led_on)
        self.led_ac = Led_16(self.console, 'ac', 3*self.CTL_MARGIN, y_pos,
                             led_off, led_on)
        y_pos += 35
        self.led_pc = Led_16(self.console, 'pc', 3*self.CTL_MARGIN, y_pos,
                             led_off, led_on)


        y_pos = 305
        wx.StaticText(self.console, -1, 'ptr', pos=(self.CTL_MARGIN, y_pos))
        y_pos += 15
        self.txt_ptrFile = wx.TextCtrl(self.console, -1,
                                       pos=(self.CTL_MARGIN, y_pos),
                                       size=(self.WIDTH_CONSOLE-2*self.CTL_MARGIN, 25))
        y_pos += 30

        wx.StaticText(self.console, -1, 'ptp', pos=(self.CTL_MARGIN, y_pos))
        y_pos += 15
        self.txt_ptpFile = wx.TextCtrl(self.console, -1,
                                       pos=(self.CTL_MARGIN, y_pos),
                                       size=(self.WIDTH_CONSOLE-2*self.CTL_MARGIN, 25))
        y_pos += 15

        dc = wx.PaintDC(self.console)
        dc.SetPen(wx.Pen('black', 1))
        dc.DrawLine(0, self.HEIGHT_CONSOLE - self.png_height,
                    self.WIDTH_CONSOLE-1, self.HEIGHT_CONSOLE - self.png_height)

        for (x, y) in self.led_ac.ticks:
            dc.DrawLine(x, y, x, y+5)
        first = self.led_ac.ticks[0]
        last = self.led_ac.ticks[-1]
        (x1, y1) = first
        (x2, y2) = last
        dc.DrawLine(x1, y2+5, x2, y2+5)

        for (x, y) in self.led_pc.ticks:
            dc.DrawLine(x, y, x, y+5)
        first = self.led_pc.ticks[0]
        last = self.led_pc.ticks[-1]
        (x1, y1) = first
        (x2, y2) = last
        dc.DrawLine(x1, y2+5, x2, y2+5)

        self.y_offset = 0
        self.y_sign = +1

        self.Fit() 

    def run(self):
        # get operations list
        ops = handle_options()
    
        # Initialize the emulator.
        boot_rom = 'ptr'    # default ROM loader
        Imlac.init(0, TRACE_FILENAME, None, None, boot_rom, CORE_FILENAME)
    
        # now perform operations
        for (operation, args) in ops:
            if operation == 'boot':
                Memory.set_ROM(args)
                Trace.comment('Bootstrap ROM set to %s' % args.upper())
                self.on_paint()
            elif operation == 'clear':
                Memory.clear_core()
                Trace.comment('Core cleared')
                self.on_paint()
            elif operation == 'load_ptp':
                Ptp.mount(args)
                Trace.comment("File '%s' mounted on PTP" % args)
                self.on_paint()
            elif operation == 'load_ptr':
                Ptr.mount(args)
                Trace.comment("File '%s' mounted on PTR" % args)
                self.on_paint()
            elif operation == 'data':
                MainCPU.DS = args
                Trace.comment('Dataswitch value set to %06o' % args)
                self.on_paint()
            elif operation == 'run':
                MainCPU.PC = args
                Trace.comment('Running from address %06o' % args)
                if Imlac.tracestart:
                    Trace.comment('DPC\tDisplay\t\tPC\tMain\t\tRegs')
                    Trace.comment('------  -------------   ------  --------------  '
                                  '-----------------------')
                self.on_paint()
                Imlac.run()
                self.on_paint()
                Trace.comment('Imlac halted')
                self.on_paint()
            elif operation == 'set':
                Trace.comment("Setting memory from file '%s'" % args)
                self.on_paint()
            elif operation == 'trace':
                if args == 'off':
                    Imlac.tracestart = None
                    Imlac.traceend = None
                else:
                    (start, end) = args
                    Imlac.tracestart = start
                    Imlac.traceend = end
                tstart = Imlac.tracestart
                if tstart is not None:
                    tstart = '%06o' % tstart
                tend = Imlac.traceend
                if tend is not None:
                    tend = '%06o' % tend
                Trace.comment('Trace set to (%s, %s)' % (tstart, tend))
                self.on_paint()
            elif operation == 'ttyin':
                TtyIn.mount(args)
                Trace.comment("File '%s' mounted on TTYIN" % args)
                self.on_paint()
            elif operation == 'ttyout':
                TtyOut.mount(args)
                Trace.comment("File '%s' mounted on TTYOUT" % args)
                self.on_paint()
            elif operation == 'view':
                Trace.comment("Viewing memory from file '%s'" % args)
                self.on_paint()
            elif operation == 'write':
                if args == 'on':
                    Memory.using_rom = True
                elif args == 'off':
                    Memory.using_rom = False
                else:
                    abort("Invalid view arg: %s" % args)
                Trace.comment('ROM write protect set %s' % args.upper())
                self.on_paint()
            else:
                abort('Invalid internal operation: %s' % operation)
    
        Imlac.close(CORE_FILENAME)


    def on_paint(self, event=None):
        global count

        # establish the painting surface
        dc = wx.PaintDC(self.screen)
        dc.SetBackground(wx.Brush(self.SCREEN_COLOUR, 1))
        dc.SetPen(wx.Pen(self.PHOSPHOR_COLOUR, 1))
        dc.Clear()
        if self.y_sign > 0:
            self.y_offset = self.y_offset + self.INC
            if self.y_offset > self.HEIGHT_SCREEN-1:
                self.y_sign = -1
                self.y_offset = self.HEIGHT_SCREEN-1
        else:
            self.y_offset = self.y_offset - self.INC
            if self.y_offset < 0:
                self.y_sign = +1
                self.y_offset = 0
        dc.DrawLine(0, int(self.y_offset), self.WIDTH_SCREEN-1, int(self.HEIGHT_SCREEN-self.y_offset-1))
        dc.DrawLine(0, int(self.HEIGHT_SCREEN-self.y_offset-1), self.WIDTH_SCREEN-1, int(self.y_offset))

        dc = wx.PaintDC(self.console)
        #dc.SetPen(wx.Pen('black', wx.DOT))
        dc.SetPen(wx.Pen('black', 1))
        dc.DrawLine(0, self.HEIGHT_CONSOLE - self.png_height,
                    self.WIDTH_CONSOLE-1, self.HEIGHT_CONSOLE - self.png_height)

        for (x, y) in self.led_ac.ticks:
            dc.DrawLine(x, y, x, y+5)
        first = self.led_ac.ticks[0]
        last = self.led_ac.ticks[-1]
        (x1, y1) = first
        (x2, y2) = last
        dc.DrawLine(x1, y2+5, x2, y2+5)

        for (x, y) in self.led_pc.ticks:
            dc.DrawLine(x, y, x, y+5)
        first = self.led_pc.ticks[0]
        last = self.led_pc.ticks[-1]
        (x1, y1) = first
        (x2, y2) = last
        dc.DrawLine(x1, y2+5, x2, y2+5)

        count += 1
        self.led_ac.set_value(count)


        pass


# test it ...
app = wx.PySimpleApp() 
frame1 = MyFrame(title='pymlac 0.1') 
frame1.Center() 
frame1.Show() 
app.MainLoop()

sys.exit(0)


#import profile
#profile.run('main()', 'profile.out')

main()






sys.exit(0)


count = 1

class Led_1(object):
    def __init__(self, parent, label, x, y, off, on):
        wx.StaticText(parent, -1, label, pos=(x, y))
        y += 15
        wx.StaticBitmap(parent, -1, off, pos=(x-1, y))
        self.led = wx.StaticBitmap(parent, -1, on, pos=(x-1, y))
        self.set_value(0)

    def set_value(self, value):
        if value:
            self.led.Enable()
        else:
            self.led.Disable()
        

class Led_16(object):
    def __init__(self, parent, label, x, y, off, on):
        led_width = off.GetWidth()
        led_height = off.GetHeight()
        wx.StaticText(parent, -1, label, pos=(x, y))
        y += 15
        self.leds = []
        mark_count = 2
        ticks = [(x-17+led_width,y+led_height/2+5)]
        dc = wx.PaintDC(parent)
        for i in range(16):
            wx.StaticBitmap(parent, -1, off, pos=(x-1+i*17, y))
            led = wx.StaticBitmap(parent, -1, on, pos=(x-1+i*17, y))
            self.leds.append(led)
            mark_count += 1
            if mark_count >= 3:
                mark_count = 0
                ticks.append((x+i*17 + led_width, y+led_height/2+5))

        self.set_value(0)
        self.ticks = ticks

    def set_value(self, value):
        mask = 0x8000
        for l in self.leds:
            if value & mask:
                l.Enable()
            else:
                l.Disable()
            mask = mask >> 1
        

class MyFrame(wx.Frame): 
    """a frame with two panels"""

    WIDTH_SCREEN = 1024
    HEIGHT_SCREEN = 1024
    WIDTH_CONSOLE = 330 # 400 # 256
    HEIGHT_CONSOLE = HEIGHT_SCREEN

    SCREEN_COLOUR = (0, 0, 0)
    CONSOLE_COLOUR = (255, 223, 169)
    PHOSPHOR_COLOUR = '#F0F000'	# yellow
    #PHOSPHOR_COLOUR = '#40FF40'	# green

    V_MARGIN = 20
    CTL_MARGIN = 15
    LED_MARGIN = 5

    IMAGE_LED_OFF = 'images/led_off.png'
    IMAGE_LED_ON = 'images/led_on.png'

    def __init__(self, parent=None, id=-1, title=None): 
        wx.Frame.__init__(self, parent, id, title) 

        self.make_gui()
#        self.run()

    def make_gui(self):
        self.screen = wx.Panel(self,
                               size=(self.WIDTH_SCREEN, self.HEIGHT_SCREEN),
                               pos=(0,0)) 
        self.screen.SetBackgroundColour(self.SCREEN_COLOUR)
        self.screen.Bind(wx.EVT_PAINT, self.on_paint) 
        self.console = wx.Panel(self, style=wx.SIMPLE_BORDER,
                                size=(self.WIDTH_CONSOLE, self.HEIGHT_SCREEN),
                                pos=(self.WIDTH_SCREEN,0)) 
        self.console.SetBackgroundColour(self.CONSOLE_COLOUR)
        self.console.Bind(wx.EVT_PAINT, self.on_paint) 

        python_png = wx.Image('images/PythonPowered.png',
                              wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        python_height = python_png.GetHeight()
        python_width = python_png.GetWidth()

        wxpython_png = wx.Image('images/wxPython2.png',
                                wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        wxpython_height = wxpython_png.GetHeight()
        wxpython_width = wxpython_png.GetWidth()

        h_margin = (self.WIDTH_CONSOLE - wxpython_width - python_width) / 3

        png_height = max(python_height, wxpython_height) + self.V_MARGIN

        v_margin = (png_height - python_height)/2
        python_ypos = self.HEIGHT_CONSOLE - png_height + v_margin
        v_margin = (png_height - wxpython_height)/2
        wxpython_ypos = self.HEIGHT_CONSOLE -  png_height + v_margin

        wx.StaticBitmap(self.console, -1, python_png,
                        pos=(h_margin, python_ypos))
        wx.StaticBitmap(self.console, -1, wxpython_png,
                        pos=(python_width + 2*h_margin, wxpython_ypos))

        self.png_height = png_height

        led_off = wx.Image('images/led_off.png',
                           wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        led_on = wx.Image('images/led_on.png',
                          wx.BITMAP_TYPE_PNG).ConvertToBitmap()

        y_pos = 8
        self.led_l = Led_1(self.console, 'l', self.CTL_MARGIN, y_pos,
                           led_off, led_on)
        self.led_ac = Led_16(self.console, 'ac', 3*self.CTL_MARGIN, y_pos,
                             led_off, led_on)
        y_pos += 35
        self.led_pc = Led_16(self.console, 'pc', 3*self.CTL_MARGIN, y_pos,
                             led_off, led_on)

        y_pos = 305
        wx.StaticText(self.console, -1, 'ptr', pos=(self.CTL_MARGIN, y_pos))
        y_pos += 15
        self.txt_ptrFile = wx.TextCtrl(self.console, -1,
                                       pos=(self.CTL_MARGIN, y_pos),
                                       size=(self.WIDTH_CONSOLE-2*self.CTL_MARGIN, 25))
        y_pos += 30

        wx.StaticText(self.console, -1, 'ptp', pos=(self.CTL_MARGIN, y_pos))
        y_pos += 15
        self.txt_ptpFile = wx.TextCtrl(self.console, -1,
                                       pos=(self.CTL_MARGIN, y_pos),
                                       size=(self.WIDTH_CONSOLE-2*self.CTL_MARGIN, 25))
        y_pos += 15

        dc = wx.PaintDC(self.console)
        dc.SetPen(wx.Pen('black', 1))
        dc.DrawLine(0, self.HEIGHT_CONSOLE - self.png_height,
                    self.WIDTH_CONSOLE-1, self.HEIGHT_CONSOLE - self.png_height)

        for (x, y) in self.led_ac.ticks:
            dc.DrawLine(x, y, x, y+5)
        first = self.led_ac.ticks[0]
        last = self.led_ac.ticks[-1]
        (x1, y1) = first
        (x2, y2) = last
        dc.DrawLine(x1, y2+5, x2, y2+5)

        for (x, y) in self.led_pc.ticks:
            dc.DrawLine(x, y, x, y+5)
        first = self.led_pc.ticks[0]
        last = self.led_pc.ticks[-1]
        (x1, y1) = first
        (x2, y2) = last
        dc.DrawLine(x1, y2+5, x2, y2+5)

        self.y_offset = 0
        self.y_sign = +1

        self.Fit() 

    def on_paint(self, event):
        global count

        # establish the painting surface
        dc = wx.PaintDC(self.screen)
        dc.SetBackground(wx.Brush(self.SCREEN_COLOUR, 1))
        dc.SetPen(wx.Pen(self.PHOSPHOR_COLOUR, 1))
        dc.Clear()
        if self.y_sign > 0:
            self.y_offset = self.y_offset + self.INC
            if self.y_offset > self.HEIGHT_SCREEN-1:
                self.y_sign = -1
                self.y_offset = self.HEIGHT_SCREEN-1
        else:
            self.y_offset = self.y_offset - self.INC
            if self.y_offset < 0:
                self.y_sign = +1
                self.y_offset = 0
        dc.DrawLine(0, int(self.y_offset), self.WIDTH_SCREEN-1, int(self.HEIGHT_SCREEN-self.y_offset-1))
        dc.DrawLine(0, int(self.HEIGHT_SCREEN-self.y_offset-1), self.WIDTH_SCREEN-1, int(self.y_offset))

        dc = wx.PaintDC(self.console)
        #dc.SetPen(wx.Pen('black', wx.DOT))
        dc.SetPen(wx.Pen('black', 1))
        dc.DrawLine(0, self.HEIGHT_CONSOLE - self.png_height,
                    self.WIDTH_CONSOLE-1, self.HEIGHT_CONSOLE - self.png_height)

        for (x, y) in self.led_ac.ticks:
            dc.DrawLine(x, y, x, y+5)
        first = self.led_ac.ticks[0]
        last = self.led_ac.ticks[-1]
        (x1, y1) = first
        (x2, y2) = last
        dc.DrawLine(x1, y2+5, x2, y2+5)

        for (x, y) in self.led_pc.ticks:
            dc.DrawLine(x, y, x, y+5)
        first = self.led_pc.ticks[0]
        last = self.led_pc.ticks[-1]
        (x1, y1) = first
        (x2, y2) = last
        dc.DrawLine(x1, y2+5, x2, y2+5)

        count += 1
        self.led_ac.set_value(count)


# test it ...
app = wx.PySimpleApp() 
frame1 = MyFrame(title='pymlac 0.1') 
frame1.Center() 
frame1.Show() 
app.MainLoop()






# test it ...
app = wx.PySimpleApp() 
frame1 = MyFrame(title='pymlac 0.1') 
frame1.Center() 
frame1.Show() 
app.MainLoop()
