"""Make system cursors from Images
Creates pygame cursors from a graphic file. This function allows you
to draw your custom cursors in an image-editing program, and keep them
all in a single file.

Your image file must be a multiple of 32x32 in size, and must use
certain colors: Black (0,0,0) and White (255,255,255) are treated
normally, Red (255, 0, 0) and Magenta (255, 0, 255) are used to
specify the hotspot, and any other color (green in the example) is
transparent.

Author website, http://nedbatchelder.com
"""
__author__ = "Ned Batchelder"
__copyright__ = "Copyright (c) 2001 Ned Batchelder"
__license__ = "Public Domain"
__version__ = "1.0"

import pygame

def MakeCursors(filename, names):
    """
    MakeCursors(filename, names):
    Read the image at filename, creating 32x32 cursors.  Return a dictionary
    of cursors, assigned to the names in names.
    Colors in the image:
    black and white are black and white.
    Red and magenta are the hotspot (colored black or white, respectively).
    Any other color is transparent.
    """

    # Load the raw tile image
    try:
        tiles = pygame.image.load(filename)
    except pygame.error:
        raise pygame.error, 'Could not load image "%s" %s' % (filename, pygame.get_error())

    tileWidth = 32
    tileHeight = 32
    tileSize = (tileWidth, tileHeight)

    curs = {}

    tiles.lock()

    # Split it into individual tiles
    for ycur in range(tiles.get_height() / tileHeight):
        for xcur in range(tiles.get_width() / tileWidth):
            tileX = xcur * tileWidth
            tileY = ycur * tileHeight

            strings = []
            hot = (0,0)

            if len(names) > 0 and names[0] != '':
                for y in range(tileY, tileY + tileHeight):
                    l = ''
                    for x in range(tileX, tileX + tileWidth):
                        clr = tiles.get_at((x, y))[:3]
                        # not sure why, but the colors are impure.  Force them to black, white, or green
                        pclr = map(lambda x: x > 100, clr)
                        if pclr == [0,0,0]:
                            l += 'X'
                        elif pclr == [1,1,1]:
                            l += '.'
                        elif pclr == [1,0,0]:
                            l += 'X'
                            hot = (x - tileX, y - tileY)
                        elif pclr == [1,0,1]:
                            l += '.'
                            hot = (x - tileX, y - tileY)
                        else:
                            l += ' '
                    strings.append(l)

                data = pygame.cursors.compile(strings, ".", "X")
                curs[names[0]] = ( (tileWidth, tileHeight), hot) + data

            names = names[1:]

    tiles.unlock()

    return curs


if __name__ == '__main__':
    pygame.init()
    print MakeCursors('cursors.gif', ('arrow', 'forward', 'left', 'right'))
