/* $Id: DSCData.java 125 2011-03-09 09:49:51Z ohura $ */
/*
 * Created on 2006/08/24
 */
package jp.ac.hokudai.meme.core_smart_gs;

import java.awt.Rectangle;
import java.util.ArrayList;

import jp.ac.hokudai.meme.core_smart_gs.searcher.PagedRect;

/**
 * @author hajime
 */
public class DSCData {

    protected double[][] dscData_ = null;

    protected ArrayList slitDataList_ = null;

    protected DSCFileHeader header_ = null;

    protected ArrayList cumslitinPage_ = null;

    protected ArrayList slitinPage_ = null; // iページに含まれるスリット数
    
    protected int[] lineNos_ = new int[0];
    
    protected int[] slitNos_ = new int[0];

    public DSCData() {
        slitDataList_ = new ArrayList();
        slitinPage_ = new ArrayList();
        cumslitinPage_ = new ArrayList();
    }

    public Rectangle[] getPageRectangle(int page) {
        return (Rectangle[]) slitDataList_.get(page);
    }

    public int getSlitInPage(int page) {
        return ((Integer) slitinPage_.get(page)).intValue();
    }

    public int getCumSlitInPage(int page) {
        return ((Integer) cumslitinPage_.get(page)).intValue();
    }

    public void addDscData(DSCFileHeader addFileHeader, Rectangle[] slitData,
            double[][] addData) throws InvalidDataFormatException {
        if (validateHeader(addFileHeader)) {
            updateHeader(addFileHeader);
            slitDataList_.add(slitData);
            slitinPage_.add(new Integer(addFileHeader.getSlitCount()));
            if (cumslitinPage_ == null) {
                cumslitinPage_.add(new Integer(addFileHeader.getSlitCount()));//none
            } else {
                // cumslitinPage_.add(cumslitinPage_.get(cumslitinPage_.size()-1)
                // header.getSlitCount());
                cumslitinPage_.add(new Integer(header_.getSlitCount()));
            }
            double[][] destDataArray = new double[header_.getSlitCount()][header_.getDscDimension()];
            if (dscData_ == null) {
                dscData_ = addData;
            } else {
                System.arraycopy(dscData_, 0, destDataArray, 0, dscData_.length);
                System.arraycopy(addData, 0, destDataArray, dscData_.length, addData.length);
                dscData_ = destDataArray;
            }
        } else {
            throw new InvalidDataFormatException("IllegalArgument: Input file format is different.");
        }

    }
    
    public void addDscData(DSCFileHeader addFileHeader, Rectangle[] slitData,
            double[][] addData, int[] lineNos, int[] slitNos) throws InvalidDataFormatException{
        addDscData(addFileHeader, slitData, addData);
        lineNos_ = concat(lineNos_, lineNos);
        slitNos_ = concat(slitNos_, slitNos);
    }
    
    
    public boolean hasDscData() {
        if (dscData_ != null) {
            return true;
        } else {
            return false;
        }
    }
    
    protected int[] concat(int[] src1, int[] src2){
        int newSize = src1.length + src2.length;
        int[] dest = new int[newSize];
        System.arraycopy(src1, 0, dest, 0, src1.length);
        System.arraycopy(src2, 0, dest, src1.length, src2.length);
        return dest;
    }
    
    protected int pageIDToSerialID(int page, int pid) {
        int sid;
        // impl そのページのスリット数より大きいpidを受け取ったときおよび全ページ数より大きいpageを受け取ったときのエラー処理
        if (page == 0) {
            sid = pid;
        } else {
            sid = ((Integer) cumslitinPage_.get(page - 1)).intValue() + pid;
        }
        return sid;
    }

    protected void updateHeader(DSCFileHeader addFileHeader) {
        if (header_ == null) {
            header_ = addFileHeader;
        } else {
            header_.setSlitCount(header_.getSlitCount() + addFileHeader.getSlitCount());
        }
    }

    protected boolean validateHeader(DSCFileHeader header){
        boolean valid = true;
        String mes = "";
        if (header_ == null) {
			return true;
		}
        if (header_.getVersion() != header.getVersion()) {
			valid = false;
			mes += "IllegalArgument: Loading File Dimension.";
		}
        if (header_.getDscDimension() != header.getDscDimension()) {
			valid = false;
			mes += "IllegalArgument: Loading File Version.";
		}
        if (header_.getFileType() != header.getFileType()) {
        	valid = false;
			mes += "IllegalArgument: Loading File Type.";
		}
        return valid;
    }

    public double[][] getDscData() {
        return dscData_;
    }

    public ArrayList getSlitDataList_() {
        return slitDataList_;
    }
    
    protected int[] serialIDToPageID(int sid) {
        int page = 0;
        while (((Integer) cumslitinPage_.get(page)).intValue() <= sid)
            page++;
        // impl 最後まで行ってもwhileからでない場合のエラー処理
        int pid = 0;
        if (page == 0) {
            pid = sid;
        } else {
            pid = sid - ((Integer) cumslitinPage_.get(page - 1)).intValue();
        }
//        if (pid == 4180) {
//            System.out.println(sid);
//        }
        int lineNo = lineNos_[sid];
        int slitNo = slitNos_[sid];
        return new int[] { page, pid, lineNo, slitNo};
    }
    
    public PagedRect[] convertPieceIndexToRect(int[] indexes) {
        PagedRect[] prectary = new PagedRect[indexes.length];
        int indexlength = indexes.length;
        for (int i = 0; i < indexlength; ++i) {
            int[] ppos = serialIDToPageID(indexes[i]);
            int page = ppos[0];
            int pid = ppos[1];
            Rectangle rect = ((Rectangle[]) slitDataList_.get(page))[pid];
            int lineNo = ppos[2];
            int slitNo = ppos[3];
            prectary[i] = new PagedRect(page, rect, lineNo, slitNo);
        }

        return prectary;
    }

    public static void main(String[] args) {

    }

}
