#!/usr/bin/python

###lojval was created by Zachary Spector, aka lojbaj
###
###I hereby release this code into the public domain.  In case this is
###not possible, I authorize anyone to use this code for any purpose.
###
###However, I humbly request that you keep my name on it.

###  begin configuration  ###

#change these to the proper locations of your vocabulary files
cmavo = "/usr/share/lojban/cmavo.txt"
gismu = "/usr/share/lojban/gismu.txt"
rafsi = "/usr/share/lojban/rafsi.txt"
lujvo = "/usr/share/lojban/NORALUJV.txt"
#and change this to the location of your Pauker flashcard deck
paukerdeck = "/home/sanotehu/Documents/Pauker/lojban.general.pau.gz"

#change this to True if you'd prefer for every successful, unique
#match to be added to your flashcard deck
pauker = False

#Note that lojval makes certain assumptions about how the vocabulary
#files are formatted. If you have different versions of said files,
#strange behavior may result. This version of lojval is known to work
#with:
#-LogFlash cmavo list 26 August 2002
#-gismu list 9/26/94
#-the list of rafsi from the package "lojban-common" version 1.4-1 from the
#Ubuntu Gutsy Universe repository
#-the version of NORALUJV.txt from the same package

###  end configuration  ###

import sys, os, re, gzip


i = 1
scope = []
searchterms = []
while i < len(sys.argv):
    if sys.argv[i] in ('-cmavo', '-c') and not (cmavo in scope):
        scope.append(cmavo)
    elif sys.argv[i] in ('-gismu', '-g') and not (gismu in scope):
        scope.append(gismu)
    elif sys.argv[i] in ('-rafsi', '-r') and not (rafsi in scope):
        scope.append(rafsi)
    elif sys.argv[i] in ('-lujvo', '-l') and not (lujvo in scope):
        scope.append(lujvo)
    elif sys.argv[i] in ('-pauker', '-p') and not pauker:
        pauker = True
    elif sys.argv[i] in ('-nopauker', '-np') and pauker:
        pauker = False
    elif sys.argv[i][:8] == '-pauker=':
        pauker = True
        paukerdeck = sys.argv[i][8:]
    elif sys.argv[i][:3] == '-p=':
        pauker = True
        paukerdeck = sys.argv[i][3:]
    elif sys.argv[i] in ('-all', '-a', '-rovalsi', '-ro'):
        scope = [cmavo, rafsi, gismu, lujvo]
    else:
        searchterms.append(sys.argv[i])

    i += 1

if scope == []: scope = [gismu]


def parseAndPrint(searchresults, searchterm):
    if len(searchresults) == 0: return
    results = []

    while len(searchresults) > 0:
        readline = searchresults.pop()

        #keyspots are those places in readline where I might find an exact
        #match.  The keyspots are presented out of order, so that
        #keyspot[0] is always the English gloss. 
        if cmavo in readline:

            readline = readline[len(cmavo):] #strip out the filename, we
                                               #don't need it anymore
            keyspots = (readline[20:62].strip(), readline[0:11].strip(), readline[11:20].strip())
            prettyline = readline[:62].strip() + "\n" + readline[62:].strip()
        elif gismu in readline:

            readline = readline[len(gismu):]
            keyspots = (readline[20:41].strip(), readline[1:6], readline[7:10], readline[11:14], readline[15:19], readline[41:62].strip())
            prettyline = readline[:62].strip() + "\n" + readline[62:159].strip()
        elif rafsi in readline:

            readline = readline[len(rafsi):]
            keyspots = (readline[12:].strip(), readline[0:5].strip(), readline[5:10])
            prettyline = readline.strip()
        elif lujvo in readline:

            readline = readline[len(lujvo):]

            lujvo_roots = readline[31:]
            lujvo_root_end = lujvo_roots.find(":")
            lujvo_roots = lujvo_roots[:lujvo_root_end]
            lujvo_roots_list = []
            this_lujvo_root = ""
            for char in lujvo_roots:
                if char.isalpha():
                    this_lujvo_root += char
                else:
                    lujvo_roots_list.append(this_lujvo_root)
                    this_lujvo_root = ""

            definition = readline[45:]
            gloss_end = definition.find(":")
            gloss = definition[:gloss_end]
            gloss = gloss.strip()
            keyspots = (gloss, readline[:31].strip()) + tuple(lujvo_roots_list)
            prettyline = readline[:31].strip() + "\n" + readline[31:].strip()
        else:
            print "Error: Don't know how to deal with the vocabulary file."
            exit()


        if searchterm in keyspots:
            print "\t" + prettyline

            if pauker:
                try:
                    lojbancards = gzip.open(paukerdeck).read()
                    used_gzip = True
                except (IOError):
                    try:
                        lojbancards = open(paukerdeck).read()
                        used_gzip = False
                    except:
                        print "\nI couldn't find a flashcard file there; creating one now."
                        gzip.open(paukerdeck, "wb").write("""<!--
    This is a lesson file for Pauker (http://pauker.sourceforge.net)
    -->
    <Lesson LessonFormat="1.7">
    <Description/>
    <Batch>
    </Batch>
    </Lesson>""")
                        lojbancards = gzip.open(paukerdeck, "r").read()
                        used_gzip = True

                front = keyspots[0]
                back = prettyline

                if back in lojbancards:
                    print "\nThat card is already in your flashcard deck."
                    return

                addcard = """\n    <Card>
      <FrontSide Orientation="LTR" RepeatByTyping="false">
        <Text>%s</Text>
        <Font Background="-1" Bold="false" Family="Dialog" Foreground="-16777216" Italic="false" Size="12"/>
      </FrontSide>
      <ReverseSide Orientation="LTR" RepeatByTyping="false">
        <Text>%s</Text>
        <Font Background="-1" Bold="false" Family="Dialog" Foreground="-16777216" Italic="false" Size="12"/>
      </ReverseSide>
    </Card>""" % (front, back)

                cardstart = re.search("<Batch>", lojbancards)
                if cardstart is None:
                    print "The flashcard file is malformed. I can't work with it."
                    return
                cardstart = cardstart.end()

                print "\nNow adding this definition to the flashcard deck."

                lojbancards = lojbancards[:cardstart] + addcard + lojbancards[cardstart:]

                os.remove(paukerdeck)

                if used_gzip:
                    gzip.open(paukerdeck, "wb").write(lojbancards)
                else:
                    open(paukerdeck, "wb").write(lojbancards)

            return

        else:
            results.append(prettyline)



    for item in results:
        print "\t" + item
    if pauker:
            print "Since there was more than one match for %s, " + \
                "I won't add anything to the flashcard deck." % searchterm

allsearchresults = []
for term in searchterms:

    if len(searchterms) > 1:
        print '\nResults for "%s":' % term

    for wordclass in scope:
        wordfile = open(wordclass, "r")
        readline = wordfile.readline()
        wordclassresults = []

        while readline != "":
            linematch = re.search(term, readline.lower())
            if linematch:
                wordclassresults.append(wordclass + readline)
            readline = wordfile.readline()

        wordfile.close()

        if wordclass is cmavo:
            print "===cmavo==="
        elif wordclass is gismu:
            print "===gismu==="
        elif wordclass is rafsi:
            print "===rafsi==="
        elif wordclass is lujvo:
            print "===lujvo==="

        if len(wordclassresults) == 0:
            print "No results."

        parseAndPrint(wordclassresults, term)
