// +-----------------------------------------------------------------------+
// | Copyright (c) 2003-2004 Mira Software, Inc.                           |
// | All rights reserved.                                                  |
// |                                                                       |
// | Redistribution and use in source and binary forms, with or without    |
// | modification, are permitted provided that the following conditions    |
// | are met:                                                              |
// |                                                                       |
// | o Redistributions of source code must retain the above copyright      |
// |   notice, this list of conditions and the following disclaimer.       |
// | o Redistributions in binary form must reproduce the above copyright   |
// |   notice, this list of conditions and the following disclaimer in the |
// |   documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote      |
// |   products derived from this software without specific prior written  |
// |   permission.                                                         |
// |                                                                       |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
// |                                                                       |
// +-----------------------------------------------------------------------+
// | Author: Andrey Klimoff - miramax@e-mail.ru - http://www.miramax.da.ru |
// +-----------------------------------------------------------------------+
//
// $Id: value.js, Version 1.00 2005/11/02 15:45:00 Mira Software, Inc. Exp $
//
// This software required JavaScript Version 1.2 (Microsoft Internet
// Explorer 4.0, Netscape Navigator 4.0, Mozilla 1.1, Mac Internet
// Explorer 4, Opera 5.1)

var Domains = new String("aero|arpa|biz|com|coop|edu|info|int|museum|name|net|org|pro|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|ws|ye|yu|za|zm|zr|zw");

function Value(expression)
    {
    var Instance;
    if (expression) Instance = new String(expression);
    else Instance = new String("");
    Instance.asString      = asString;
    Instance.charAt        = charAt;
    Instance.inRange       = inRange;
    Instance.isAlpha       = isAlpha;
    Instance.isCombining   = isCombining;
    Instance.isEmail       = isEmail;
    Instance.isEmpty       = isEmpty;
    Instance.isEqual       = isEqual;
    Instance.isFloat       = isFloat;
    Instance.isInteger     = isInteger;
    Instance.isNumeric     = isNumeric;
    Instance.isPhoneNumber = isPhoneNumber;
    Instance.isURL         = isURL;
    Instance.remove        = remove;
    Instance.toLowerCase   = toLowerCase;
    Instance.toUpperCase   = toUpperCase;
    Instance.split         = split;
    Instance.subvalue      = subvalue;
    return Instance;
    }

function asString()
    {
    return String(this);
    }

function charAt(index)
    {
    return Value(this.asString().charAt(index));
    }

function inRange(countA, countB)
    {
    if (!countA) countA = 0; else countA = parseInt(countA);
    if (!countB) countB = 0; else countB = parseInt(countB);
    if (countA < countB) return !(this.length < countA || this.length > countB);
    else !(this.length < countB || this.length > countA);
    }

function isAlpha()
    {
    return RegExp("^\\w+$").test(this);
    }

function isCombining(combiningString)
    {
    if (!combiningString) return RegExp("^[\\x21-\\x7E]+$").test(this);
    combiningString = new String(combiningString);
    if (!this.length) return false;
    for (i = 0; i < this.length; i++) if (combiningString.indexOf(this.charAt(i)) == -1) return false;
    return true;
    }

function isEmail()
    {
    return RegExp("^[-\\w]+(\\.[-\\w]+)*@[-\\w]+(\\.[-\\w]+)*\\.(" + Domains + ")$").test(this.toLowerCase());
    }

function isEmpty()
    {
    return RegExp("^$").test(this);
    }

function isEqual(regularExpression)
    {
    if (!regularExpression) return false;
    return regularExpression.test(this);
    }

function isFloat()
    {
    return RegExp("^[+-]?(0|([1-9]\\d*))(\\.\\d+)?$").test(this);
    }

function isInteger()
    {
    return RegExp("^[+-]?[1-9]\\d*$").test(this);
    }

function isNumeric()
    {
    return RegExp("^\\d+$").test(this);
    }

function isPhoneNumber()
    {
    for (i = 0, digCount = 0; i < this.length; i++) if (this.charAt(i) >= '0' && this.charAt(i) <= '9') digCount++;
    if (digCount < 8) return RegExp("^(\\d-?){4,6}\\d$").test(this);
    else if (digCount == 11) return RegExp("^\\+\\d{1,3} ?(\\(\\d{1,5}\\)|\\d{1,5}) ?(\\d-?){3,6}\\d$").test(this);
    else return false;
    }

function isURL(type)
    {
    if (!type) type = "http";
    else type = type.toLowerCase();
    var xdomain = Domains;
    var xalpha = "[-\\w]+";
    var xres   = "[-\\w\\+\\*@%]";
    var spec   = "[-\\w\\+\\.\\$\\*\\\\(\\)\\?,'!;&=]";
    var xchar  = "[^/\\\\:\\*?\"<>\\|\\.]+";
    var xattr  = "(subject|cc|bcc)=(&[^&]*|[^&]+)";
    var ippart = "(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])";
    var domain = "\\.(" + xdomain + ")";
    var upas   = "(" + spec + "+(:" + spec + "+)?@)?";
    var port   = "(:[1-9]\\d{4})?";
    var ip     = ippart + "(\\." + ippart + "){3}";
    var qpart  = xres   + "+="   + xres   + "*";
    var frag   = xalpha + "(\\." + xalpha + ")*";
    var file   = xchar  + "(\\." + xchar  + ")*";
    var path   = file   + "(/"   + file   + ")*";
    var query  = "\\?("  + qpart  + "(&"   + qpart  + ")*)?";
    var attrib = "\\?("  + xattr  + "(&"   + xattr + ")*)?";
    var anchor = "#("    + xres   + "+)?";
    var host   = "("     + frag   + domain + "|"   + ip + ")";
    var http   = "^https?://" + upas + host + port + "(/(" + path + "(" + query + ")?(" + anchor + ")?)?)?$";
    var ftp    = "^ftp://"    + upas + host + port + "(/(" + path + ")?)?$";
    var mailto = "^mailto: *" + frag + "@" + host + "(" + attrib + ")?$";
    switch (type)
        {
        case "http"   : return RegExp(http).test(this.toLowerCase());
        case "ftp"    : return RegExp(ftp).test(this.toLowerCase());
        case "mailto" : return RegExp(mailto).test(this.toLowerCase());
        default       : return false;
        }
    }

function remove(valueToRemove)
    {
    var newObject = this;
    while ((index = newObject.indexOf(valueToRemove)) != -1)
        {
        newObject = newObject.substring(0,index) + newObject.substring(index + valueToRemove.length, newObject.length);
        }
    return Value(newObject);
    }

function toLowerCase()
    {
    return Value(this.asString().toLowerCase());
    }

function toUpperCase()
    {
    return Value(this.asString().toUpperCase());
    }

function split(separator)
    {
    var newArray = this.asString().split(separator);
    for (i = 0; i < newArray.length; i++) newArray[i] = new Value(newArray[i]);
    return newArray;
    }

function subvalue(indexA, indexB)
    {
    return Value(this.asString().substring(indexA,indexB));
    }

