#! /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. 
#
# WebCore build script for the waf build system

import Options

from settings import *
import wxpresets

import TaskGen
from TaskGen import taskgen, feature, after
import Task, ccroot

def generate_webcore_derived_sources(conf):
    # build the derived sources
    derived_sources_dir = os.path.join(webcore_dir, 'DerivedSources')
    wc_dir = webcore_dir
    if building_on_win32:
        wc_dir = get_output('cygpath --unix "%s"' % wc_dir)
    if not os.path.exists(derived_sources_dir):
        os.mkdir(derived_sources_dir)

    olddir = os.getcwd()
    os.chdir(derived_sources_dir)
    
    # DerivedSources.make expects Cygwin (i.e. Unix-style) python, so use that instead.
    if building_on_win32:
        oldpath = os.environ["PATH"]
        os.environ["PATH"] = "/usr/bin" + os.pathsep + os.environ["PATH"]
    os.system('make -f %s/DerivedSources.make WebCore=%s SOURCE_ROOT=%s all FEATURE_DEFINES="%s"' % (wc_dir, wc_dir, wc_dir, conf.env["FEATURE_DEFINES"]))
    if building_on_win32:
        os.environ["PATH"] = oldpath
    os.system('perl %s/Source/WebKit/scripts/generate-webkitversion.pl --outputDir=%s --config %s/Source/WebKit/mac/Configurations/Version.xcconfig' % (wk_root, derived_sources_dir, wk_root))
    os.chdir(olddir)

def generate_jscore_derived_sources(conf):
    # build the derived sources
    js_dir = jscore_dir
    if building_on_win32:
        js_dir = get_output('cygpath --unix "%s"' % js_dir)
    derived_sources_dir = os.path.join(jscore_dir, 'DerivedSources')
    if not os.path.exists(derived_sources_dir):
        os.mkdir(derived_sources_dir)

    olddir = os.getcwd()
    os.chdir(derived_sources_dir)

    # DerivedSources.make expects Cygwin (i.e. Unix-style) python, so use that instead.
    if building_on_win32:
        oldpath = os.environ["PATH"]
        os.environ["PATH"] = "/usr/bin" + os.pathsep + os.environ["PATH"]
    command = 'make -f %s/DerivedSources.make JavaScriptCore=%s BUILT_PRODUCTS_DIR=%s all FEATURE_DEFINES="%s"' % (js_dir, js_dir, js_dir, conf.env["FEATURE_DEFINES"])
    os.system(command)
    if building_on_win32:
        os.environ["PATH"] = oldpath
    os.chdir(olddir)

def set_options(opt):
    common_set_options(opt)

def configure(conf):
    common_configure(conf)
    generate_jscore_derived_sources(conf)
    generate_webcore_derived_sources(conf)
    if Options.options.port == "wx" and sys.platform.startswith('win'):
        graphics_dir = os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'graphics')
        # HACK ALERT: MSVC automatically adds the source file's directory as the first entry in the
        # path. Unfortunately, that means when compiling these files we will end up including
        # win/FontPlatformData.h, which breaks wx compilation. So we copy the files to the wx dir.
        for afile in ['UniscribeController.h', 'UniscribeController.cpp', 'GlyphPageTreeNodeCairoWin.cpp']:
            shutil.copy(os.path.join(graphics_dir, 'win', afile), os.path.join(graphics_dir, 'wx'))

    webcore_out_dir = os.path.join(output_dir, 'WebCore')
    if not os.path.exists(webcore_out_dir):
        os.makedirs(webcore_out_dir)
    shutil.copy('Source/WebCore/platform/mac/WebCoreSystemInterface.h', os.path.join(output_dir, 'WebCore', 'WebCoreSystemInterface.h'))
    jscore_out_dir = os.path.join(output_dir, 'JavaScriptCore')
    if not os.path.exists(jscore_out_dir):
        os.makedirs(jscore_out_dir)
    for api_file in glob.glob(os.path.join(jscore_dir, 'API/*.h')):
        shutil.copy(api_file, os.path.join(jscore_out_dir, os.path.basename(api_file)))

    if Options.options.port == "wx" and Options.options.wxpython:
        common_configure(conf)
        conf.check_tool('swig', tooldir='Source/WebKit/wx/bindings/python')
        conf.check_swig_version('1.3.29')

def build(bld):

    webcore_dirs = list(webcore_dirs_common)

    if Options.options.port == "wx":
        webcore_dirs.extend(['Source/WebKit/wx', 'Source/WebKit/wx/WebKitSupport'])
    
    wk_includes = ['.',
                    os.path.join(wk_root, 'Source', 'JavaScriptCore'),
                    os.path.join(wk_root, 'Source', 'JavaScriptCore', 'wtf', 'text'),
                    os.path.join(wk_root, 'Source', 'WebCore'),
                    os.path.join(wk_root, 'Source', 'WebCore', 'DerivedSources'),
                    os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'image-decoders'),
                    os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'win'),
                    os.path.join(wk_root, 'Source', 'WebCore', 'workers'),
                    os.path.join(output_dir),
            ]
    
    if Options.options.port == "wx":
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebKit', 'wx'))
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'wx', 'wxcode'))
    
    if sys.platform.startswith("win"):
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'win'))
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'graphics', '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_sources = {}
    
    if Options.options.port == "wx":
        webcore_sources['wx'] = [
            'Source/WebCore/bindings/cpp/WebDOMEventTarget.cpp',
            'Source/WebCore/platform/KillRingNone.cpp',
            'Source/WebCore/platform/text/LocalizedDateNone.cpp',
            'Source/WebCore/platform/text/LocalizedNumberNone.cpp'
        ]  
    
        if building_on_win32:
            # make sure platform/wx comes after this so we get the right
            # FontPlatformData.h
            webcore_dirs.extend(['Source/WebCore/platform/wx/wxcode/win', 'Source/WebCore/plugins/win'])
            webcore_sources['wx-win'] = [
                   'Source/WebCore/platform/graphics/win/GlyphPageTreeNodeCairoWin.cpp',
                   'Source/WebCore/platform/graphics/win/TransformationMatrixWin.cpp',
                   'Source/WebCore/platform/ScrollAnimatorWin.cpp',
                   # wxTimer on Windows has a bug that causes it to eat crashes in callbacks
                   # so we need to use the Win port's implementation until the wx bug fix is
                   # widely available (it was fixed in 2.8.10).
                   'Source/WebCore/platform/win/SharedTimerWin.cpp',
                   'Source/WebCore/platform/win/SystemInfo.cpp',
                   'Source/WebCore/platform/win/WebCoreInstanceHandle.cpp',
                   # Use the Windows plugin architecture
                   #'Source/WebCore/plugins/win/PluginDataWin.cpp',
                   'Source/WebCore/plugins/win/PluginDatabaseWin.cpp',
                   'Source/WebCore/plugins/win/PluginMessageThrottlerWin.cpp',
                   'Source/WebCore/plugins/win/PluginPackageWin.cpp',
                   'Source/WebCore/plugins/win/PluginViewWin.cpp',
            ]
            if Options.options.cairo:
                webcore_dirs.append('Source/WebCore/platform/wx/wxcode/cairo')
            else:
                webcore_dirs.append('Source/WebCore/platform/wx/wxcode/gdiplus')
        elif sys.platform.startswith('darwin'):
            webcore_dirs.append('Source/WebCore/plugins/mac')
            webcore_dirs.append('Source/WebCore/platform/wx/wxcode/mac/carbon')
            webcore_dirs.append('Source/WebCore/platform/text/mac')
            webcore_sources['wx-mac'] = [
                   'Source/WebCore/platform/mac/PurgeableBufferMac.cpp',
                   'Source/WebCore/platform/mac/WebCoreNSStringExtras.mm',
                   'Source/WebCore/platform/mac/WebCoreSystemInterface.mm',
                   'Source/WebCore/platform/graphics/cg/FloatSizeCG.cpp',
                   'Source/WebCore/platform/graphics/mac/ComplexTextController.cpp',
                   'Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm',
                   'Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp',
                   'Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp',
                   'Source/WebCore/platform/graphics/mac/SimpleFontDataATSUI.mm',
                   'Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp',
                   'Source/WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm',
                   'Source/WebCore/platform/wx/wxcode/mac/carbon/fontprops.mm',
                   'Source/WebCore/plugins/mac/PluginPackageMac.cpp',
                   'Source/WebCore/plugins/mac/PluginViewMac.mm'
            ]
        else:
            webcore_sources['wx-gtk'] = [
                   'Source/WebCore/plugins/PluginViewNone.cpp',
                   'Source/WebCore/plugins/PluginPackageNone.cpp'
            ]
            webcore_dirs.append('Source/WebCore/platform/wx/wxcode/gtk')
            webcore_dirs.append('Source/WebCore/platform/wx/wxcode/cairo')
        

    import TaskGen

    # FIXME: Does this need to be Source/JavaScriptCore?
    bld.add_subdirs('Source/JavaScriptCore')

    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']

    features = [Options.options.port.lower()]
    exclude_patterns = ['*AllInOne.cpp', '*CFNet.cpp', '*Chromium*.cpp', 
            '*Efl.cpp', '*Gtk.cpp', '*Mac.cpp', '*None.cpp', '*Qt.cpp', '*Safari.cpp',
            'test*bindings.*', '*WinCE.cpp', "WebDOMCanvas*.cpp", "WebDOMSVG*.cpp"]
    if Options.options.port == 'wx':
        features.append('curl')
        exclude_patterns.append('*Win.cpp')
        
    if sys.platform.startswith('darwin'):
        features.append('cf')
        
    else:
        exclude_patterns.append('*CF.cpp')

    full_dirs = get_dirs_for_features(wk_root, features=features, dirs=webcore_dirs)

    jscore_dir = os.path.join(wk_root, 'Source', 'JavaScriptCore')
    for item in os.listdir(jscore_dir):
        fullpath = os.path.join(jscore_dir, item)
        if os.path.isdir(fullpath) and not item == "os-win32" and not item == 'icu':
            wk_includes.append(fullpath)

    wk_includes.append('Source')
    wk_includes.append(os.path.join(jscore_dir, 'collector', 'handles'))
    wk_includes.append(os.path.join(jscore_dir, 'wtf', 'unicode'))
    wk_includes.append(os.path.join(jscore_dir, 'wtf', 'unicode', 'icu'))
    wk_includes += common_includes + full_dirs
    if sys.platform.startswith('darwin'):
        wk_includes.append(os.path.join(webcore_dir, 'icu'))

    cxxflags = []
    if building_on_win32:
        cxxflags.append('/FIWebCorePrefix.h')
        # FIXME: We do this because in waf, local include dirs take precedence
        # over global ones. This makes sense, but because unicode/utf8.h is both
        # an ICU header name and a WebKit header name (in Source/JavaScriptCore/wtf)
        # we have to make sure <unicode/utf8.h> picks up the ICU one first.
        global msvclibs_dir
        wk_includes.append(os.path.join(msvclibs_dir, 'include'))
    else:
        cxxflags.extend(['-include', 'WebCorePrefix.h'])

    webcore = bld.new_task_gen(
        features = 'cc cxx cshlib',
        includes = ' '.join(wk_includes),
        source = ' '.join(flattenSources(webcore_sources.values())),
        cxxflags = cxxflags,
        defines = ['WXMAKINGDLL_WEBKIT', 'BUILDING_WebCore'],
        libpath = [output_dir],
        target = 'wxwebkit',
        uselib = 'WX ICU XML XSLT CURL SQLITE3 WKINTERFACE ' + get_config(),
        uselib_local = 'jscore',
        install_path = output_dir,
        )
        
    excludes = []
    
    if Options.options.port == 'wx':
        excludes = get_excludes(webcore_dir, exclude_patterns)
        excludes.extend(['UserStyleSheetLoader.cpp', 'RenderMediaControls.cpp'])

        # intermediate sources
        excludes.append('DocTypeStrings.cpp')
        excludes.append('HTMLEntityNames.cpp')

        # Qt specific file in common sources
        excludes.append('ContextShadow.cpp')

        # FIXME: these three require headers that I can't seem to find in trunk.
        # Investigate how to resolve these issues.
        excludes.append('JSAbstractView.cpp')
        excludes.append('JSPositionCallback.cpp')
        excludes.append('JSInspectorController.cpp')
        
        # The bindings generator seems to think these are ref-counted, while they aren't in trunk.
        excludes.append('JSElementTimeControl.cpp')
        excludes.append('JSSVGAnimatedPathData.cpp')
        excludes.append('JSSVGAnimatedPoints.cpp')
        excludes.append('JSSVGExternalResourcesRequired.cpp')
        excludes.append('JSSVGFilterPrimitiveStandardAttributes.cpp')
        excludes.append('JSSVGLocatable.cpp')
        excludes.append('JSSVGStyleTable.cpp')
        excludes.append('JSSVGTests.cpp')
        excludes.append('JSSVGStylable.cpp')
        excludes.append('JSSVGZoomAndPan.cpp')
        
        # These are files that expect methods not in the base C++ class, usually XYZAnimated methods.
        excludes.append('JSSVGFitToViewBox.cpp')
        excludes.append('JSSVGLangSpace.cpp')
        excludes.append('JSSVGTransformable.cpp')
        excludes.append('JSSVGURIReference.cpp')
        
        # These are C++ DOM Bindings that won't compile because they look for things not in trunk.
        excludes.append('WebDOMEventTarget.cpp')
        excludes.append('WebDOMAbstractView.cpp')
        excludes.append('WebDOMBlobBuilder.cpp')
        excludes.append('WebDOMEventListenerCustom.cpp')
        excludes.append('WebDOMElementTimeControl.cpp')
        excludes.append('WebDOMImageData.cpp')
        excludes.append('WebDOMInspectorBackend.cpp')
        excludes.append('WebDOMScriptProfile.cpp')
        excludes.append('WebDOMScriptProfileNode.cpp')
        excludes.append('WebNativeEventListener.cpp')
        
        # FIXME: It appears these are no longer needed by any port, once this is confirmed,
        # we should remove these sources from the tree.
        excludes.append('WebDOMDOMWindowCustom.cpp')
        excludes.append('WebDOMHTMLOptionsCollectionCustom.cpp')
        excludes.append('WebDOMNodeCustom.cpp')
        excludes.append('WebDOMHTMLDocumentCustom.cpp')
        excludes.append('WebDOMHTMLCollectionCustom.cpp')
        excludes.append('WebNativeNodeFilterCondition.cpp')
        excludes.append('WebDOMNodeFilterCustom.cpp')
        
        # this file is unused by any port, not sure why it was
        # left in the tree
        excludes.append('GeneratedImage.cpp')
        
        # features we don't build / use
        excludes.append('JSNavigatorCustom.cpp')
        excludes.append('WebGLContextEvent.cpp')
        excludes.append('FileSystemPOSIX.cpp')
        excludes.append('SharedBufferPOSIX.cpp')
        
        
        # These files appear not to build with older versions of ICU
        excludes.append('LocalizedNumberICU.cpp')
        excludes.append('LocaleToScriptMappingICU.cpp')
        
        if building_on_win32:
            excludes.append('SharedTimerWx.cpp')
            excludes.append('RenderThemeWin.cpp')
            excludes.append('KeyEventWin.cpp')
            
        if building_on_win32 or sys.platform.startswith('darwin'):
            excludes.append('GlyphMapWx.cpp')
        excludes.append('AuthenticationCF.cpp')
        excludes.append('LoaderRunLoopCF.cpp')
        excludes.append('ResourceErrorCF.cpp')
        
        # once we move over to the new FPD implementation, remove this.
        excludes.append('FontPlatformData.cpp')
        
        # we don't use gestures currently
        excludes.append('PlatformGestureRecognizer.cpp')
        
        # we need a better system to exclude CF stuff
        excludes.append('HyphenationCF.cpp')
        
        if sys.platform.startswith('darwin'):
            webcore.includes += ' Source/WebKit/mac/WebCoreSupport Source/WebCore/platform/mac'
            webcore.source += ' Source/WebKit/mac/WebCoreSupport/WebSystemInterface.mm'
            
        if building_on_win32:
            for wxlib in bld.env['LIB_WX']:
                wx_version = wxpresets.get_wx_version(os.environ['WXWIN'])
                if int(wx_version[1]) % 2 == 1:
                    wxlib = wxlib.replace(''.join(wx_version[:2]), ''.join(wx_version))
                wxlibname = os.path.join(bld.env['LIBPATH_WX'][0], wxlib + '_vc.dll')
                print "Copying %s" % wxlibname
                if os.path.exists(wxlibname):
                    bld.install_files(webcore.install_path, [wxlibname])
        
            for dep in windows_deps:
                bld.install_files(webcore.install_path, [os.path.join(msvclibs_dir, dep)])
            
            if "CAIRO_ROOT" in os.environ and Options.options.cairo:
                cairo_bin_dir = os.path.join(os.environ["CAIRO_ROOT"], "bin") 
                for dep in glob.glob(os.path.join(cairo_bin_dir, "*.dll")):
                    bld.install_files(webcore.install_path, [os.path.join(cairo_bin_dir, dep)])
                    
    webcore.find_sources_in_dirs(full_dirs, excludes = excludes, exts=['.c', '.cpp'])

    bld.add_group()
    
    if Options.options.port == "wx":    
        bld.add_subdirs(['Tools/DumpRenderTree', 'Tools/wx/browser', 'Source/WebKit/wx/bindings/python'])
