##
## window.py -- Display window with associated storage.
##
## Copyleft 1997 Teemu Kalvas <chery@s2.org>
##

## +class Window       (screen,  screen on which to draw
##                      next,    next window initializer
##                      prev,    previous window initializer
##                      name,    name initializer
##                      server)  server initializer
##  -method page_up    ()
##  -method page_down  ()
##  -method set_name   (name)    new window name
##  -method log        (str)     string to log
##  -method redraw     ()
##  -method touch      ()
##  -method next
##  -method prev
##  -method name
##  -method server

import curses

import linelist

def wrap(line, width):
    wrapped = []
    while len(line) >= width:
	wrapped.append(line[:width -1 ] + '\\')
	line = line[width - 1:]
    wrapped.append(line)
    return wrapped

def wlen(line, width):
    return (len(line) + width - 2) / (width - 1)

class Window:
    def __init__(self, screen, next, prev, name, server):
	self.screen = screen
	self.next = next
	self.prev = prev
	self.name = name
	self.server = server
	self.at = 0, 0
	self.visible = 0
	self.lines = linelist.LineList(8)
	self.hold = 0
	self.detect = 0
	self.redraw()

    def page_up(self):
	height, width = self.screen.log_area.getmaxyx()
	i = height - 1
	while i:
	    if self.at[1] > 0:
		self.at = self.at[0], self.at[1] - 1
	    elif self.at[0] > 0:
		self.at = (self.at[0] - 1,
			   wlen(self.lines.lookup(self.at[0] - 1), width) - 1)
	    else:
		break
	    if self.visible < height:
		self.visible = self.visible + 1
	    else:
		self.hold = 1
	    i = i - 1
	self.redraw()

    def page_down(self):
	height, width = self.screen.log_area.getmaxyx()
	i = height - 1
	l = wlen(self.lines.lookup(self.at[0]), width) - self.at[1]
	while i:
	    if self.at[1] < l - 1:
		self.at = self.at[0], self.at[1] + 1
	    elif self.at[0] < self.lines.lines - 1:
		self.at = self.at[0] + 1, 0
		l = wlen(self.lines.lookup(self.at[0]), width)
	    else:
		break
	    i = i - 1
	at = self.at[:]
	self.visible = 1
	while self.visible < height:
	    if at[1] < l - 1:
		at = at[0], at[1] + 1
	    elif at[0] < self.lines.lines - 1:
		at = at[0] + 1, 0
		l = wlen(self.lines.lookup(at[0]), width)
	    else:
		self.hold = 0
		break
	    self.visible = self.visible + 1
	self.redraw()

    def set_name(self, name):
	self.name = name
	self.screen.redraw()

    def log(self, str):
	visible = self == self.screen.current
	window = self.screen.log_area
	height, width = window.getmaxyx()
	wrapped = wrap(str, width)
	self.lines.append(str)
	l = len(wrapped)
	if not self.hold and self.visible + l > height:
	    for i in range(height, self.visible + l):
		if visible:
		    window.scroll()
		if wlen(self.lines.lookup(self.at[0]), width) > self.at[1] + 1:
		    self.at = self.at[0], self.at[1] + 1
		else:
		    self.at = self.at[0] + 1, 0
	    self.visible = height - l
	if visible and self.visible < height:
	    for line in wrapped:
		window.addstr(self.visible, 0, line)
		self.visible = self.visible + 1
		if self.visible == height:
		    break
	    self.touch()
	if not visible:
	    self.visible = min(height, self.visible + l)
	    self.detect = self.detect + 1
	    self.screen.stat_line.redraw()

    def redraw(self):
	window = self.screen.log_area
	height, width = window.getmaxyx()
	window.clear()
	y, k = 0, self.at[0]
	wrapped = wrap(self.lines.lookup(k), width)[self.at[1]:]
	while y < self.visible:
	    for line in wrapped:
		window.addstr(y, 0, line)
		y = y + 1
		if y >= self.visible:
		    self.touch()
		    return
	    k = k + 1
	    wrapped = wrap(self.lines.lookup(k), width)
	self.touch() ## shouldn't get here in any case

    def touch(self):
	screen = self.screen
	screen.touched = screen.touched | 1

## End. ##
