--[[
  Preliminary ConTeXT lexer

  % ConTeXt
  tex context
  mkii context
  mkiv context

  experiment dd 2009/10/28 .. todo:

  -- figure out if tabs instead of splits are possible
  -- locate an option to enter name in file dialogue (like windows permits)
  -- nesting of lua somehow does not re-lex while typing (backtrack till begin_...)
  -- find trick to overload latex lexer (mime_types, metatype trickery)
  -- convert scite lua scripts to textadept
  -- check linux and osx versions
  -- figure out why loading a file fails (lfs too)

  so, this is just an experiment

]]--

local textadept = _G.textadept

module(..., package.seeall)

local context = context
local lua     = require 'lua'

local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V

--~ local some_words = { "starttext", "stoptext", "writestatus" }

local some_words = {
 "CAP",
 "Cap",
 "Caps",
 "Character",
 "Characters",
 "MONTH",
 "Romannumerals",
 "WEEKDAY",
 "WORD",
 "WORDS",
 "Word",
 "Words",
 "about",
 "adaptlayout",
 "adding",
 "appendix",
 "arg",
 "at",
 "atpage",
 "background",
 "blackrule",
 "blackrules",
 "blank",
 "bookmark",
 "but",
 "button",
 "bypassblocks",
 "cap",
 "chapter",
 "character",
 "characters",
 "chem",
 "clip",
 "clonefield",
 "color",
 "column",
 "comment",
 "comparecolorgroup",
 "comparepalet",
 "completecombinedlist",
 "completelistoffloats",
 "completelistofsorts",
 "completelistofsynonyms",
 "completeregister",
 "convertnumber",
 "copyfield",
 "correctwhitespace",
 "coupledocument",
 "coupledregister",
 "couplemarking",
 "couplepage",
 "couplepaper",
 "coupleregister",
 "crlf",
 "currentdate",
 "currentheadnumber",
 "date",
 "decouplemarking",
 "define",
 "defineblank",
 "defineblock",
 "definebodyfont",
 "definebodyfontenvironment",
 "definebuffer",
 "definecolor",
 "definecolorgroup",
 "definecombinedlist",
 "defineconversion",
 "definedescription",
 "defineenumeration",
 "definefield",
 "definefieldstack",
 "definefiguresymbol",
 "definefloat",
 "definefont",
 "defineframed",
 "defineframedtext",
 "definehead",
 "defineindenting",
 "defineinteractionmenu",
 "defineinteractionmenu",
 "definelabel",
 "definelist",
 "definelogo",
 "definemakeup",
 "definemarking",
 "defineoutput",
 "defineoverlay",
 "definepalet",
 "definepapersize",
 "defineparagraphs",
 "defineprofile",
 "defineprogram",
 "definerawfont",
 "definereference",
 "definereferenceformat",
 "definereferencelist",
 "defineregister",
 "definerule",
 "definesection",
 "definesectionblock",
 "definesorting",
 "definestartstop",
 "definesubfield",
 "definesymbol",
 "definesynonyms",
 "definetabletemplate",
 "definetabulate",
 "definetext",
 "definetextposition",
 "definetextvariable",
 "definetype",
 "definetyping",
 "defineversion",
 "description",
 "determineheadnumber",
 "determinelistcharacteristics",
 "disableinteractionmenu",
 "donttest",
 "emptylines",
 "enumeration",
 "externalfigure",
 "field",
 "fieldstack",
 "fillinfield",
 "fillinline",
 "fillinrules",
 "fillintext",
 "fitfield",
 "fixedspaces",
 "followprofile",
 "followprofileversion",
 "followversion",
 "footnote",
 "footnotetext",
 "forceblocks",
 "fraction",
 "framed",
 "framedtext",
 "from",
 "getbuffer",
 "getmarking",
 "godown",
 "goto",
 "gotobox",
 "graycolor",
 "grid",
 "hairline",
 "head",
 "headnumber",
 "headtext",
 "hideblocks",
 "high",
 "hl",
 "in",
 "indentation",
 "indenting",
 "inframed",
 "ininner",
 "inleft",
 "inline",
 "inmargin",
 "inothermargin",
 "inouter",
 "inright",
 "installlanguage",
 "interactionbar",
 "interactionbuttons",
 "item",
 "items",
 "its",
 "keepblocks",
 "labeling",
 "labels",
 "labeltext",
 "language",
 "leftaligned",
 "listsymbol",
 "loadsorts",
 "loadsynonyms",
 "logfields",
 "lohi",
 "low",
 "mainlanguage",
 "mar",
 "marginrule",
 "margintext",
 "marking",
 "markversion",
 "mathematics",
 "mediaeval",
 "midaligned",
 "mirror",
 "month",
 "moveongrid",
 "name",
 "nextsection",
 "nocap",
 "noheaderandfooterlines",
 "noindenting",
 "nolist",
 "nomarking",
 "nomoreblocks",
 "nomorefiles",
 "nop",
 "nospace",
 "note",
 "notopandbottomlines",
 "nowhitespace",
 "numbers",
 "overbar",
 "overbars",
 "overstrike",
 "overstrikes",
 "packed",
 "page",
 "pagereference",
 "pagetype",
 "paragraph",
 "part",
 "periods",
 "placebookmarks",
 "placecombinedlist",
 "placecombinedlist",
 "placefloat",
 "placefootnotes",
 "placeformula",
 "placelegend",
 "placelist",
 "placelistoffloats",
 "placelistofsorts",
 "placelistofsynonyms",
 "placelocalfootnotes",
 "placelogos",
 "placeongrid",
 "placeontopofeachother",
 "placereferencelist",
 "placeregister",
 "placeregister",
 "placerule",
 "placesidebyside",
 "placesubformula",
 "placetextvariable",
 "position",
 "positiontext",
 "processblocks",
 "processpage",
 "program",
 "publication",
 "quotation",
 "quote",
 "ran",
 "ref",
 "reference",
 "referral",
 "referraldate",
 "register",
 "reservefloat",
 "reset",
 "resetmarking",
 "resettextcontent",
 "rightaligned",
 "romannumerals",
 "rotate",
 "scale",
 "screen",
 "section",
 "seeregister",
 "selectblocks",
 "selectpaper",
 "selectversion",
 "settextcontent",
 "settextvariable",
 "setupalign",
 "setuparranging",
 "setupbackground",
 "setupbackgrounds",
 "setupblackrules",
 "setupblank",
 "setupblock",
 "setupbodyfont",
 "setupbodyfontenvironment",
 "setupbottom",
 "setupbottomtexts",
 "setupbuffer",
 "setupbuttons",
 "setupcapitals",
 "setupcaption",
 "setupcaptions",
 "setupclipping",
 "setupcolor",
 "setupcolors",
 "setupcolumns",
 "setupcombinations",
 "setupcombinedlist",
 "setupcomment",
 "setupdescriptions",
 "setupenumerations",
 "setupexternalfigures",
 "setupfield",
 "setupfields",
 "setupfillinlines",
 "setupfillinrules",
 "setupfloat",
 "setupfloats",
 "setupfloatsplitting",
 "setupfooter",
 "setupfootertexts",
 "setupfootnotedefinition",
 "setupfootnotes",
 "setupforms",
 "setupformulae",
 "setupframed",
 "setupframedtexts",
 "setuphead",
 "setupheader",
 "setupheadertexts",
 "setupheadnumber",
 "setupheads",
 "setupheadtext",
 "setuphyphenmark",
 "setupindentations",
 "setupindenting",
 "setupinmargin",
 "setupinteraction",
 "setupinteractionbar",
 "setupinteractionscreen",
 "setupinterlinespace",
 "setupinterlinespace",
 "setupitemgroup",
 "setupitems",
 "setuplabeltext",
 "setuplanguage",
 "setuplayout",
 "setuplegend",
 "setuplinenumbering",
 "setuplines",
 "setuplinewidth",
 "setuplist",
 "setuplistalternative",
 "setupmakeup",
 "setupmarginblocks",
 "setupmarginrules",
 "setupmarking",
 "setupnarrower",
 "setupnumbering",
 "setupoppositeplacing",
 "setupoutput",
 "setuppagenumber",
 "setuppagenumbering",
 "setuppagetransitions",
 "setuppalet",
 "setuppaper",
 "setuppapersize",
 "setupparagraphnumbering",
 "setupparagraphs",
 "setuppositioning",
 "setupprofiles",
 "setupprograms",
 "setuppublications",
 "setupquote",
 "setupreferencelist",
 "setupreferencing",
 "setupregister",
 "setuprotate",
 "setuprule",
 "setupscreens",
 "setupsection",
 "setupsectionblock",
 "setupsorting",
 "setupspacing",
 "setupstrut",
 "setupsubpagenumber",
 "setupsymbolset",
 "setupsynchronization",
 "setupsynchronizationbar",
 "setupsynonyms",
 "setupsystem",
 "setuptab",
 "setuptables",
 "setuptabulate",
 "setuptext",
 "setuptextposition",
 "setuptextrules",
 "setuptexttexts",
 "setuptextvariable",
 "setupthinrules",
 "setuptolerance",
 "setuptop",
 "setuptoptexts",
 "setuptype",
 "setuptyping",
 "setupunderbar",
 "setupurl",
 "setupversions",
 "setupwhitespace",
 "showbodyfont",
 "showbodyfontenvironment",
 "showcolor",
 "showcolorgroup",
 "showexternalfigures",
 "showfields",
 "showframe",
 "showgrid",
 "showlayout",
 "showmakeup",
 "showpalet",
 "showprint",
 "showsetups",
 "showstruts",
 "showsymbolset",
 "someline",
 "somewhere",
 "sort",
 "space",
 "splitfloat",
 "startalignment",
 "startbackground",
 "startbuffer",
 "startcolor",
 "startcolumns",
 "startcombination",
 "startcomment",
 "startcomponent",
 "startdescription",
 "startdocument",
 "startenumeration",
 "startenvironment",
 "startfact",
 "startfigure",
 "startfloattext",
 "startformula",
 "startframedtext",
 "starthiding",
 "startinteractionmenu",
 "startitemgroup",
 "startlegend",
 "startline",
 "startlinecorrection",
 "startlinenumbering",
 "startlines",
 "startlocal",
 "startlocalenvironment",
 "startlocalfootnotes",
 "startmakeup",
 "startmarginblock",
 "startmarginrule",
 "startnamemakeup",
 "startnarrower",
 "startopposite",
 "startoverlay",
 "startoverview",
 "startpacked",
 "startparagraph",
 "startpositioning",
 "startpostponing",
 "startproduct",
 "startprofile",
 "startproject",
 "startquotation",
 "startregister",
 "startsymbolset",
 "startsynchronization",
 "starttable",
 "starttables",
 "starttabulate",
 "starttextrule",
 "starttyping",
 "startunpacked",
 "startversion",
 "stopalignment",
 "stopbackground",
 "stopbuffer",
 "stopcolor",
 "stopcolumns",
 "stopcombination",
 "stopcomment",
 "stopcomponent",
 "stopdescription",
 "stopdocument",
 "stopenumeration",
 "stopenvironment",
 "stopfact",
 "stopfigure",
 "stopfloattext",
 "stopformula",
 "stopframedtext",
 "stophiding",
 "stopinteractionmenu",
 "stopitemgroup",
 "stoplegend",
 "stopline",
 "stoplinecorrection",
 "stoplinenumbering",
 "stoplines",
 "stoplocal",
 "stoplocalenvironment",
 "stoplocalfootnotes",
 "stopmakeup",
 "stopmarginblock",
 "stopmarginrule",
 "stopnamemakeup",
 "stopnarrower",
 "stopopposite",
 "stopoverlay",
 "stopoverview",
 "stoppacked",
 "stopparagraph",
 "stoppositioning",
 "stoppostponing",
 "stopproduct",
 "stopprofile",
 "stopproject",
 "stopquotation",
 "stopsymbolset",
 "stopsynchronization",
 "stoptable",
 "stoptables",
 "stoptabulate",
 "stoptextrule",
 "stoptyping",
 "stopunpacked",
 "stopversion",
 "stretched",
 "sub",
 "subject",
 "subsection",
 "subsubject",
 "subsubsection",
 "subsubsubject",
 "switchtobodyfont",
 "switchtorawfont",
 "sym",
 "symbol",
 "synchronizationbar",
 "synchronize",
 "synonym",
 "tab",
 "tex",
 "textreference",
 "textrule",
 "textvariable",
 "thinrule",
 "thinrules",
 "title",
 "tooltip",
 "translate",
 "typ",
 "type",
 "typebuffer",
 "typefile",
 "underbar",
 "underbars",
 "useURL",
 "useblocks",
 "usecommands",
 "usedirectory",
 "useencoding",
 "useexternaldocument",
 "useexternalfigure",
 "useexternalfile",
 "useexternalfiles",
 "useexternalsoundtrack",
 "usemodule",
 "usereferences",
 "usespecials",
 "usesymbols",
 "version",
 "vl",
 "weekday",
 "whitespace",
 "wordright",
 "writebetweenlist",
 "writetolist",
 "writetoreferencelist",
 "writetoregister",
}

local tex_word_match = word_match(word_list(some_words))

--~ local function tex_preamble_match()
--~     return P(function(input, index)
--~         if index < 10 then
--~             local s, e, word = input:find('^(.+)[\n\r]',index)
--~             if word then
--~                 local interface = word:match("interface=(..)")
--~                 if interface then
--~                     local name = "c:/data/develop/context/lua/textadept/cont-" .. interface .. "-scite.lua"
--~                     --~ local f = io.open(name,"rb") -- fails
--~                     if f then
--~                         local data = f:read("*all")
--~                         data = data and loadstring(data)
--~                         data = data and data()
--~                         if data and type(data) == "table" then
--~                             some_words = word_list(data)
--~                             context.LoadTokens()
--~                         --  InitLexer(context)
--~                         end
--~                         f:close()
--~                     end
--~                 end
--~             end
--~         end
--~         return false
--~     end)
--~ end

local spacing      = token('whitespace', S(" \n\r\t\f")^1)
--~ local preamble     = token('preamble',   P('%') * tex_preamble_match())
local comment      = token('comment',    P('%') * (1-S("\n\r"))^0)
local keyword      = token('keyword',    P('\\') * tex_word_match)
local command      = token('command',    P('\\') * ((R("az","AZ")+S("@!?"))^1 + P(1)))
local grouping     = token('grouping',   S("{$}"))
local specials     = token('specials',   S("#()[]<>=\""))
local extras       = token('extras',     S("`~%^&_-+/\'|"))

-- LexByLine = true

local startluacode           = token("grouping", P("\\startluacode"))
local stopluacode            = token("grouping", P("\\stopluacode"))
--~ local startctxlua            = token("grouping", P("\\ctxlua") * spacing^0 * P("{"))
--~ local stopctxlua             = token("grouping", P("}"))

--~ local startMPcode            = token("grouping", P("\\startMPcode"))
--~ local stopMPcode             = token("grouping", P("\\stopMPcode"))
--~ local startuseMPgraphic      = token("grouping", P("\\startuseMPgraphic"))
--~ local stopuseMPgraphic       = token("grouping", P("\\stopuseMPgraphic"))
--~ local startreusableMPgraphic = token("grouping", P("\\startreusableMPgraphic"))
--~ local stopreusableMPgraphic  = token("grouping", P("\\stopreusableMPgraphic"))
--~ local startuniqueMPgraphic   = token("grouping", P("\\startuniqueMPgraphic"))
--~ local stopuniqueMPgraphic    = token("grouping", P("\\stopuniqueMPgraphic"))

function LoadTokens()

    lua.LoadTokens()

    add_token(context, 'whitespace', spacing)
--~ add_token(context, 'preamble',   preamble)
    add_token(context, 'comment',    comment)
    add_token(context, 'keyword',    keyword)
    add_token(context, 'command',    command)
    add_token(context, 'grouping',   grouping)
    add_token(context, 'specials',   specials)
    add_token(context, 'extras',     extras)
    add_token(context, 'any_char',   any_char)

    lua.TokenPatterns.any_char = token('default', 1 - stopluacode)

    make_embeddable(lua, context, startluacode, stopluacode)
--  make_embeddable(lua, context, startctxlua,  stopctxlua) -- no multiple embeddables unless more complex anychar
    embed_language(context, lua)

--  metapost.LoadTokens()
--  metapost.TokenPatterns.any_char = token('any_char', 1 - stopMPcode - stopuseMPgraphic - stopreusableMPgraphic - stopuniqueMPgraphic)
--  make_embeddable(metapost, context, startMPcode,            stopMPcode           )
--  make_embeddable(metapost, context, startuseMPgraphic,      stopuseMPgraphic     )
--  make_embeddable(metapost, context, startreusableMPgraphic, stopreusableMPgraphic)
--  make_embeddable(metapost, context, startuniqueMPgraphic,   stopuniqueMPgraphic  )
end

local bold   = true
local italic = true

function LoadStyles()
    add_style('preamble', style_nothing .. { fore = colors.yellow, bold = bold })
    add_style('comment',  style_nothing .. { fore = colors.yellow, bold = bold })
    add_style('keyword',  style_nothing .. { fore = colors.green,  bold = bold, italic = italic })
    add_style('command',  style_nothing .. { fore = colors.green,  bold = bold })
    add_style('grouping', style_nothing .. { fore = colors.red,    bold = bold })
    add_style('specials', style_nothing .. { fore = colors.blue,   bold = bold })
    add_style('extras',   style_nothing .. { fore = colors.yellow, bold = bold })
end

--~ textadept.mime_types.extensions["tex"]  = context
--~ textadept.mime_types.extensions["mkii"] = context
--~ textadept.mime_types.extensions["mkiv"] = context
