/**
*
*  Javascript sprintf
*  http://www.webtoolkit.info/
*
*
**/

sprintfWrapper = {

        init : function () {

                if (typeof arguments == 'undefined') { return null; }
                if (arguments.length < 1) { return null; }
                if (typeof arguments[0] != 'string') { return null; }
                if (typeof RegExp == 'undefined') { return null; }

                var string = arguments[0];
                var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
                var matches = new Array();
                var strings = new Array();
                var convCount = 0;
                var stringPosStart = 0;
                var stringPosEnd = 0;
                var matchPosEnd = 0;
                var newString = '';
                var match = null;

                while (match = exp.exec(string)) {
                        if (match[9]) { convCount += 1; }

                        stringPosStart = matchPosEnd;
                        stringPosEnd = exp.lastIndex - match[0].length;
                        strings[strings.length] = string.substring(stringPosStart, stringPosEnd);

                        matchPosEnd = exp.lastIndex;
                        matches[matches.length] = {
                                match: match[0],
                                left: match[3] ? true : false,
                                sign: match[4] || '',
                                pad: match[5] || ' ',
                                min: match[6] || 0,
                                precision: match[8],
                                code: match[9] || '%',
                                negative: parseInt(arguments[convCount]) < 0 ? true : false,
                                argument: String(arguments[convCount])
                        };
                }
                strings[strings.length] = string.substring(matchPosEnd);

                if (matches.length == 0) { return string; }
                if ((arguments.length - 1) < convCount) { return null; }

                var code = null;
                var match = null;
                var i = null;

                for (i=0; i<matches.length; i++) {

                        if (matches[i].code == '%') { substitution = '%' }
                        else if (matches[i].code == 'b') {
                                matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
                                substitution = sprintfWrapper.convert(matches[i], true);
                        }
                        else if (matches[i].code == 'c') {
                                matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
                                substitution = sprintfWrapper.convert(matches[i], true);
                        }
                        else if (matches[i].code == 'd') {
                                matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
                                substitution = sprintfWrapper.convert(matches[i]);
                        }
                        else if (matches[i].code == 'f') {
                                matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
                                substitution = sprintfWrapper.convert(matches[i]);
                        }
                        else if (matches[i].code == 'o') {
                                matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
                                substitution = sprintfWrapper.convert(matches[i]);
                        }
                        else if (matches[i].code == 's') {
                                matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
                                substitution = sprintfWrapper.convert(matches[i], true);
                        }
                        else if (matches[i].code == 'x') {
                                matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
                                substitution = sprintfWrapper.convert(matches[i]);
                        }
                        else if (matches[i].code == 'X') {
                                matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
                                substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
                        }
                        else {
                                substitution = matches[i].match;
                        }

                        newString += strings[i];
                        newString += substitution;

                }
                newString += strings[i];

                return newString;

        },

        convert : function(match, nosign){
                if (nosign) {
                        match.sign = '';
                } else {
                        match.sign = match.negative ? '-' : match.sign;
                }
                var l = match.min - match.argument.length + 1 - match.sign.length;
                var pad = new Array(l < 0 ? 0 : l).join(match.pad);
                if (!match.left) {
                        if (match.pad == '0' || nosign) {
                                return match.sign + pad + match.argument;
                        } else {
                                return pad + match.sign + match.argument;
                        }
                } else {
                        if (match.pad == '0' || nosign) {
                                return match.sign + match.argument + pad.replace(/0/g, ' ');
                        } else {
                                return match.sign + match.argument + pad;
                        }
                }
        }
}

sprintf = sprintfWrapper.init;
