//parsing tag input
var ParseTags = {
    /**
	 * Quotes a single tag
	 */
    quoteTag: function (tag) {
        tag = tag.replace(/"/g, "'").replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '');
        if (tag.match(/\s+|,/)) {
            tag = '"' + tag + '"';
        }
        return tag;
    },
	
    //input text => tag array
    //tags input: comma or space separated. double quotes allowed
    //merge quoted if necessary
    //TEST: 'a b c' => ['a', 'b', 'c']
    //TEST: 'a,b,c' => ['a', 'b', 'c']
    //TEST: 'a b,c' => ['a', 'b', 'c']
    //TEST: 'a "b,c"' => ['a', 'bc']
    //TEST: '"a b" c' => ['a b', 'c']
    //TEST: '"a b c' => ['abc']
    parseTags: function (strTags, validate) {
        var stack = [], tags = [];
        var begin_delimiter = false;
		
        for (var i = 0, len = strTags.length, c; c = strTags.charAt(i), i < len; i++) {
            if (c == '"') {
                if (!begin_delimiter) 
                    begin_delimiter = true;
                else {
                    begin_delimiter = false;
                    clearStack();
                }
            } else {
                if (begin_delimiter) {
                    stack.push(c);
                } else {
                    if (/\s/.test(c) || c == ',') 
                        clearStack();
                    else {
                        stack.push(c);
                    }
                }
            }
        }
		
        clearStack(); //if there is unclosed delimiter
		
        if (validate) {
            tags.compact().map(function(t){
                t.strip();
            }).uniq();
        }
        return tags;
		
        function clearStack() {
            if (stack.length > 0) {
                tags.push(stack.join(''));
                stack.length = 0;
            }
        }
		
    },
	
    /**
	 * tag array => input text
	 */
    unparseTags: function (tagArray, joinBy) {
        return tagArray.map(function(t) {
            return ParseTags.quoteTag(t)
        }).join(joinBy || ' ');
    }
};