package flare.query
{
    import flash.utils.ByteArray;
    
    /**
     * Utility class providing functions for manipulating <code>String</code>
     * objects. These functions are intended for use by the
     * <code>Fn</code> operator.
     */
    public class StringUtil
    {
        public static function concat(...args):String
        {
            return args.join("");
        }
        
        public static function concat_ws(sep:String, ...args):String
        {
            return args.join(sep);
        }
        
        public static function format(x:Number, d:int):String
        {
            return x.toFixed(d);
        }
        
        public static function insert(s:String, pos:int, len:int, ns:String):String
        {
            var slen:int = s.length;
            if (pos < 0 || pos > slen)
                return s;
            if (len < 0 || len > slen)
                return s.substring(0,pos)+ns;
            else
                return s.substring(0,pos)+ns+s.substring(len);
        }
        
        public static function left(s:String, len:int):String
        {
            return s.substring(0, len);
        }
        
        public static function length(s:String):int
        {
            return s.length;
        }
        
        public static function lower(s:String):String
        {
            return s.toLowerCase();
        }
        
        public static function lpad(s:String, len:int, pad:String):String
        {
            var strlen:int = s.length;
            if (strlen > len) {
                return s.substring(0,len);
            }
            else if (strlen == len) {
                return s;
            }
            else {
                var b:ByteArray = new ByteArray();
                var padlen:int = pad.length;
                var diff:int = len - strlen;

                for (var i:int=0; i<diff; i+=padlen)
                    b.writeUTFBytes(pad);
                if (b.length > diff)
                    b.position = diff;
                b.writeUTFBytes(s);
                b.position = 0;
                return b.readUTFBytes(b.length);
            }
        }
        
        public static function position(sub:String, s:String):int
        {
            return s.indexOf(sub);
        }
        
        public static function reverse(s:String):String
        {
            var b:ByteArray = new ByteArray();
            for (var i:int=s.length-1; --i>=0; ) {
                b.writeUTFBytes(s.charAt(i));
            }
            b.position = 0;
            return b.readUTFBytes(b.length);
        }
        
        public static function repeat(s:String, count:int):String
        {
            var b:ByteArray = new ByteArray();
            for (var i:int=0; i<count; ++i) {
                b.writeUTFBytes(s);
            }
            b.position = 0;
            return b.readUTFBytes(b.length);
        }
        
        public static function replace(s:String, orig:String, replace:String):String
        {
            return s.replace(new RegExp(orig, "g"), replace);
        }
        
        public static function right(s:String, len:int):String
        {
            return s.substring(s.length-len);
        }
        
        public static function rpad(s:String, len:int, pad:String):String
        {
            var strlen:int = s.length;
            if (strlen > len) {
                return s.substring(0,len);
            }
            else if (strlen == len) {
                return s;
            }
            else {
                var b:ByteArray = new ByteArray();
                b.writeUTFBytes(s);
                var padlen:int = pad.length;
                var diff:int = len - strlen;

                for (var i:int=0; i<diff; i+=padlen)
                    b.writeUTFBytes(pad);
                b.position = 0;
                return b.readUTFBytes(len);
            }
        }
        
        public static function space(len:int):String
        {
            return repeat(" ", len);
        }
        
        public static function substring(s:String, pos:int, len:int=-1):String
        {
            return len<0 ? s.substr(pos) : s.substr(pos, len);
        }
        
        public static function upper(s:String):String
        {
            return s.toUpperCase();
        }
        
        public static function startsWith(s:String, p:String):Boolean
        {
            return s.indexOf(p) == 0;
        }
        
        public static function endsWith(s:String, p:String):Boolean
        {
            var diff:int = s.length - p.length;
            if (diff < 0) return false;
            for (var i:uint=0; i<p.length; ++i) {
                if (s.charCodeAt(i+diff) != p.charCodeAt(i))
                    return false;
            }
            return true;
        }

    } // end of class StringUtil
}