import curses
import sys
import random
import time

from os import listdir
from os.path import isfile, join

class FileListing:
    DOWN = 1
    UP = -1
    SPACE_KEY = 32
    ESC_KEY = 27

    PREFIX_SELECTED = '[X]'
    PREFIX_DESELECTED = '[_]'

    outputLines = []
    screen = None

    mypath = "."

    def __init__(self):
        self.screen = curses.initscr()
        curses.noecho()
        curses.cbreak()
        self.screen.keypad(1)
        self.screen.border(0)
        self.topLineNum = 0
        self.highlightLineNum = 0
        self.markedLineNums = []
        self.getOutputLines()
        (self.maxY, self.maxX) = self.screen.getmaxyx()

    def run(self):
        c = ""
        while c not in [ord("q"), self.ESC_KEY]:
            self.displayScreen()
            c = self.screen.getch()
            if c == curses.KEY_UP:
                self.updown(self.UP)
            elif c == curses.KEY_DOWN:
                self.updown(self.DOWN)
            elif c == self.SPACE_KEY:
                self.markLine()

        return [self.mypath+self.outputLines[i] for i in self.markedLineNums]

    def markLine(self):
        linenum = self.topLineNum + self.highlightLineNum
        if linenum in self.markedLineNums:
            self.markedLineNums.remove(linenum)
        else:
            self.markedLineNums.append(linenum)

    def getOutputLines(self):
        self.outputLines = [ f for f in listdir(self.mypath) if isfile(join(self.mypath,f)) ]
        self.nOutputLines = len(self.outputLines)

    def displayScreen(self):
        # clear screen
        self.screen.clear()
        self.screen.border(0)

        # now paint the rows
        top = self.topLineNum
        bottom = self.topLineNum+curses.LINES
        for (index,line,) in enumerate(self.outputLines[top:bottom]):
            linenum = self.topLineNum + index
            if linenum in self.markedLineNums:
                prefix = self.PREFIX_SELECTED
            else:
                prefix = self.PREFIX_DESELECTED

            line = '%s %s' % (prefix, line,)

            # highlight current line
            if index != self.highlightLineNum:
                self.screen.addstr(index+2, 4, line)
            else:
                self.screen.addstr(index+2, 4, line, curses.A_BOLD)

        # Affichage bas de la fenetre
        for u in range(self.maxX):
            if u == 0:
                self.screen.addch(self.maxY - 3, u, curses.ACS_LTEE)
            elif u == self.maxX - 1:
                self.screen.addch(self.maxY - 3, u, curses.ACS_RTEE)
            else:
                self.screen.addch(self.maxY - 3, u, curses.ACS_HLINE)
        self.screen.addstr(self.maxY - 2, 1, '(Esc|q) - Back')

        self.screen.refresh()

    # move highlight up/down one line
    def updown(self, increment):
        nextLineNum = self.highlightLineNum + increment

        # paging
        if increment == self.UP and self.highlightLineNum == 0 and self.topLineNum != 0:
            self.topLineNum += self.UP
            return
        elif increment == self.DOWN and nextLineNum == curses.LINES and (self.topLineNum+curses.LINES) != self.nOutputLines:
            self.topLineNum += self.DOWN
            return

        # scroll highlight line
        if increment == self.UP and (self.topLineNum != 0 or self.highlightLineNum != 0):
            self.highlightLineNum = nextLineNum
        elif increment == self.DOWN and (self.topLineNum+self.highlightLineNum+1) != self.nOutputLines and self.highlightLineNum != curses.LINES:
            self.highlightLineNum = nextLineNum
