// based on PHP Name Parser by Josh Fraser (joshfraser.com)
// http://www.onlineaspect.com/2009/08/17/splitting-names/
// ported to JavaScript by Mark Pemburn (pemburnia.com)
// released under Apache 2.0 license

goog.provide("parse_names.vendor");

parse_names.vendor.removeIgnoredChars = function (word) {
    //ignore periods
    return word.replace(".","");
};

// detect compound last names like "Von Fange"
parse_names.vendor.is_compound_lastName = function (word) {
    word = word.toLowerCase();
    // these are some common prefixes that identify a compound last names - what am I missing?
    var words = ['vere','von','van','de','del','della','di','da','pietro','vanden','du','st.','st','la','lo','ter'];
    return (words.indexOf(word) >= 0);
};

parse_names.vendor.is_camel_case = function (word) {
    var ucReg = /[A-Z]+/;
    var lcReg = /[a-z]+/;
    return (ucReg.exec(word) && lcReg.exec(word));
};

// single letter, possibly followed by a period
parse_names.vendor.is_initial = function (word) {
    word = parse_names.vendor.removeIgnoredChars(word);
    return (word.length === 1);
};

// helper for this.fix_case
// uppercase words split by the seperator (ex. dashes or periods)
parse_names.vendor.safe_ucfirst = function (seperator, word) {
    return word.split(seperator).map(function(thisWord){
	if(parse_names.vendor.is_camel_case(thisWord)) {
	    return thisWord;
	} else {
	    return thisWord.substr(0,1).toUpperCase() + thisWord.substr(1).toLowerCase();
	}
    }, this).join(seperator);
};

// ucfirst words split by dashes or periods
// ucfirst all upper/lower strings, but leave camelcase words alone
parse_names.vendor.fix_case = function (word) {
    // uppercase words split by dashes, like "Kimura-Fay"
    word = parse_names.vendor.safe_ucfirst("-",word);
    // uppercase words split by periods, like "J.P."
    word = parse_names.vendor.safe_ucfirst(".",word);
    return word;
};


// detect and format standard salutations
// I'm only considering english honorifics for now & not words like
parse_names.vendor.is_salutation = function (word) {
    word = parse_names.vendor.removeIgnoredChars(word).toLowerCase();
    // returns normalized values
    if (word === "mr" || word === "master" || word === "mister") {
	return "Mr.";
    } else if (word === "mrs") {
	return "Mrs.";
    } else if (word === "miss" || word === "ms") {
	return "Ms.";
    } else if (word === "dr") {
	return "Dr.";
    } else if (word === "rev") {
	return "Rev.";
    } else if (word === "fr") {
	return "Fr.";
    } else {
	return false;
    }
};

//  detect and format common suffixes
parse_names.vendor.is_suffix = function (word) {
    word = parse_names.vendor.removeIgnoredChars(word).toLowerCase();
    // these are some common suffixes - what am I missing?
    var suffixArray = [
	'I','II','III','IV','V','Senior','Junior','Jr','Sr','PhD','APR','RPh','PE','MD','MA','DMD','CME',
	"BVM","CFRE","CLU","CPA","CSC","CSJ","DC","DD","DDS","DO","DVM","EdD","Esq",
	"JD","LLD","OD","OSB","PC","Ret","RGS","RN","RNC","SHCJ","SJ","SNJM","SSMO",
	"USA","USAF","USAFR","USAR","USCG","USMC","USMCR","USN","USNR"
    ];

    var suffixIndex = suffixArray.map(function(suffix){
	return suffix.toLowerCase();
    }).indexOf(word);

    if(suffixIndex >= 0) {
	return suffixArray[suffixIndex];
    } else {
	return false;
    }
};

// split full names into the following parts:
// - prefix / salutation  (Mr., Mrs., etc)
// - given name / first name
// - middle initials
// - surname / last name
// - suffix (II, Phd, Jr, etc)
parse_names.vendor.parse = function (fullastName) {
    fullastName = fullastName.trim();
    var nameParts = [];
    var lastName = "";
    var firstName = "";
    var initials = "";
    var word = null;
    var j = 0;
    var i = 0;
    // split into words
    // completely ignore any words in parentheses
    nameParts = fullastName.split(" ").filter(function(namePart){
	return (namePart.indexOf("(") === -1);
    });
    var numWords = nameParts.length;
    // is the first word a title? (Mr. Mrs, etc)
    var salutation = parse_names.vendor.is_salutation(nameParts[0]);
    var suffix = parse_names.vendor.is_suffix(nameParts[numWords - 1]);
    // set the range for the middle part of the name (trim prefixes & suffixes)
    var start = (salutation) ? 1 : 0;
    var end = (suffix) ? numWords - 1 : numWords;
    word = nameParts[start];
    // if we start off with an initial, we'll call it the first name
    if (parse_names.vendor.is_initial(word)) {
	// if so, do a look-ahead to see if they go by their middle name
	// for ex: "R. Jason Smith" => "Jason Smith" & "R." is stored as an initial
	// but "R. J. Smith" => "R. Smith" and "J." is stored as an initial
	if (parse_names.vendor.is_initial(nameParts[start + 1])) {
	    firstName += " " + word.toUpperCase();
	} else {
	    initials += " " + word.toUpperCase();
	}
    } else {
	firstName += " " + parse_names.vendor.fix_case(word);
    }
    // concat the first name
    for (i=start + 1; i<(end - 1); i++) {
	word = nameParts[i];
	// move on to parsing the last name if we find an indicator of a compound last name (Von, Van, etc)
	// we do not check earlier to allow for rare cases where an indicator is actually the first name (like "Von Fabella")
	if (parse_names.vendor.is_compound_lastName(word)) {
	    break;
	}
	if (parse_names.vendor.is_initial(word)) {
	    initials += " " + word.toUpperCase();
	} else {
	    firstName += " " + parse_names.vendor.fix_case(word);
	}
    }
    // check that we have more than 1 word in our string
    if ((end - start) > 1) {
	// concat the last name
	for (j=i; j<end; j++) {
	    lastName += " " + parse_names.vendor.fix_case(nameParts[j]);
	}
    }
    // return the various parts in an array
    return {
	"salutation": salutation || "",
	"firstName": firstName.trim(),
	"initials": initials.trim(),
	"lastName": lastName.trim(),
	"suffix": suffix || ""
    };
};

@@ -1002,32 +1002,65 @@
 nction (word) %7B%0A
+    if (!word) %7B return false; %7D%0A
     word = parse

Fix parse("a")