/**
 * @license
 * Patterns @VERSION@ parser - argument parser
 *
 * Copyright 2012 Simplon B.V.
 * Copyright 2012 Florian Friesdorf
 */
define([
    'require',
    '../logging'
], function(require) {
    var log = require('../logging').getLogger('parser');

    function ArgumentParser(spec) {
        this.params = [];
        this.defaults = {};
        if (spec) this.add_spec(spec);
    }

    ArgumentParser.prototype = {
        named_param_pattern: /^\s*([a-zA-Z0-9]+)\s*:(.*)/,

        add_argument: function(name, default_value) {
            if (default_value === undefined) default_value = "";
            this.params.push(name);
            this.defaults[name] = default_value;
        },

        add_spec: function(spec) {
            var parts = spec.split(';'),
                parser = this;
            for (var i=0, part; i<parts.length; i++) {
                part = parts[i].trim();
                var match = part.match(parser.named_param_pattern);
                if (match) {
                    parser.add_argument(match[1], match[2].trim());
                } else {
                    parser.add_argument(part);
                }
            }
        },

        parse: function(parameter, defaults) {
            defaults = defaults || {};
            if (!parameter) {
                return defaults;
            }
            if (parameter.match(/&&/)) {
                return parameter.split(/\s*&&\s*/).map(function(parameter) {
                    return this.parse(parameter, defaults);
                }, this);
            }

            var parts = parameter.split(";"),
                opts = {},
                part, matches, i, name;

            // Popuplate options with default values
            for (i=0; i<this.params.length; i++) {
                name = this.params[i];
                opts[name] = defaults[name] || this.defaults[name];
            }

            // Grab all positional parameters
            i=-1;
            while (parts.length) {
                i++;
                if (i>=this.params.length) {
                    break;
                }
                part = parts.shift().trim();
                if (!part)
                    continue;
                if (this.named_param_pattern.test(part)) {
                    parts.unshift(part);
                    break;
                }
                opts[this.params[i]] = part.trim();
            }

            // Handle all named parameters
            for (i=0; i<parts.length; i++) {
                matches = parts[i].match(this.named_param_pattern);
                if (!matches) {
                    log.warn("Positional parameters not allowed after named parameters");
                    break;
                }
                if (this.defaults[matches[1]] === undefined) {
                    log.warn("Unknown named parameter " + matches[1]);
                    continue;
                }
                opts[matches[1]] = matches[2].trim();
            }

            for (name in opts) {
                if (opts[name].slice(0,1) === "$") {
                    opts[name] = opts[opts[name].slice(1)];
                }
            }

            return opts;
        }
    };

    return ArgumentParser;

});

// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab

@@ -359,16 +359,28 @@
 f (spec)
+%0A           
  this.ad
@@ -591,16 +591,32 @@
 defined)
+%0A               
  default
@@ -628,10 +628,12 @@
 e = 
-%22%22
+null
 ;%0A  
@@ -1261,47 +1261,8 @@
 ) %7B%0A
-            defaults = defaults %7C%7C %7B%7D;%0A
     
@@ -1273,17 +1273,16 @@
     if (
-!
 paramete
@@ -1286,75 +1286,12 @@
 eter
-) %7B%0A                return defaults;%0A            %7D%0A            if (
+ && 
 para
@@ -1509,151 +1509,190 @@
 var 
+o
 p
-ar
 ts = 
-parameter.split(%22;%22),%0A                opts = %7B%7D,%0A                part, matches, i, name;%0A%0A            // Popuplate options with
+%7B%7D, i, name;%0A%0A            // Copy all defaults to opts.%0A            if (typeof defaults === %22object%22)%0A                for (i in defaults)%0A                    opts%5Bi%5D =
  default
  val
@@ -1691,15 +1691,13 @@
 ault
- values
+s%5Bi%5D;
 %0A   
@@ -1715,80 +1715,83 @@
 r (i
-=0; i%3Cthis.params.length; i++) %7B%0A                name = this.param
+ in this.defaults)%0A                opts%5Bi%5D = opts%5Bi%5D %7C%7C this.default
 s%5Bi%5D;%0A
+%0A
     
@@ -1802,77 +1802,130 @@
     
-    opts%5Bname%5D = defaults%5Bname%5D %7C%7C this.defaults%5Bname%5D;%0A            %7D
+if (!parameter)%0A                return opts;%0A%0A            var parts = parameter.split(%22;%22),%0A                part, matches;
 %0A%0A  
@@ -3073,16 +3073,48 @@
     if (
+typeof opts%5Bname%5D===%22string%22 && 
 opts%5Bnam
@@ -3135,18 +3135,16 @@
 === %22$%22)
- %7B
 %0A       
@@ -3196,34 +3196,16 @@
 ce(1)%5D;%0A
-                %7D%0A
         

Fix parser test errors.