#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2006, A. Murat Eren (meren at uludag.org.tr)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# v0.1, 03 Feb 2006..
 
import os
import sys
import codecs


wikiAddr = "http://www.pardus-wiki.org/index.php"


lyxStandardTemplate = "\n\n\\layout Standard\n%s"
lyxItemizeTemplate = "\n\\layout Itemize\n%s\n"
lyxEnumeratedTemplate = "\n\\layout Enumerate\n%s"
lyxCodeBlockTemlpate = "\n\\layout LyX-Code\n%s"
lyxLinkTemplate = '\\begin_inset LatexCommand \\url!#!%s#!#{%s}\n\\end_inset\n'
lyxBoldTemplate = '\n\\series bold\n%s\n\\series default\n'
lyxItalicTemplate = '\n\\emph on\n%s\n\\emph default\n'
lyxDepthStart, lyxDepthEnd = "\n\\begin_deeper\n", "\n\\end_deeper\n"
lyxHeaderTemplates = ["\n"*4 + "\\layout Section\n%s",
                      "\n"*4 + "\\layout Subsection\n%s", 
                      "\n"*4 + "\\layout Subsubsection\n%s", 
                      "\n"*4 + "\\layout Subsubsubsection\n%s"]
lyxBegin = """#LyX 1.3 created this file. For more info see http://www.lyx.org/
\\lyxformat 221
\\textclass article
\\language turkish
\\inputencoding auto
\\fontscheme default
\\graphics default
\\paperfontsize default
\\spacing single
\\papersize Default
\\paperpackage a4
\\use_geometry 0
\\use_amsmath 0
\\use_natbib 0
\\use_numerical_citations 0
\\paperorientation portrait
\\secnumdepth 3
\\tocdepth 3
\\paragraph_separation skip
\\defskip medskip
\\quotes_language english
\\quotes_times 2
\\papercolumns 1
\\papersides 1
\\paperpagestyle default

"""
lyxEnd = "\\the_end"

escapeDict = {'[': '!#!', ']': '#!#'}


def disassemble(line, opener, closer):

    P, L = lambda x, y = 0: line.find(x, y), lambda x: len(x)
    
    if P(opener) > -1:
        R = P(closer, P(opener) + L(opener) + 1)
        while 1:
            if line[R:R + L(closer)] != closer: break
            else: 
                R = R + 1
        return line[:P(opener)], line[P(opener) + L(opener):R - 1], line[R + L(closer) - 1:]
    return (None, None, line)


# Converterz

def convertLink((pre, link, rest)):
    if link:
        linkAddress, linkName = link.split()[0], ' '.join(link.split()[1:])
        rest = convertLink(disassemble(pre + lyxLinkTemplate % (linkName, linkAddress) + rest, '[', ']'))
    return rest

def convertWikiLink((pre, link, rest)):
    if link:
        if link.find('|') > -1:
            linkName = link.split('|')[1]
            linkAddress = wikiAddr + '/' + link.split('|')[0]
        else:
            linkName = link
            linkAddress = wikiAddr + '/' + linkName
        rest = convertLink(disassemble(pre + lyxLinkTemplate % (linkName, linkAddress) + rest, '[[', ']]'))
    return rest

def convertBold((pre, bold, rest)):
    if bold:
        rest = convertBold(disassemble(pre + lyxBoldTemplate % (bold) + rest, "'''", "'''"))
    return rest

def convertItalic((pre, italic, rest)):
    if italic:
        rest = convertItalic(disassemble(pre + lyxItalicTemplate % (italic) + rest, "''", "''"))
    return rest

def convertTemplate((pre, template, rest)):
    #TODO: find a clever way to convert special wiki templates into lyx..
    if template:
        return pre + '{{' + template + '}}' + rest
    return rest


# Wiki Component Prosesırs.

def processHeader(line):
    signs = ["====", "===", "==", "="]
    for level in range(0, len(signs)):
        if line[0:len(signs[level])] == signs[level]:
            headerLevel = 4 - level
            break

    headerText = line[headerLevel:line.rfind(headerLevel * '=')].strip()
    return lyxHeaderTemplates[headerLevel - 1] % (headerText)

def processNewLine(line):
    pass

def processList(line):
    return lyxItemizeTemplate % (line[line.find([x for x in line if x is not '*' if x is not ' '][0]):])

def processIndent(line):
    depth = line.find([x for x in line if x is not ':'][0])
    if line[depth] == '*': line = line[:depth] + processList(line[depth:])
    elif line[depth] == '#': line = line[:depth] + processEnumerated(line[depth:])
    return lyxDepthStart * depth + line[depth:] + lyxDepthEnd * depth

def processEnumerated(line):
    return lyxEnumeratedTemplate % (line[line.find([x for x in line if x is not '#' if x is not ' '][0]):])

def processCodeBlock(line):
    return lyxCodeBlockTemlpate % (line)

def processRegularText(line):
    line = convertWikiLink(disassemble(line, '[[', ']]'))
    line = convertLink(disassemble(line, '[', ']'))
    line = convertBold(disassemble(line, "'''", "'''"))
    line = convertItalic(disassemble(line, "''", "''"))
    line = convertTemplate(disassemble(line, "{{", "}}"))

    for item in escapeDict.items(): line = line.replace(item[1], item[0])      

    if line:
        if not line.startswith('\\layout') and line.find('deeper') == -1:
            return  lyxStandardTemplate % (line)
        else:
            return line


##


def getContent(filePath):
    #TODO: need to be abstracted..
    if os.path.isfile(filePath):
        return open(filePath).readlines()
    else:
        print "Missing file: ", filePath
        sys.exit(1)

def storeContent(filePath, content):
    open(filePath, 'a').write(codecs.encode(content, "iso-8859-9"))

def parse(fileContent):

    wikiPreProcessors = {
        '\n': processNewLine,
        '=' : processHeader,
        '*' : processList,
        '#' : processEnumerated,
        ':' : processIndent
        }

    pre = None
    
    for line in fileContent:
    
        if line.startswith('<pre>') : pre = 1; continue 
        if line.startswith('</pre>'): pre = None; continue
        if pre:
            line = processCodeBlock(line)
            
        else:
            for key in wikiPreProcessors.iterkeys():
                if len(line) > len(key) and line[len(key) - 1] == key:
                    line = wikiPreProcessors.get(line[0])(line) or line
            line = processRegularText(line.strip())
        if line:
            yield line



if __name__ == "__main__":
    if len(sys.argv) > 1:
        for f in sys.argv[1:]:
            storeContent(f + '.lyx', lyxBegin)
            for line in parse(getContent(f)):
                storeContent(f + '.lyx', line)
            storeContent(f + '.lyx', lyxEnd)
    sys.exit(0)


