package jp.sourceforge.shovel.taglib;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import jp.sourceforge.shovel.util.HtmlUtil;



import freemarker.template.utility.StringUtil;

public class TruncateTag extends TagSupport
{
    public static final String TO_ENCORDING = "Windows-31J";    // CP932
    static final long serialVersionUID = 1L;
    
    String data;
    String suffix = "...";
    int length = 20;
    boolean contain = false;
    boolean html;

    public String getData()
    {
        return data;
    }
    public void setData( String data )
    {
        this.data = data;
    }
    public int getLength()
    {
        return length;
    }
    public void setLength( int length )
    {
        this.length = length;
    }
    public String getSuffix()
    {
        return suffix;
    }
    public void setSuffix( String suffix )
    {
        this.suffix = suffix;
    }
    public boolean isHtml() {
        return html;
    }
    public void setHtml(boolean html) {
        this.html = html;
    }
    
    public void setContain( boolean contain )
    {
        this.contain = contain;
    }
    private String createTruncateString() throws Exception
    {
        byte[] bytes = this.data.getBytes( TO_ENCORDING );

        if( bytes.length > this.length )
        {
            int length = this.length;
            if( contain )
            {
                length = this.length - this.suffix.length();
            }

            int i = 0;
            boolean fin = false;
            while( true )
            {
                byte b = bytes[i];
                int unsigned;
                unsigned = b & 0xFF;
                if( ( unsigned >= 0x81 && unsigned <= 0x9F ) ||
                    ( unsigned >= 0xE0 && unsigned <= 0xFC ) )
                {
                    i += 2;
                    if( i > length )
                    {
                        i -= 2;
                        fin = true;
                    }
                }
                else
                {
                    i++;
                }
                if( i >= length || fin == true )
                {

                    byte[] newBytes = new byte[i + suffix.length()];
                    System.arraycopy( bytes, 0, newBytes, 0, i );
                    System.arraycopy( suffix.getBytes(), 0, newBytes, i, suffix.length() );
                    return new String( newBytes, TO_ENCORDING );
                }
            }
        }
        else
        {
            return this.data;
        }
    }
    public int doStartTag() throws JspException
    {
        try
        {
            if (this.html) {
                this.data = HtmlUtil.stripTags(this.data);
            }
            String s = this.createTruncateString();
            s = StringUtil.HTMLEnc( s );
            pageContext.getOut().print( s );
        }
        catch( Exception e )
        {
            throw new JspException( e.getMessage() );
        }

        return SKIP_BODY;
    }
    public int doEndTag()
    {
        return EVAL_PAGE;
    }
}
