var Strings = {
    acronym: function (arr) {
        return arr.map(data => data.charAt(0)).join('');
    },
    titleCase(str) {
        return str
            .toLowerCase()
            .split(' ')
            .map(s => s.charAt(0).toUpperCase() + s.slice(1))
            .join(' ');
    },
    toUTF16: function(codePoint) {
        var TEN_BITS = parseInt('1111111111', 2);
        function u(codeUnit) {
            return '\\u' + codeUnit.toString(16).toUpperCase();
        }

        if (codePoint <= 0xFFFF) {
            return u(codePoint);
        }
        codePoint -= 0x10000;
        
        // Shift right to get to most significant 10 bits
        var leadSurrogate = 0xD800 + (codePoint >> 10);

        // Mask to get least significant 10 bits
        var tailSurrogate = 0xDC00 + (codePoint & TEN_BITS);

        return u(leadSurrogate) + u(tailSurrogate);
    },
    getUnicodeCharacter: function(cp) {
        if (cp >= 0 && cp <= 0xD7FF || cp >= 0xE000 && cp <= 0xFFFF) {
            return String.fromCharCode(cp);
        } else if (cp >= 0x10000 && cp <= 0x10FFFF) {

            // we substract 0x10000 from cp to get a 20-bits number
            // in the range 0..0xFFFF
            cp -= 0x10000;

            // we add 0xD800 to the number formed by the first 10 bits
            // to give the first byte
            var first = ((0xffc00 & cp) >> 10) + 0xD800;

            // we add 0xDC00 to the number formed by the low 10 bits
            // to give the second byte
            var second = (0x3ff & cp) + 0xDC00;

            return String.fromCharCode(first) + String.fromCharCode(second);
        }
    },
    fromHexCode: function(code) {
        return String.fromCharCode(parseInt(code, 16));
    }
};

module.exports = Strings;