module.exports = function(environment) {

var Quoted = require("../tree/quoted"),
    URL = require("../tree/url"),
    functionRegistry = require("./function-registry"),
    fallback = function(functionThis, node) {
        return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context);
    },
    logger = require('../logger');

functionRegistry.add("data-uri", function(mimetypeNode, filePathNode) {

    if (!filePathNode) {
        filePathNode = mimetypeNode;
        mimetypeNode = null;
    }

    var mimetype = mimetypeNode && mimetypeNode.value;
    var filePath = filePathNode.value;
    var currentFileInfo = this.currentFileInfo;
    var currentDirectory = currentFileInfo.relativeUrls ?
        currentFileInfo.currentDirectory : currentFileInfo.entryPath;

    var fragmentStart = filePath.indexOf('#');
    var fragment = '';
    if (fragmentStart !== -1) {
        fragment = filePath.slice(fragmentStart);
        filePath = filePath.slice(0, fragmentStart);
    }

    var fileManager = environment.getFileManager(filePath, currentDirectory, this.context, environment, true);

    if (!fileManager) {
        return fallback(this, filePathNode);
    }

    var useBase64 = false;

    // detect the mimetype if not given
    if (!mimetypeNode) {

        mimetype = environment.mimeLookup(filePath);

        if (mimetype === "image/svg+xml") {
            useBase64 = false;
        } else {
            // use base 64 unless it's an ASCII or UTF-8 format
            var charset = environment.charsetLookup(mimetype);
            useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;
        }
        if (useBase64) { mimetype += ';base64'; }
    }
    else {
        useBase64 = /;base64$/.test(mimetype);
    }

    var fileSync = fileManager.loadFileSync(filePath, currentDirectory, this.context, environment);
    if (!fileSync.contents) {
        logger.warn("Skipped data-uri embedding of " + filePath + " because file not found");
        return fallback(this, filePathNode || mimetypeNode);
    }
    var buf = fileSync.contents;
    if (useBase64 && !environment.encodeBase64) {
        return fallback(this, filePathNode);
    }

    buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf);

    var uri = "data:" + mimetype + ',' + buf + fragment;

    // IE8 cannot handle a data-uri larger than 32,768 characters. If this is exceeded
    // and the --ieCompat flag is enabled, return a normal url() instead.
    var DATA_URI_MAX = 32768;
    if (uri.length >= DATA_URI_MAX) {

        if (this.context.ieCompat !== false) {
            logger.warn("Skipped data-uri embedding of " + filePath + " because its size (" + uri.length +
                " characters) exceeds IE8-safe " + DATA_URI_MAX + " characters!");

            return fallback(this, filePathNode || mimetypeNode);
        }
    }

    return new URL(new Quoted('"' + uri + '"', uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
});

};