##
## clirc -- An IRC client in Python.
## curseseditline.py - Curses single line editor.
##
## Copyleft 1997-2000 Teemu Kalvas <chery@s2.org>
##

import linelist
import reloadable

import main

class CursesEditline(reloadable.Reloadable):
    def __init__(self, screen):
        self.screen = screen
        self.prompt = '> '
        self.history = linelist.LineList(8)
        self.history_pos = 0
        self.reset()

    def reset(self, *rest):
        self.string = ''
        self.offset = -len(self.prompt)
        self.position = 0
        self.redraw()

    def insert(self, str):
        width = self.screen.width
        self.string = self.string[:self.position] + str \
                      + self.string[self.position:]
	self.position = self.position + len(str)
        if self.position < self.offset + width:
            window = self.window()
	    x = self.position - self.offset - len(str)
	    for ch in str:
		window.insch(0, x, ord(ch))
		x = x + 1
            self.changed()
        else:
            self.redraw()

    def set_string(self, str):
        self.string = str
        self.position = len(str)
        self.offset = -len(self.prompt)
        self.redraw()

    def accept(self, event):
        self.history.append(self.string)
        self.history_pos = self.history.lines
        event.accept(self.string)
        self.reset()

    def refresh(self, event):
        self.screen.refresh()

    def del_char_left(self, event):
        if self.position:
            self.position = self.position - 1
            self.string = self.string[:self.position] \
                          + self.string[self.position + 1:]
            self.redraw()

    def del_char_right(self, event):
        if self.position < len(self.string):
            self.string = self.string[:self.position] \
                          + self.string[self.position + 1:]
            self.redraw()

    def line_beg(self, event):
        self.position = 0
        self.offset = -len(self.prompt)
        self.reposition()

    def line_end(self, event):
        self.position = len(self.string)
        self.reposition()

    def char_left(self, event):
        if self.position:
            self.position = self.position - 1
            self.reposition()

    def char_right(self, event):
        if self.position < len(self.string):
            self.position = self.position + 1
            self.reposition()

    def del_line_end(self, event):
        self.string = self.string[:self.position]
        self.redraw()

    def history_prev(self, event):
        if self.history_pos:
            self.history_pos = self.history_pos - 1
            self.string = self.history.lookup(self.history_pos)
            self.position = len(self.string)
            self.offset = 0
            self.redraw()

    def history_next(self, event):
        if self.history_pos < self.history.lines - 1:
            self.history_pos = self.history_pos + 1
            self.string = self.history.lookup(self.history_pos)
        else:
            self.string = ''
        self.position = len(self.string)
        self.offset = 0
        self.redraw()

    def transpose_char(self, event):
        str = self.string
        pos = self.position
        if pos == len(str):
            self.string = str[:pos - 2] + str[pos - 1] + str[pos - 2]
        else:
            self.string = str[:pos - 1] + str[pos] + str[pos - 1] \
                          + str[pos + 1:]
            self.position = pos + 1
        self.redraw()

    def window(self):
        return self.screen.get_window(self)

    def changed(self):
        self.screen.window_changed(self)
        self.cursor_changed()

    def cursor_changed(self):
        self.screen.cursor_changed(self, self.position - self.offset)

    def reposition(self):
	self.cursor_changed()
	width = self.screen.width
        if self.position <= self.offset + 2 or \
           self.position >= self.offset + width - 2:
            self.redraw()

    def redraw(self):
        self.screen.redraw_window(self)

    def redraw_event(self):
        window = self.window()
        width = self.screen.width
        if self.position <= self.offset + 2 or \
           self.position >= self.offset + width - 2:
            self.offset = max(-len(self.prompt), self.position - width / 2)
        str = self.prompt + self.string
        off = self.offset + len(self.prompt)
        if len(str) - off >= width:
            window.addstr(0, 0, str[off:off + width - 1])
        else:
            window.addstr(0, 0, str[off:])
            window.clrtoeol()
        self.changed()

reloadable.register_for_reload(CursesEditline)

## End. ##
