#!/usr/bin/env python
#vim: et:ts=4:sw=4:sts=4

import base64
import json
import os
import ox
import re
import shutil
import sys


def build_oxjs(geo):

    base_path = os.path.dirname(__file__)
    if base_path:
        os.chdir(base_path)

    source_path = '../../source/'
    build_path = '../../build/'
    dev_path = '../../dev/'
    comment = 'OxJS (c) 2012 0x2620, dual-licensed GPL/MIT, see http://oxjs.org for details'

    # SVGs
    path = source_path + 'Ox.UI/themes/classic/svg/'
    for filename in os.listdir(path):
        svg = read_file(path + filename)
        svg = svg.replace('#000000', '#XXXXXX').replace('#404040', '#C0C0C0').replace('#FFFFFF', '#000000').replace('#XXXXXX', '#FFFFFF')
        write_file(path.replace('/classic/', '/modern/') + filename, svg)
    imageURLs = {}
    imageDataURLs = {}
    for theme in ['classic', 'modern']:
        path = source_path + 'Ox.UI/themes/' + theme + '/svg/'
        for filename in os.listdir(path):
            if not filename[0] in '._' and not filename.endswith('~'):
                key = theme + '/' + filename[:-4]
                imageURLs[key] = os.path.join(path, filename).replace(source_path, '')
                data = re.sub('\n\s+', '', read_file(path + filename))
                imageDataURLs[key] = 'data:image/svg+xml;base64,' + base64.b64encode(data)
    write_file(build_path + 'Ox.UI/json/Ox.UI.imageURLs.json', json.dumps(imageURLs, sort_keys=True))
    write_file(build_path + 'Ox.UI/json/Ox.UI.imageDataURLs.json', json.dumps(imageDataURLs, sort_keys=True))
    write_file(dev_path + 'Ox.UI/json/Ox.UI.imageURLs.json', json.dumps(imageURLs, indent=4, sort_keys=True))
    write_file(dev_path + 'Ox.UI/json/Ox.UI.imageDataURLs.json', json.dumps(imageDataURLs, indent=4, sort_keys=True))

    # copy & link
    ui_files = {'build': [], 'dev': []}
    for path, dirnames, filenames in os.walk(source_path):
        for filename in filenames:
            if not '_' in path and not filename[0] in '._' \
                    and not filename.endswith('~') \
                    and (geo or not '/Ox.Geo/' in path):
                # write copies in build path
                source = os.path.join(path, filename)
                is_jquery = re.match('^jquery-[\d\.]+\.js$', filename)
                is_jquery_min = re.match('^jquery-[\d\.]+\.min\.js$', filename)
                is_jquery_plugin = re.match('^jquery\..*?\.js$', filename)
                if is_jquery or is_jquery_min:
                    target = os.path.join(path.replace(source_path, build_path), 'jquery.js')
                else:
                    target = os.path.join(path.replace(source_path, build_path), filename)
                    if is_jquery_plugin:
                        ui_files['build'].append(target.replace(build_path, ''))
                        ui_files['dev'].append(target.replace(build_path, ''))
                if not '/Ox/js' in source and not '/Ox.UI/js/' in source and not is_jquery:
                    if re.match('^Ox\..+\.js$', filename):
                        js = read_file(source)
                        write_file(target, ox.js.minify(js, comment))
                    else:
                        copy_file(source, target)
                # write links in dev path
                parts = os.path.join(path.replace(source_path, ''), filename).split('/')
                for i, part in enumerate(parts):
                    if i < len(parts) - 1:
                        parts[i] = '..'
                link_source = '/'.join(parts).replace(filename, os.path.join(path, filename))[3:]
                link_target = target.replace(build_path, dev_path)
                if not is_jquery_min:
                    write_link(link_source, link_target)

    # Ox.js
    # FIXME: Document what exactly the following dependecies are!
    filenames = [
        ['Fallback.js', 'Core.js'],
        ['Collection.js', 'Math.js']
    ]
    js = ''
    js_dir = 'Ox/js/'
    data = [[], [], []]
    for filename in filenames[0]:
        data[0].append(js_dir + filename)
    for filename in filenames[1]:
        data[1].append(js_dir + filename)
    filenames = filenames[0] + filenames[1]
    for filename in os.listdir(source_path + js_dir):
        if not filename in filenames \
                and not filename.startswith('.') \
                and not filename.endswith('~'):
            filenames.append(filename)
    for filename in filenames:
        js += read_file(source_path + js_dir + filename) + '\n'
        if not js_dir + filename in data[0] + data[1]:
            data[2].append(js_dir + filename)
    write_file(build_path + 'Ox.js', ox.js.minify(js, comment))
    write_file(dev_path + '/Ox/json/' + 'Ox.json', json.dumps(data, indent=4))

    # Ox.UI
    js = ''
    root = source_path + 'Ox.UI/'
    for path, dirnames, filenames in os.walk(root):
        for filename in sorted(filenames):
            # jquery gets included by Ox.UI loader
            # theme css files get included by main css
            # svgs are loaded as URLs or dataURLs
            # browser images appear before load
            if path != root and not '_' in path and not filename[0] in '._'\
                    and not filename.endswith('~')\
                    and not 'jquery' in filename\
                    and not ('/themes/' in path and filename.endswith('.css'))\
                    and not filename.endswith('.svg')\
                    and not filename.startswith('browser'):
                ui_files['dev'].append(os.path.join(path.replace(source_path, ''), filename))
                if not '/js/' in path:
                    ui_files['build'].append(os.path.join(path.replace(source_path, ''), filename))
                if filename.endswith('.js'):
                    js += read_file(os.path.join(path, filename)) + '\n'
    filename = build_path + 'Ox.UI/js/Ox.UI.js'
    write_file(filename, ox.js.minify(js, comment))
    ui_files['build'].append(filename.replace(build_path, ''))
    files = json.dumps(sorted(ui_files['build']))
    write_file(build_path + 'Ox.UI/json/Ox.UI.files.json', files)
    files = json.dumps(sorted(ui_files['dev']), indent=4)
    write_file(dev_path + 'Ox.UI/json/Ox.UI.files.json', files)


def copy_file(source, target):
    print 'copying', source, 'to', target
    write_file(target, read_file(source))

def read_file(file):
    print 'reading', file
    f = open(file)
    data = f.read()
    f.close()
    return data

def write_file(file, data):
    print 'writing', file
    write_path(file)
    f = open(file, 'w')
    f.write(data)
    f.close()
    return len(data)

def write_link(source, target):
    print 'linking', source, 'to', target
    write_path(target)
    if os.path.exists(target):
        os.unlink(target)
    os.symlink(source, target)

def write_path(file):
    path = os.path.split(file)[0]
    if path and not os.path.exists(path):
        os.makedirs(path)


if __name__ == '__main__':
    geo = False if sys.argv[-1] == '-nogeo' else True
    build_oxjs(geo)