#!/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/zack/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

#change this to True if you want to search through comparisons and notes
verbose = False

#By default, I'll put the English gloss on the front of every
#flashcard, and the definition on the back. If you'd like it the other
#way around, change this to True.
lojban_on_front = False

#you can customize the output style by modifying these functions
def printGismu(desired_gismu, english_gloss, rafsi_for_this_gismu, definition, annotation):
    print desired_gismu + "\t" + rafsi_for_this_gismu + "\t" + english_gloss + "\n\t" + definition
    if verbose:
        print "\tNotes: " + annotation

def printRafsi(desired_rafsi, associated_gismu, english_gloss):
    print desired_rafsi + "\t" + associated_gismu + "\t" + english_gloss

def printLujvo(desired_lujvo, english_gloss, lujvo_roots):
    print desired_lujvo + "\t" + english_gloss + "\n\t" + lujvo_roots

def printCmavo(desired_cmavo, english_gloss, definition, selmaho, annotation):
    print desired_cmavo + "\t" + selmaho + "\t" + english_gloss + "\n\t" + definition
    if verbose:
        print "\tNotes: " + annotation

#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  ###

#Coming soon:
#-support for more flashcard formats
#-hopefully a GUI
#-a "lujvo dissection" function, to pull apart the various rafsi in a
#lujvo and display their corresponding gismu; requires morphological
#parsing
#-"preferential" scoping: search the gismu first, if there's a perfect
#match, stop there; otherwise continue to the lujvo


import sys, os, re, gzip, copy


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]
    elif sys.argv[i] in ('-v', 'verbose'):
        verbose = True
    else:
        searchterms.append(sys.argv[i])

    i += 1

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

def paukerAdd(paukerdeck, front, back):
    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


    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)



def parseResults(old_searchresults, searchterm, file):
    searchresults = copy.deepcopy(old_searchresults)
    results = []
    for readline in searchresults:
        
        if "9/26/94" in readline:
#Sometimes a search will turn up the first line of the file, which is
#just version information and doesn't contain any vocabulary. Discard
#this result.
                continue

        if cmavo == file:
            keyspots = (readline[0:11], readline[11:20], readline[20:62])

        elif gismu == file:
            keyspots = (readline[1:7], readline[7:10], readline[11:14], readline[15:19], readline[20:41], readline[41:62])

        elif rafsi == file:
            keyspots = (readline[0:5], readline[5:10], readline[12:])

        elif lujvo == file:
            lujvo_roots = readline[31:]
            lujvo_root_end = lujvo_roots.find("x1")
            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 = ""

            gloss_start = readline.find(":")
            gloss_end = readline.rfind(":")
            gloss = readline[gloss_start:gloss_end].strip(":")
            keyspots = [readline[:31]]
            for item in lujvo_roots_list:
                keyspots.append(item)
            keyspots.append(gloss)
            keyspots = tuple(keyspots)
        else:
            print "Error: Don't know how to deal with the vocabulary file."
            exit()
        results.append(keyspots)
    
    results.sort()
    return results


def printOneResult(result, file):
    if gismu == file:
        desired_gismu = result[1:6]
        english_gloss = result[20:62].strip()
        rafsi_for_this_gismu = result[7:19]
        definition = result[62:159].strip()
        annotation = result[159:].strip()
        printGismu(desired_gismu, english_gloss, rafsi_for_this_gismu, definition, annotation)
        if lojban_on_front:
            front = desired_gismu
            back = "\t".join((english_gloss, rafsi_for_this_gismu, definition))
        else:
            front = english_gloss
            back = "\t".join((desired_gismu, rafsi_for_this_gismu, definition))
    if rafsi == file:
        desired_rafsi = result[0:4]
        associated_gismu = result[5:10]
        english_gloss = ""
        printRafsi(desired_rafsi, associated_gismu, english_gloss)
        if lojban_on_front:
            front = desired_rafsi
            back = ""
        else:
            front = english_gloss
            back = ""
    if lujvo == file:
        parsed = parseResults([result], None, file)
        desired_lujvo = parsed[0][0].strip()
        english_gloss = parsed[0][-1].strip()
        lujvo_roots = result[result.rfind(":"):].strip(":").strip()
        printLujvo(desired_lujvo, english_gloss, lujvo_roots)
        if lojban_on_front:
            front = desired_lujvo
            back = english_gloss
        else:
            front = english_gloss
            back = desired_lujvo
    if cmavo == file:
        desired_cmavo = result[0:11].strip()
        english_gloss = result[20:62].strip()
        definition = result[62:168].strip()
        selmaho = result[11:20].strip()
        annotation = result[168:].strip()
        printCmavo(desired_cmavo, english_gloss, definition, selmaho, annotation)
        if lojban_on_front:
            front = desired_cmavo
            back = "\t".join((english_gloss, selmaho, definition))
        else:
            front = english_gloss
            back = "\t".join((desired_cmavo, selmaho, definition))

                        
def printResults(results, file):
    if (results == []) or (results == None):
        print "No results."
        return
    for item in results:
        printOneResult(item, file)
            
            
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 != "":
            if term == "*":
                linematch = True
            else:
                linematch = re.search(term, readline)
            if linematch:
                wordclassresults.append(readline)
            readline = wordfile.readline()
                    
        wordfile.close()
        wordclassresults.sort()
        if wordclass is cmavo:
            print "===cmavo==="
        elif wordclass is gismu:
            print "===gismu==="
        elif wordclass is rafsi:
            print "===rafsi==="
        elif wordclass is lujvo:
            print "===lujvo==="

        wordclassresults_parsed = parseResults(wordclassresults, term, wordclass)

        i = 0
        exactMatch = False
        while i < len(wordclassresults_parsed):
            for keyspot in wordclassresults_parsed[i]:
                if term == keyspot.strip():
                    printOneResult(wordclassresults[i], wordclass)
                    exactMatch = True
            i += 1

        if exactMatch == False:
            printResults(wordclassresults, wordclass)
