package org.maachang.proxy.engine.mobile.emoji ;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;

import org.maachang.proxy.engine.mobile.carrier.MobileData;
import org.maachang.proxy.engine.net.RequestInfo;
import org.maachang.proxy.engine.net.ResponseInfo;
import org.maachang.util.AnalysisUtil;
import org.maachang.util.StringUtil;

/**
 * レスポンス情報を絵文字変換.
 *
 * @version 2008/04/08
 * @author  masahito suzuki
 * @since   MaachangProxy 1.01
 */
public class ConvertEmoji {
    
    private static final byte[] START_CD = "[".getBytes() ;
    private static final byte[] END_CD = "]".getBytes() ;
    private static final String EMOJI_SIMBOL = "emoji" ;
    private static final String INPUT_SIMBOL = "input" ;
    
    /**
     * レスポンス情報を絵文字変換します.
     * @param res 対象のレスポンス情報を設定します.
     * @param conf 対象の絵文字コンフィグ情報を設定します.
     * @param data 対象の携帯機種情報を設定します.
     * @return boolean [true]の場合、変換処理が行われました.
     * @exception Exception 例外.
     */
    public static final boolean convert( ResponseInfo res,EmojiConfig conf,MobileData data )
        throws Exception {
    	String carrier = conf.getCarrierName( data ) ;
        // レスポンスが、HTML系でない場合は、処理しない.
        String type = res.getHeader( "Content-Type",0 ) ;
        if( type == null || ( type.indexOf( "text/html" ) <= -1 &&
            type.indexOf( "application/xhtml" ) <= -1 &&
            type.indexOf( "text/xml" ) <= -1 ) ) {
            return false ;
        }
        // 絵文字コード変換.
        ByteArrayOutputStream bo = new ByteArrayOutputStream() ;
        int b = 0 ;
        byte[] body = res.getBody() ;
        for( ;; ) {
            int p = AnalysisUtil.binaryIndexOf( body,START_CD,b ) ;
            if( p <= -1 ) {
                if( body.length - b > 0 ) {
                    bo.write( body,b,body.length - b ) ;
                }
                break ;
            }
            int e = AnalysisUtil.binaryIndexOf( body,END_CD,p ) ;
            if( e <= -1 ) {
                if( body.length - b > 0 ) {
                    bo.write( body,b,body.length - b ) ;
                }
                break ;
            }
            int p2 = AnalysisUtil.binaryIndexOf( body,START_CD,p+1 ) ;
            if( p2 != -1 && e > p2 ) {
                bo.write( body,b,p2 - b ) ;
                b = p2 ;
                continue ;
            }
            bo.write( body,b,p - b ) ;
            byte[] emoji = getEmojiData( conf,data,carrier,body,p,e+1 ) ;
            if( emoji != null ) {
                bo.write( emoji ) ;
            }
            b = e+1 ;
        }
        body = bo.toByteArray() ;
        bo = null ;
        res.setBody( body ) ;
        return true ;
    }
    
    private static final byte[] getEmojiData( EmojiConfig conf,MobileData data,String carrier,byte[] body,int start,int end )
        throws Exception {
        if( start+1 == end ) {
            return null ;
        }
        int len = end - start ;
        byte[] ret = new byte[ len ] ;
        System.arraycopy( body,start,ret,0,len ) ;
        String code = new String( ret,"ISO-8859-1" ) ;
        ArrayList<String> lst = StringUtil.cutString( code,"[]: 　\r\n\t" ) ;
        if( lst == null || lst.size() != 2 ) {
            return ret ;
        }
        String simbol = lst.get( 0 ) ;
        String value = lst.get( 1 ) ;
        lst = null ;
        // 絵文字コンバート.
        if( EMOJI_SIMBOL.equals( simbol.toLowerCase() ) ) {
            byte[] emojiBin = conf.getEmoji( carrier,value ) ; ;
            if( emojiBin == null ) {
                return ret ;
            }
            else {
                return emojiBin ;
            }
        }
        // 入力スタイルコンバート.
        else if( data != null && INPUT_SIMBOL.equals( simbol.toLowerCase() ) ) {
            if( "docomo".equals( carrier ) ) {
                String inKey = "1" ;
                if( "1".equals( value ) ) {
                    inKey = "1" ;
                }
                else if( "2".equals( value ) ) {
                    inKey = "2" ;
                }
                else if( "3".equals( value ) ) {
                    inKey = "3" ;
                }
                else if( "4".equals( value ) ) {
                    inKey = "4" ;
                }
                return new StringBuilder().append( "istyle=\"" ).
                    append( inKey ).append( "\" ").
                    toString().getBytes( "ISO-8859-1" ) ;
            }
            else if( "au".equals( carrier ) ) {
                String inKey = "*M" ;
                if( "1".equals( value ) ) {
                    inKey = "*M" ;
                }
                else if( "2".equals( value ) ) {
                    inKey = "*M" ;
                }
                else if( "3".equals( value ) ) {
                    inKey = "*x" ;
                }
                else if( "4".equals( value ) ) {
                    inKey = "*N" ;
                }
                return new StringBuilder().append( "format=\"" ).
                    append( inKey ).append( "\" " ).
                    toString().getBytes( "ISO-8859-1" ) ;
            }
            else if( "softbank".equals( carrier ) ) {
                String inKey = "hiragana" ;
                if( "1".equals( value ) ) {
                    inKey = "hiragana" ;
                }
                else if( "2".equals( value ) ) {
                    inKey = "hankakukana" ;
                }
                else if( "3".equals( value ) ) {
                    inKey = "alphabet" ;
                }
                else if( "4".equals( value ) ) {
                    inKey = "numeric" ;
                }
                return new StringBuilder().append( "mode=\"" ).
                    append( inKey ).append( "\" " ).
                    toString().getBytes( "ISO-8859-1" ) ;
            }
            return null ;
        }
        return ret ;
    }
    
    /**
     * リクエストBody内容を変換.
     * @param req 対象のリクエスト情報を設定します.
     * @param conf 対象の絵文字コンフィグ情報を設定します.
     * @param data 対象の携帯機種情報を設定します.
     * @exception Exception 例外.
     */
    public static final void convertRequestBody( RequestInfo req,EmojiConfig conf,MobileData data )
        throws Exception {
        if( data != null ) {
        	String carrier = conf.getCarrierName( data ) ;
            conf.convertRequestBody( req,data,carrier ) ;
        }
    }
    
}


