package org.maachang.mimdb.core ;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.maachang.mimdb.core.impl.EqualsNoList;

/**
 * 結果行要素実装.
 * 
 * @version 2013/10/10
 * @author masahito suzuki
 * @since MasterInMemDB 1.00
 */
@SuppressWarnings("unchecked")
class ResultRowImpl extends MimdbResultRow {
    
    /** 親オブジェクト. **/
    ResultImpl parent ;
    
    /**
     * コンストラクタ.
     */
    public ResultRowImpl() {}
    
    /**
     * コンストラクタ.
     * @param parent 親オブジェクトを設定します.
     */
    public ResultRowImpl( ResultImpl parent ) {
        create( parent ) ;
    }
    
    /**
     * 情報生成.
     * @param parent 親オブジェクトを設定します.
     */
    public void create( ResultImpl parent ) {
        this.parent = parent ;
    }
    
    /**
     * 情報クリア.
     */
    public void clear() {
        parent = null ;
    }
    
    /**
     * 更新IDを取得.
     * @return long 更新IDが返却されます.
     */
    public long getDbId() {
        return parent.dbId ;
    }
    
    /**
     * テーブル名の取得.
     * @return String テーブル名が返却されます.
     */
    public String getName() {
        return parent.table.name ;
    }
    
    /**
     * テーブル情報の取得.
     * @return BaseTable テーブル情報が返却されます.
     */
    public BaseTable getTable() {
        return parent.table ;
    }
    
    /**
     * 対象の行番号を取得.
     * @return int 行番号が返却されます.
     */
    public int getLineNo() {
        return parent.pointer.cursor ;
    }
    
    /** viewColumnListを取得. **/
    private final EqualsNoList viewColumnList() {
        return ((MetaDataImpl)parent.meta).viewColumnList ;
    }
    
    /** 現在のsrcを取得. **/
    private final MimdbRow src() {
        return parent.pointer.src[ parent.pointer.get( parent.pointer.cursor ) ] ;
    }
    
    /**
     * カラム項番で情報を取得.
     * @param n 対象の項番を設定します.
     * @return Object 情報が返却されます.
     */
    public Object getValue( int n ) {
        
        // 表示カラム条件が設定されている場合.
        EqualsNoList viewColumnList ;
        if( ( viewColumnList = viewColumnList() ) != null ) {
            n = viewColumnList.src( n ) ;
        }
        return src().getValue( n ) ;
    }
    
    /**
     * 指定カラム名に対する項番を取得.
     */
    private final int getColumnNameByNo( String name ) {
        
        // 表示カラム条件が設定されている場合.
        EqualsNoList viewColumnList ;
        if( ( viewColumnList = viewColumnList() ) != null ) {
            int ret = parent.table.getColumnNameByNo( name ) ;
            if( !viewColumnList.equals( ret ) ) {
                return -1 ;
            }
            return ret ;
        }
        return parent.table.getColumnNameByNo( name ) ;
    }
    
    /*********************** 以下 Map定義 ***********************/
    
    public void putAll(Map toMerge) {
        // 処理なし.
    }
    public boolean containsValue(Object value) {
        // 表示カラム条件が設定されている場合.
        EqualsNoList viewColumnList ;
        if( ( viewColumnList = viewColumnList() ) != null ) {
            int[] vc = viewColumnList.arrays() ;
            int len = viewColumnList.size() ;
            Object[] values = src().getValues() ;
            if( value == null ) {
                for( int i = 0 ; i < len ; i ++ ) {
                    if( values[ vc[ i ] ] == null ) {
                        return true ;
                    }
                }
            }
            else {
                for( int i = 0 ; i < len ; i ++ ) {
                    if( value.equals( values[ vc[ i ] ] ) ) {
                        return true ;
                    }
                }
            }
        }
        else {
            int len = parent.table.columnLength ;
            Object[] values = src().getValues() ;
            if( value == null ) {
                for( int i = 0 ; i < len ; i ++ ) {
                    if( values[ i ] == null ) {
                        return true ;
                    }
                }
            }
            else {
                for( int i = 0 ; i < len ; i ++ ) {
                    if( value.equals( values[ i ] ) ) {
                        return true ;
                    }
                }
            }
        }
        return false ;
    }
    public Set entrySet() {
        // 処理なし.
        return null ;
    }
    public Collection values() {
        
        // 表示カラム条件が設定されている場合.
        EqualsNoList viewColumnList ;
        if( ( viewColumnList = viewColumnList() ) != null ) {
            int[] vc = viewColumnList.arrays() ;
            int len = viewColumnList.size() ;
            List<Object> ret = new ArrayList<Object>( len ) ;
            Object[] values = src().getValues() ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( values[ vc[ i ] ] ) ;
            }
            return ret ;
        }
        else {
            int len = parent.table.columnLength ;
            List<Object> ret = new ArrayList<Object>( len ) ;
            Object[] values = src().getValues() ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( values[ i ] ) ;
            }
            return ret ;
        }
    }
    public Object put(Object name, Object value) {
        // 処理なし.
        return null ;
    }
    public boolean containsKey(Object key) {
        
        // 表示カラム条件が設定されている場合.
        EqualsNoList viewColumnList ;
        if( ( viewColumnList = viewColumnList() ) != null ) {
            if( key instanceof String ) {
                return getColumnNameByNo( (String)key ) != -1 ;
            }
            else if( key instanceof Number ) {
                int n = ((Number)key).intValue() ;
                return ( n >= 0 && n < viewColumnList.size() ) ;
            }
        }
        else {
            if( key instanceof String ) {
                return parent.table.columnsMap.containsKey( ((String)key).trim().toLowerCase() ) ;
            }
            else if( key instanceof Number ) {
                int n = ((Number)key).intValue() ;
                return ( n >= 0 && n < parent.table.columnLength ) ;
            }
        }
        return false ;
    }
    public Object get(Object key) {
        // 表示カラム条件が設定されている場合.
        EqualsNoList viewColumnList ;
        if( ( viewColumnList = viewColumnList() ) != null ) {
            if( key instanceof String ) {
                int n = getColumnNameByNo( (String)key ) ;
                if( n != -1 ) {
                    return src().getValue( n ) ;
                }
                return null ;
            }
            else if( key instanceof Number ) {
                int n = ((Number)key).intValue() ;
                if( n >= 0 && n < viewColumnList.size() ) {
                    return src().getValue( viewColumnList.src( n ) ) ;
                }
                return null ;
            }
        }
        else {
            if( key instanceof String ) {
                Integer n = parent.table.columnsMap.get( ((String)key).trim().toLowerCase() ) ;
                if( n == null ) {
                    return null ;
                }
                return src().getValue( n ) ;
            }
            else if( key instanceof Number ) {
                int n = ((Number)key).intValue() ;
                if( n >= 0 && n < parent.table.columnLength ) {
                    return src().getValue( n ) ;
                }
                return null ;
            }
        }
        return null ;
    }
    public Object remove(Object key) {
        // 処理なし.
        return null ;
    }
    public boolean isEmpty() {
        return false ;
    }
    public Set keySet() {
        Set<Object> ret = new HashSet<Object>() ;
        getAllKey( ret ) ;
        return ret ;
    }
    public int size() {
        // 表示カラム条件が設定されている場合.
        EqualsNoList viewColumnList ;
        if( ( viewColumnList = viewColumnList() ) != null ) {
            return viewColumnList.size() ;
        }
        else {
            return parent.table.columnLength ;
        }
    }
    public void getAllKey( Set<Object> set ) {
        // 表示カラム条件が設定されている場合.
        EqualsNoList viewColumnList ;
        if( ( viewColumnList = viewColumnList() ) != null ) {
            int[] vc = viewColumnList.arrays() ;
            int len = viewColumnList.size() ;
            String[] key = parent.table.columns ;
            for( int i = 0 ; i < len ; i ++ ) {
                set.add( key[ vc[ i ] ] ) ;
            }
        }
        else {
            int len = parent.table.columnLength ;
            String[] key = parent.table.columns ;
            for( int i = 0 ; i < len ; i ++ ) {
                set.add( key[ i ] ) ;
            }
        }
    }
    public void getAllValues( Set<Object> set ) {
        // 表示カラム条件が設定されている場合.
        EqualsNoList viewColumnList ;
        if( ( viewColumnList = viewColumnList() ) != null ) {
            int[] vc = viewColumnList.arrays() ;
            int len = viewColumnList.size() ;
            Object[] values = src().getValues() ;
            for( int i = 0 ; i < len ; i ++ ) {
                set.add( values[ vc[ i ] ] ) ;
            }
        }
        else {
            int len = parent.table.columnLength ;
            Object[] values = src().getValues() ;
            for( int i = 0 ; i < len ; i ++ ) {
                set.add( values[ i ] ) ;
            }
        }
    }
    public String toString() {
        // 表示カラム条件が設定されている場合.
        EqualsNoList viewColumnList ;
        if( ( viewColumnList = viewColumnList() ) != null ) {
            int[] vc = viewColumnList.arrays() ;
            int len = viewColumnList.size() ;
            StringBuilder buf = new StringBuilder() ;
            String[] key = parent.table.columns ;
            Object[] values = src().getValues() ;
            buf.append( "{" ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                if( i != 0 ) {
                    buf.append( "," ) ;
                }
                if( values[ vc[ i ] ] instanceof String ) {
                    buf.append( key[ vc[ i ] ] ).append( ":\"" ).append( values[ vc[ i ] ] ).append( "\"" ) ;
                }
                else {
                    buf.append( key[ vc[ i ] ] ).append( ":" ).append( values[ vc[ i ] ] ) ;
                }
            }
            return buf.append( "}" ).toString() ;
        }
        else {
            int len = parent.table.columnLength ;
            StringBuilder buf = new StringBuilder() ;
            String[] key = parent.table.columns ;
            Object[] values = src().getValues() ;
            buf.append( "{" ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                if( i != 0 ) {
                    buf.append( "," ) ;
                }
                if( values[ i ] instanceof String ) {
                    buf.append( key[ i ] ).append( ":\"" ).append( values[ i ] ).append( "\"" ) ;
                }
                else {
                    buf.append( key[ i ] ).append( ":" ).append( values[ i ] ) ;
                }
            }
            return buf.append( "}" ).toString() ;
        }
    }
    
}

