// interpolate-fancy.js
//
// Copyright (c) 2006 Kyo Nagashima <kyo@hail2u.net>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

var InterpolateFancy = Class.create();

InterpolateFancy.prototype = {
  initialize: function(template) {
    this.template = template.toString();
    this.pattern = {
      variable:  /<(.+?)\s*\/>/,
      defined:   /<\?(.+?)>(.+?)<\/\?>/,
      undefined: /<\?!(.+?)>(.+?)<\/\?>/,
      test:      /<\?(.+?)\s+?(eq|ne|lt|gt|like|unlike)=(['"])(.+?)\3>(.+?)<\/\?>/
    };
  },

  evaluate: function(object) {
    var s = this.template;

    // <?foo eq="123">display if "foo" is equal 123</?>
    // <?foo ne="123">display if "foo" is not equal than 123</?>
    // <?foo lt="123">display if "foo" is less than 123</?>
    // <?foo gt="123">display if "foo" is greater than 123</?>
    // <?foo like="123">display if "foo" includes 123</?>
    // <?foo unlike="123">display if "foo" does not include 123</?>
    s = s.gsub(this.pattern.test, function(match) {
      var var1 = match[1];
      var var2 = match[4];
      var mode = match[2];
      if (
        (mode == 'eq'     && object[var1] == var2.toString())
        ||
        (mode == 'ne'     && object[var1] != var2.toString())
        ||
        (mode == 'lt'     && object[var1] <  parseInt(var2))
        ||
        (mode == 'gt'     && object[var1] >  parseInt(var2))
        ||
        (mode == 'like'   && RegExp(var2).test(object[var1]))
        ||
        (mode == 'unlike' && !RegExp(var2).test(object[var1]))
      ) {
        return match[5];
      } else {
        return '';
      }
    });

    // <?!foo>display if "foo" is not defined</?>
    s = s.gsub(this.pattern.undefined, function(match) {
      return object[match[1]] ? '' : match[2];
    });

    // <?foo>display if "foo" is defined</?>
    s = s.gsub(this.pattern.defined, function(match) {
      return object[match[1]] ? match[2] : '';
    });

    // <foo/> display "foo"
    s = s.gsub(this.pattern.variable, function(match) {
      return object[match[1]] ? object[match[1]].toString() : '';
    });

    return s;
  }
}
