#   Copyright (c) 2007 Axel Wachtler
#   All rights reserved.
#
#   Redistribution and use in source and binary forms, with or without
#   modification, are permitted provided that the following conditions
#   are met:
#
#   * Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the authors nor the names of its contributors
#     may be used to endorse or promote products derived from this software
#     without specific prior written permission.
#
#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
#   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#   POSSIBILITY OF SUCH DAMAGE.

# $Id: SConstruct,v 1.27 2009/01/15 22:05:44 awachtler Exp $

#=== modules ==================================================================
import os, time, sys
sys.path.append("./Tools")
import ds2reg

#=== setup build environment ==================================================
if os.name == 'posix':
    dbgfmt = "stabs"
else:
    dbgfmt = "dwarf-2"

com = Environment (
    tools = ['mingw'],
    CC="avr-gcc",
    DBGFMT=dbgfmt,
    CCFLAGS="-g$DBGFMT -mmcu=$CPU -Wall -Wundef -fshort-enums",
#    ENV = {'PATH' : os.environ['PATH']},
    ENV = os.environ,
    ofname = time.strftime("foo-%Y%m%d"),    
    )

class Board:
    def __init__(self,cpu,blstart,ccopts=[]):
        self.cpu = cpu
        self.blstart = blstart
        self.ccopts = ccopts

def create_radio_headerfiles(target, source, env):
    ds2reg.generate_header(str(source[0]),str(target[0]))

def configure_apsfile(target, source, env):
    strparm = []
    for k in env['STRINGPARAM'].keys():
        strparm.append("-stringparam %s '%s'" % (k,env['STRINGPARAM'][k]))

    env['PARMS'] = " ".join(strparm)
    cmd = env.subst("xsltproc $PARMS $XSLTFILE $APSTEMPLATE > %s" % target[0])
    print "CMD: %s" % cmd
    os.system(cmd)

# Template Processor for Doxygen Config File
def configure_doxyfile(target, source, env):
    fin = open(str(source[0]),"r")
    fout = open(str(target[0]),"w")
    print "****", str(env["dir_build"])
    for l in fin.xreadlines():
        l = l.rstrip()
        if "WARN_FORMAT" not in l:
            l = env.subst(l)
        fout.write(l+"\n")
    fout.close()
    fin.close()

com["TARFLAGS"] = '-c -z'
com["TARSUFFIX"] = '.tgz'
com['dir_top'] = com.Dir(".")
com['dir_src_doc'] = com.Dir("./Doc")
com['dir_src_img'] = com.Dir("./Doc/Images")
com['dir_install'] = com.Dir("install")
com['dir_install_doc'] = com.Dir("$dir_install/doc")
com['dir_install_xmpl'] = com.Dir("$dir_install/xmpl")
com['PROGSUFFIX']='.elf'
com["dir_build"] = com.Dir("build")
com.SConsignFile(".scons-signatures")


com['boardopts'] = {
                    # cpu ,  bootoffset in byte, compileflags
    "stkm8" :   Board("atmega8",0, "-DF_CPU=8000000UL"),
    "stkm16":   Board("atmega16",0x3800, "-DF_CPU=8000000UL"),
    "ict230":   Board("atmega1281",0x1e000, "-DF_CPU=8000000UL"),
    "rdk230":   Board("atmega1281",0x1e000, "-DF_CPU=8000000UL"),
    "rdk230b":  Board("atmega1281",0x1e000, "-DF_CPU=8000000UL"),
    "stk541":   Board("atmega1281",0x1e000, "-DF_CPU=8000000UL"),
    "stk541b":  Board("atmega1281",0x1e000, "-DF_CPU=8000000UL"),
    "stkt26":   Board("attiny26",0, "-DF_CPU=8000000UL"),
    "wdba1281": Board("atmega1281",0x1e000, "-DF_CPU=8000000UL"),
    "tiny230":  Board("attiny84",0, "-DF_CPU=8000000UL"),
    "stb230":   Board("atmega1281",0x1e000, "-DF_CPU=8000000UL"),
    "stb230b":  Board("atmega1281",0x1e000, "-DF_CPU=8000000UL"),
    "rzusb":    Board("at90usb1287",0x1e000, "-DF_CPU=8000000UL"),
#    "ravrf":    Board("atmega1284p",0x1e000, "-DF_CPU=8000000UL"),
    "rdk212":   Board("atmega1281",0x1e000, "-DF_CPU=8000000UL"),
    "stb212":   Board("atmega1281",0x1e000, "-DF_CPU=8000000UL"),
    }

com["boards"] = com['boardopts'].keys()
com['BUILDERS']['RadioHeaderWriter'] = Builder(action = create_radio_headerfiles)
com['BUILDERS']['DoxyfileTransformer'] =  Builder(action = configure_doxyfile)
com['BUILDERS']['ApsTransformer'] =  Builder(action = configure_apsfile)

avr = com.Clone()

#=== targets ==========================================================
for board in com["boards"]:
    avr.SConscript('Src/Lib/SConscript',
                    build_dir = '${dir_build}/%s/lib' % board,
                    exports="avr board",
                    duplicate = 0
                    )

    avr.SConscript('Src/App/SConscript',
                    build_dir = '${dir_build}/%s/app' % board,
                    exports="avr board",
                    duplicate = 0
                    )

    avr.SConscript('Src/Xmpl/SConscript',
                    build_dir = '${dir_build}/%s/xmpl' % board,
                    exports="avr board",
                    duplicate = 0
                    )
#
# Install Example sources
#
xmplsources = []
for xmpl in com.Glob('Src/Xmpl/xmpl*.[hc]'):
    x = avr.Install('$dir_install_xmpl',xmpl)
    xmplsources.append(x)

#
# Documentation targets
#
doc = com.Clone()

doc['dox_version'] = ARGUMENTS.get("version","[%s]" % time.asctime())

doc.SConscript("Doc/SConscript", build_dir='build/doc',
               exports="doc", duplicate=0)

doc.SConscript("Doc/Usr/SConscript", build_dir='build/udoc',
               exports="doc", duplicate=0)

doc.SConscript("Doc/App/SConscript", build_dir='build/adoc',
               exports="doc", duplicate=0)

doc.SConscript("Doc/Dev/SConscript", build_dir='build/ddoc',
               exports="doc", duplicate=0)

doc.SConscript("Doc/Contrib/SConscript", build_dir='build/cdoc',
               exports="doc", duplicate=0)

#=== install ==========================================================
i1 = avr.Install('${dir_install}/inc',
        ["Src/Lib/Inc/board.h",
         "Src/Lib/Inc/transceiver.h",
         "Src/Lib/Inc/const.h",
         "Src/Lib/Inc/radio.h",
         "Src/Lib/Inc/ioutil.h",
         "Src/Lib/Ioutil/uart.h",
         "Src/Lib/Inc/timer.h",
         "Src/Lib/Inc/hif.h"])

boardincludes = Glob("Src/Lib/Inc/boards/*.h")
i2 = avr.Install('${dir_install}/inc/boards/', boardincludes)
i3a = com.RadioHeaderWriter('${dir_install}/inc/at86rf230a.h','Templates/at86rf230a.txt')
i3b = com.RadioHeaderWriter('${dir_install}/inc/at86rf230b.h','Templates/at86rf230b.txt')
i3c = com.RadioHeaderWriter('${dir_install}/inc/at86rf231.h','Templates/at86rf231.txt')
i3d = com.RadioHeaderWriter('${dir_install}/inc/at86rf212.h','Templates/at86rf212.txt')
#=== clean ============================================================
com.Clean("distclean",["$dir_build", "$dir_install"])
com.Clean("clean",["$dir_build"])

#=== aliases ==========================================================
libtargets = map(lambda b: "l%s" % b, com["boards"])
apptargets = map(lambda b: "a%s" % b, com["boards"])
xmpltargets = map(lambda b: "x%s" % b, com["boards"])

for i in com["boards"]:
    avr.Alias(i, Split("l%s a%s x%s"%(i,i,i)))

avr.Alias('libs', libtargets)
avr.Alias('apps', apptargets)
avr.Alias('xmpli', xmplsources)
avr.Alias('xmpls', xmpltargets + xmplsources)
avr.Alias('all', libtargets +  apptargets + xmpltargets + xmplsources)

com.Alias('ddoc',['install/doc/dev'])
com.Alias('adoc',['install/doc/app'])
com.Alias('udoc',['install/doc/usr'])
com.Alias('cdoc',['install/doc/contrib'])
com.Alias('doc',['install/doc'])

com.Alias('install', [i1, i2, i3a, i3b, i3c , com["dir_install"] ])

Default('all')

Help("""

Build System for uracoli project

Usage:

    scons              - build all targets
    scons <target>     - build the target
    scons -c           - clean all files
    scons -c distclean - remove all created files and directories
    scons -c clean     - remove build directory (leaving install)
    scons -c <target>  - clean all files for the target

A <target> can be:
    all          : libraries and applications for all plattforms
    doc          : documentation
     adoc        :  application guide
     ddoc        :  developpers guide
     udoc        :  users guide
    libs         : libraries for all plattforms
    apps         : applications for all plattforms
    xmpls        : small example applications for all plattforms
    <BoardType>  : libraries and applications for specified board type
    l<BoardType> : libraries for specified board type
    a<BoardType> : applications for specified board type
    x<BoardType> : small example applications for specified board type

<BoardType> can be:
    stkt26  : ATtiny26 + AT86rf230 adapter on stk500
    stkm16  : ATmega16 + AT86rf230 adapter on stk500
    ict230  : version 1.0 of the In-Cirquit Radio Boards
    rdk230  : Atmel reference platform (AT86RF230 Rev. A)
    rdk230b : Atmel reference platform (AT86RF230 Rev. B)
    stk541  : Atmels RZ541 Packet Sniffer Kit board (AT86RF230 Rev. A)
    stk541b : Atmels RZ541 Packet Sniffer Kit board (AT86RF230 Rev. B)
    wdba1281: Meshnetics MeshBean WDB-A1281-* development board
    tiny230 : Joerg's (DL8DTL) ATtiny44 with AT86RF230
    stb230  : Dresden Electronic Sensor Terminal Board with AT86RF230 Rev. A
    rzusb   : Atmel Raven USB Stick with AT86RF230 Rev. B
    rdk212  : Atmel reference platform (AT86RF212)
    stb212  : Dresden Electronic Sensor Terminal Board with AT86RF212
""")
