#! /usr/bin/env python

# Copyright (C) 2009 Kevin Ollivier  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. 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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. 
#
# wxWebKit build script for the waf build system

from settings import *

webkit_dirs = ['.', 'WebKitSupport']
include_paths = webkit_dirs + common_includes + ['.', '..',
                wk_root,
                os.path.join(wk_root, 'Source', 'JavaScriptCore'),
                os.path.join(wk_root, 'Source', 'WebCore'),
                os.path.join(wk_root, 'Source', 'WebCore', 'bindings', 'wx'),
                os.path.join(wk_root, 'Source', 'WebCore', 'DerivedSources'),
                os.path.join(output_dir),
                os.path.join(wk_root, 'Source', 'WebCore', 'page', 'wx'),
                os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'network', 'curl'),
                os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'wx'),
                os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'bridge', 'wx'),
                os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'graphics', 'wx'),
]

if sys.platform.startswith("win"):
    include_paths.append(os.path.join(wk_root, 'Source', 'WebCore','platform','win'))

windows_deps = [
                'lib/pthreadVC2.dll',
                'bin/icuuc40.dll', 'bin/icudt40.dll', 'bin/icuin40.dll',
                'bin/libcurl.dll', 'bin/libeay32.dll', 'bin/ssleay32.dll', 'bin/zlib1.dll',
                'lib/sqlite3.dll', 'bin/libxml2.dll', 'bin/libxslt.dll', 'bin/iconv.dll',
                ]

webcore_include_dirs = []
for dir in webcore_dirs + ['DerivedSources']:
    include_paths.append(os.path.join(wk_root, 'Source', 'WebCore', dir)) 

js_include_dirs = [os.path.join(wk_root, 'Source', 'JavaScriptCore', 'assembler')]
for dir in jscore_dirs:
    js_include_dirs.append(os.path.join(wk_root, 'Source', 'JavaScriptCore', dir))

def set_options(opt):
    common_set_options(opt)

def configure(conf):
    common_configure(conf)
    
def pre_build(bld):
    """
    The wxWebKit library should be rebuilt if jscore or webcore changes,
    so we make those static libs as dependencies.
    """
    
    ext = '.a'
    if sys.platform.startswith('win'):
        ext = '.lib'
    
    libjscore = os.path.join(output_dir, 'libjscore%s' % ext)
    libwebcore = os.path.join(output_dir, 'libwebcore%s' % ext)
    
    assert os.path.exists(libjscore)
    assert os.path.exists(libwebcore)
    
    bld.env.CXXDEPS_JSCORE = Utils.h_file(libjscore)
    bld.env.CXXDEPS_WEBCORE = Utils.h_file(libwebcore)
    
def build(bld):

    import TaskGen

    if sys.platform.startswith('darwin'):
        TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cxx']
        TaskGen.task_gen.mappings['.m'] = TaskGen.task_gen.mappings['.cxx']

    bld.add_pre_fun(pre_build)

    bld.env.LIBDIR = output_dir

    obj = bld.new_task_gen(
        features = 'cxx cshlib implib',
        includes = ' '.join(include_paths + js_include_dirs),
        target = 'wxwebkit',
        defines = ['WXMAKINGDLL_WEBKIT'],
        uselib = 'WX CURL ICU XSLT XML SQLITE3 WEBCORE JSCORE ' + get_config(),
        libpath = [output_dir],
        uselib_local = '',
        install_path = output_dir)
        
    exts = ['.c', '.cpp']
    if sys.platform.startswith('darwin'):
        exts.append('.mm')
        obj.includes += '../mac/WebCoreSupport ../../Source/WebCore/platform/mac'
        obj.source = "../mac/WebCoreSupport/WebSystemInterface.mm"
    obj.find_sources_in_dirs(webkit_dirs)

    if building_on_win32:
        for wxlib in bld.env['LIB_WX']:
            wxlibname = os.path.join(bld.env['LIBPATH_WX'][0], wxlib + '_vc.dll')
            if os.path.exists(wxlibname):
                bld.install_files(obj.install_path, [wxlibname])
        
        for dep in windows_deps:
            bld.install_files(obj.install_path, [os.path.join(msvclibs_dir, dep)])
