#
# imshow.py : A simple Pygame based command line image viewer.
#
# author:   Deepak Sarda
#           first.last@gmail.com

__author__      = 'Deepak Sarda'
__version__     = '1.0'
__copyright__   = '(c) 2005 Deepak Sarda'
__license__     = 'Public Domain'
__url__         = 'http://www.antrix.net/'

try:
        import sys
        import os
        import fnmatch
        import pygame
        from pygame.locals import *
except ImportError, err:
        print "Couldn't load module. %s" % (err)
        sys.exit(2)


def buildFileList(source, known_types):
    """Returns a list of files of known_types in source.
    If source is a file and it is of known_types, it
    returns a list with the file as member"""
    returnlist = []
    if os.path.isfile(source):
        files = [source]
        base = './'
    if os.path.isdir(source):
        files = os.listdir(source)
        base = source+'/'
    for f in files :
        if os.path.isdir(source + "/" + f) :
            #find_in_dir(root + "/" + f, type)
            #NO RECURSION IN DIRECTORIES FOR NOW
            continue
        else:
            for t in known_types:
                if fnmatch.fnmatch(f, '*.'+t):
                    returnlist.append(base+f)
                    break
#     print returnlist
    return returnlist
#end of buildFilesList

def doBestSize(image):
    global wmMaxSize

    w, h = image.get_size()
    scale = float(w)/h
    flag = 0

    if (w >= wmMaxSize[0][0]):
        w = wmMaxSize[0][0]
        h = int(w//scale)
        flag = 1
    if (h >= wmMaxSize[0][1]):
        h = wmMaxSize[0][1]
        w = int(h*scale)
        flag = 1
    if flag:
        return pygame.transform.scale(image, (w,h))
    else:
        return image
#end of doBestSize()

def showimage(filename):
    """Show specified image on screen"""
    try:
        image = pygame.image.load(filename)
        if image.get_alpha() is None:
            image = image.convert()
        else:
            image = image.convert_alpha()
    except pygame.error, message:
        print 'Cannot load image:', filename
        if pygame.font:
            screen = pygame.display.set_mode((400,200))
            font = pygame.font.Font(None, 24)
            text = font.render("Unable to display: %s" % filename, 1, (255,255,255))
            textpos = text.get_rect()
            screen.blit(text, (20,76))
            pygame.display.set_caption('ImageShow: '+filename)
            pygame.display.flip()
        return
#       raise message

    image = doBestSize(image)
    imagesize = image.get_size()

    pygame.display.set_caption('ImageShow: '+filename+'  '+`imagesize`)
    screen = pygame.display.set_mode(imagesize)
    screen.blit(image, (0,0))
    pygame.display.flip()
#end of showimage()

def nextimage():
    global current, files
    if (current+1) == len(files):
        current = 0
    else:
        current += 1
    showimage(files[current])
#end of nextimage()

def previmage():
    global current, files
    if current == 0:
        current = len(files)-1
    else:
        current -= 1
    showimage(files[current])
#end of previmage

if __name__ == '__main__':
    if (len(sys.argv)<2):
        print """Supply image file or folder on command line as first argument.
                Eg: imshow.py myfile.png
                Eg: imshow.py mydir
                """
        raise SystemExit

    #Initialize stiff
    if not pygame.image.get_extended():
        print 'SDL_Image not present. Cannot show images!'
        raise SystemExit
    if not pygame.font:
        print 'Warning, fonts disabled'

    pygame.display.init()
    pygame.font.init()

    #Check this bit on different platforms.
    #Works on Linux: KDE 3.2
    wmMaxSize = pygame.display.list_modes()
#     print wmMaxSize

    screen = pygame.display.set_mode(wmMaxSize[0])
    pygame.display.set_caption('ImageShow')
    pygame.mouse.set_visible(False)

    image_types = ['jpg', 'jpeg', 'png', 'bmp', 'gif']
    files = buildFileList(sys.argv[1], image_types)
#     print files

    if len(files) == 0:
        print "No Image files found! Exiting"
        raise SystemExit

    showimage(files[0])

    temp = files[0]
    if len(files) == 1:
        files = buildFileList('.', image_types)
        try:
            current = files.index(temp)
        except:
            current = 0
    else:
        current = 0

    pygame.event.set_blocked([MOUSEMOTION, MOUSEBUTTONUP, MOUSEBUTTONDOWN])

    #loop through events until quit
    while 1:
        e = pygame.event.wait()
#         print e
        if e.type == QUIT:
            raise SystemExit
        if e.type == KEYDOWN:
            if e.key in (K_ESCAPE, K_q):
                raise SystemExit
            elif e.key in (K_SPACE, K_PAGEDOWN):
                nextimage()
            elif e.key in (K_BACKSPACE, K_PAGEUP):
                previmage()
        if e.type == VIDEOEXPOSE:
            #pygame.display.flip()
            pass
        pygame.event.pump()

#Unused function
def findInDir(root, known_types) :
    """Looks for files of known_types in root dir
    and returns a list of those files
    """
    files = os.listdir(root)
    returnlist = []
    for f in files :
        if os.path.isdir(root + "/" + f) :
            #find_in_dir(root + "/" + f, type)
            #NO RECURSION IN DIRECTORIES FOR NOW
            continue
        else:
            ext = string.lower(os.path.splitext(f)[1][1:])
            for t in known_types:
                if t == ext :
                    print f
                    returnlist += f
                    break
    return returnlist
#end of findInDir