/**
 * END USER LICENSE AGREEMENT (“EULA”)
 *
 * READ THIS AGREEMENT CAREFULLY (date: 9/13/2011):
 * http://www.akiban.com/licensing/20110913
 *
 * BY INSTALLING OR USING ALL OR ANY PORTION OF THE SOFTWARE, YOU ARE ACCEPTING
 * ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU AGREE THAT THIS
 * AGREEMENT IS ENFORCEABLE LIKE ANY WRITTEN AGREEMENT SIGNED BY YOU.
 *
 * IF YOU HAVE PAID A LICENSE FEE FOR USE OF THE SOFTWARE AND DO NOT AGREE TO
 * THESE TERMS, YOU MAY RETURN THE SOFTWARE FOR A FULL REFUND PROVIDED YOU (A) DO
 * NOT USE THE SOFTWARE AND (B) RETURN THE SOFTWARE WITHIN THIRTY (30) DAYS OF
 * YOUR INITIAL PURCHASE.
 *
 * IF YOU WISH TO USE THE SOFTWARE AS AN EMPLOYEE, CONTRACTOR, OR AGENT OF A
 * CORPORATION, PARTNERSHIP OR SIMILAR ENTITY, THEN YOU MUST BE AUTHORIZED TO SIGN
 * FOR AND BIND THE ENTITY IN ORDER TO ACCEPT THE TERMS OF THIS AGREEMENT. THE
 * LICENSES GRANTED UNDER THIS AGREEMENT ARE EXPRESSLY CONDITIONED UPON ACCEPTANCE
 * BY SUCH AUTHORIZED PERSONNEL.
 *
 * IF YOU HAVE ENTERED INTO A SEPARATE WRITTEN LICENSE AGREEMENT WITH AKIBAN FOR
 * USE OF THE SOFTWARE, THE TERMS AND CONDITIONS OF SUCH OTHER AGREEMENT SHALL
 * PREVAIL OVER ANY CONFLICTING TERMS OR CONDITIONS IN THIS AGREEMENT.
 */

package com.akiban.server.types3.mcompat.mfuncs;

import com.akiban.server.types3.LazyList;
import com.akiban.server.types3.TExecutionContext;
import com.akiban.server.types3.TOverloadResult;
import com.akiban.server.types3.mcompat.mtypes.MNumeric;
import com.akiban.server.types3.mcompat.mtypes.MString;
import com.akiban.server.types3.pvalue.PValueSource;
import com.akiban.server.types3.pvalue.PValueTarget;
import com.akiban.server.types3.texpressions.TInputSetBuilder;
import com.akiban.server.types3.texpressions.TOverloadBase;

public class MChar extends TOverloadBase
{

    @Override
    protected void buildInputSets(TInputSetBuilder builder)
    {
        builder.vararg(MNumeric.BIGINT);
    }

    @Override
    protected void doEvaluate(TExecutionContext context, LazyList<? extends PValueSource> inputs, PValueTarget output)
    {
        // length of the varbin string
        int length = 0;
        
        for(PValueSource num : inputs)
            length += Math.log(num.getInt64()) / DIV + 1;
        
        byte ret 
    }

    @Override
    public String overloadName()
    {
        return "CHAR";
    }

    @Override
    public TOverloadResult resultType()
    {
        // TODO: calculate the length of varbinary
        return TOverloadResult.fixed(MString.VARBINARY.instance());
    }
    
    private static final long MASK = 0xff;
    private static final double DIV = Math.log(256);
    
    /**
     * TODO: byte is too small ==> causes overflow, but this is what underlies VARBINARY
     * @param num
     * @return 
     */
    static byte[] parse(long num)
    {
        byte ret[] = new byte[(int)(Math.log(num) / DIV) + 1];
        
        int n = ret.length -1;
        
        while (num > 0)
        {
            ret[n] = (byte)(num & MASK);
            num = num >> 8;
            --n;
        }
        return ret;
    }
}

@@ -1370,16 +1370,59 @@
 ontext;%0A
+import com.akiban.server.types3.TOverload;%0A
 import c
@@ -1849,16 +1849,106 @@
 Base%0A%7B%0A%0A
+    public static final TOverload INSTANCE = new MChar();%0A    %0A    private MChar()%7B%7D%0A    %0A
     @Ove
@@ -2270,32 +2270,145 @@
 h = 0;%0A        %0A
+        // legnth of each sub string%0A        int lengths%5B%5D = new int%5Binputs.size()%5D;%0A        %0A        int n = 0;%0A
         for(PVal
@@ -2452,16 +2452,35 @@
 ngth += 
+lengths%5Bn%5D = (int)(
 Math.log
@@ -2505,16 +2505,17 @@
  DIV + 1
+)
 ;%0A      
@@ -2533,17 +2533,221 @@
 byte ret
- 
+%5B%5D = new byte%5Blength%5D;%0A        %0A        int pos = 0;%0A        for (n = 0; n %3C lengths.length; ++n)%0A            parse(inputs.get(n).getInt64(), ret, pos += lengths%5Bn%5D);%0A        %0A        output.putBytes(ret);
 %0A    %7D%0A%0A
@@ -3246,16 +3246,8 @@
   * 
-@return 
 %0A   
@@ -3266,14 +3266,12 @@
 tic 
-byte%5B%5D
+void
  par
@@ -3285,87 +3285,38 @@
  num
-)%0A    %7B%0A       
+,
  byte
+%5B%5D
  ret
-%5B%5D = new byte%5B(int)(Math.log(num) / DIV) + 1%5D;
+, int limit)
 %0A    
-    
+%7B
 %0A   
@@ -3332,18 +3332,13 @@
 n = 
-ret.length
+limit
  -1;
@@ -3398,16 +3398,18 @@
    ret%5Bn
+--
 %5D = (byt
@@ -3439,21 +3439,16 @@
     
- num =
  num %3E%3E
+=
  8;%0A
@@ -3459,46 +3459,9 @@
     
-    --n;%0A        %7D%0A        return ret;
+%7D
 %0A   

add CHAR function