/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package textkeymatcher.ui.model;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.io.IOException;
import org.apache.commons.lang3.StringUtils;
import textkeymatcher.entity.KeyMatchedRowMap;
import textkeymatcher.entity.KeyMatchedRowView;
import textkeymatcher.entity.LineDataList;
import textkeymatcher.io.DocArchive;
import textkeymatcher.service.KeyMatcher;

/**
 * ビューに表示されるテーブルのモデル.<br>
 * @author seraphy
 */
public class DataViewTableModel extends KeyMatchedRowView {
    
    /**
     * プロパティ変更サポート
     */
    private PropertyChangeSupport propCng = new PropertyChangeSupport(this);
    
    /**
     * キーマッチング方法のプロパティ名
     */
    public static final String PROPERTY_KEY_MATCHER = "keyMatcher";
    
    /**
     * 取り込んだデータソースや、キーマッチングなどを決定している
     * データマップ
     */
    private KeyMatchedRowMap rowMap = new KeyMatchedRowMap();
    
    
    public void addPropertyChangeListener(PropertyChangeListener pl) {
        propCng.addPropertyChangeListener(pl);
    }

    public void removePropertyChangeListener(PropertyChangeListener pl) {
        propCng.removePropertyChangeListener(pl);
    }

    public PropertyChangeListener[] getPropertyChangeListeners() {
        return propCng.getPropertyChangeListeners();
    }

    public void addPropertyChangeListener(String string, PropertyChangeListener pl) {
        propCng.addPropertyChangeListener(pl);
    }

    public void removePropertyChangeListener(String string, PropertyChangeListener pl) {
        propCng.removePropertyChangeListener(pl);
    }

    public PropertyChangeListener[] getPropertyChangeListeners(String string) {
        return propCng.getPropertyChangeListeners(string);
    }
    
    
    /**
     * データソースを追加する.
     * @param lineDataList 
     */
    public void addLineDataList(LineDataList lineDataList) {
        if (lineDataList == null) {
            throw new IllegalArgumentException();
        }
        rowMap.addLineDataList(lineDataList);
        rowMap.remap();

        renumbering(rowMap);
    }
    
    /**
     * 保持しているデータソースの数を返す
     * @return データソースの数
     */
    public int getDataListCount() {
        return rowMap.getNumOfLineDataLists();
    }
    
    /**
     * 現在適用されているキーマッチング方法を取得する.
     * @return キーマッヂング方法
     */
    public KeyMatcher getKeyMatcher() {
        return rowMap.getKeyMatcher();
    }
    
    /**
     * キーマッチング方法を設定する.<br>
     * 必要に応じて表は再構成される.<br>
     * @param keyMatcher キーマッチング方法
     */
    public void setKeyMatcher(KeyMatcher keyMatcher) {
        if (keyMatcher == null) {
            throw new IllegalArgumentException();
        }
        
        KeyMatcher oldValue = getKeyMatcher();
        if (oldValue != keyMatcher) {
            // キータイプが変更される場合のみ
            // キーを変更してマッチチングを再適用し、表を構成し直す.
            rowMap.setKeyMatcher(keyMatcher);
            rowMap.remap();

            renumbering(rowMap);

            propCng.firePropertyChange(PROPERTY_KEY_MATCHER, oldValue, keyMatcher);
        }
    }
    
    /**
     * キーまたはデータソースのタイトルを返す.<br>
     * 0列がキーで、それ以降はデータソースごとのタイトルが返される.<br>
     * @param i
     * @return 
     */
    @Override
    public String getColumnName(int i) {
        if (i == 0) {
            return "Key";
        }
        int column = i - 1; // 左端はキーカラム固定
        String title = rowMap.getTitle(column);

        if (StringUtils.isBlank(title)) {
            // 空の場合は列番号をつけて返す.
            title = "(" + column + ")";
        }
        
        return title;
    }
    

    /**
     * このデータをファイルに保存する.
     * @param file 保存先ファイル
     * @throws IOException 失敗
     */
    public void save(File file) throws IOException {
        if (file == null) {
            throw new IllegalArgumentException();
        }
        
        DocArchive.write(file, rowMap, this);
    }
}
