/*
 * Created by kweldon on 9/30/2014
 */
var phoneNumberInTextParser = function(){
    var
        minDigits = 7,
        validFirstCharacters = "0123456789(+",
        validSubsequentCharacters= "0123456789- .()",
        validExpressions = [
            /^((\+?1)?[-. ]?((\([2-9][0-8][0-9]\))|([2-9][0-8][0-9]))[-. ]?)?([2-9][0-9]{2})[-. ]?([0-9]{4})$/, // US Format
            /^\+[0-9]{1,3}\.[0-9]{4,14}$/, // +CCC.NNNNNNNNNN Extensible Provisioning Protocol (EPP) Format
            /^\+1\.[0-9]{7,15}$/ // +1.NNNNNNNNNNNNNNN ITU.E164.2005 Format
        ],
        logger = require("auditor.js").auditor("phoneNumberInTextParser");
    function log(msg) {
        logger.onLog(msg);
    }
    function matchesValidExpressions(text) {
        var
            j = 0;
        for (j = 0; j < validExpressions.length; j++) {
            if (text.match(validExpressions[j])) {
                return true;
            }
        }
        return false;
    }
    function isDigit(c) {
        return ("0123456789".indexOf(c) >= 0);
    }
    function checkForPhoneNumbersInText(node){
        var
            phoneNumbers = [];
        //var text = node.data + "~";
        var text = node + "~";
        var len = text.length;
        log("checkForPhoneNumberInSelection: " + node.toString());
        if (len < minDigits) return phoneNumbers;
        if (text.trim().length < minDigits) return phoneNumbers;

        var currentString = "";
        var onlyDigits = "";
        var startPosition = 0;
        var activeValidCharacters = validFirstCharacters;
        var i = 0;
        while (i < len) {

            // retrieve the next character
            var c = text.charAt(i);

            // if this character is not a valid phone number character
            // then attempt to verify if the potential phone number that
            // we have captured so far is in fact a valid phone number.
            var isValidCharacter = activeValidCharacters.indexOf(c) >= 0;
            if (!isValidCharacter) {
                currentString = trimRight(currentString);
                if (currentString.length > minDigits &&
                    matchesValidExpressions(currentString)) {
                    phoneNumbers.push( {
                        startPosition: startPosition,
                        length: currentString.length,
                        digitsOnly: onlyDigits
                    });

                    i = startPosition + currentString.length;
                }
                else {
                    var spaceIndex = currentString.indexOf(" ");
                    i = startPosition + (spaceIndex >= 0 ? spaceIndex : currentString.length) + 1;
                }
                startPosition = i;
                currentString = "";
                onlyDigits = "";
                activeValidCharacters = validFirstCharacters;
                continue;
            }

            // If this character is a space then it is possible that we
            // could have two phone numbers side-by-side with only whitespace
            // separating them. So test the current captured string to
            // see if it is a valid phone number.
            if (c == " ") {
                var testString = trimRight(currentString);
                if (testString.length > minDigits &&
                    matchesValidExpressions(testString)) {
                    phoneNumbers.push({
                        startPosition: startPosition,
                        length: testString.length,
                        digitsOnly: onlyDigits
                    });
                    i = startPosition + testString.length + 1;
                    startPosition = i;
                    currentString = "";
                    onlyDigits = "";
                    activeValidCharacters = validFirstCharacters;
                    continue;
                }
            }

            currentString += c;

            if (isDigit(c)) {
                onlyDigits += c;
            }

            // we have collected at least 1 character so set the list
            // of active characters to the list of valid subsequent characters.
            activeValidCharacters = validSubsequentCharacters;

            // move on to the next character
            ++i;
        }

        // we have reached the end of the text string so check if we
        // have collected a valid phone number.
        currentString = trimRight(currentString);
        if (currentString.length > minDigits &&
            matchesValidExpressions(currentString)) {
            phoneNumbers.push(onlyDigits);
            return true;
        }

        return phoneNumbers;

        function trimRight(string) {
            var trimmed = string;
            var len = trimmed.length;
            for (var idx = len - 1; idx >= 0; --idx) {
                var c = trimmed[idx];
                if (isDigit(c)) break;
                trimmed = trimmed.substr(0, idx);
            }
            return trimmed;
        }
    }
    return{
        onCheckForPhoneNumbersInText:checkForPhoneNumbersInText
    };
}();
exports.phoneNumberInTextParser = phoneNumberInTextParser;
