/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on ----
!  AUTHOR(S): KOGA, Junichiro
!  File : VectorConsistencyChecker.java
!  
!  Contact address :  Phase System Consortium
!                     E-mail: phase_system@nims.go.jp URL https://azuma.nims.go.jp
!
!
!   Since 2002, this program set had been intensively developed as a part of the following 
!  national projects supported by the Ministry of Education, Culture, Sports, Science and
!  Technology (MEXT) of Japan; "Frontier Simulation Software for Industrial Science
!  (FSIS)" from 2002 to 2005, "Revolutionary Simulation Software (RSS21)" from 2006 to
!  2008. "Research and Development of Innovative Simulation Software (RISS)" from 2008
!  to 2013. These projects is lead by the Center for Research on Innovative Simulation 
!  Software (CISS), the Institute of Industrial Science (IIS), the University of Tokyo.
!   Since 2013, this program set has been further developed centering on PHASE System
!  Consortium. 
!   The activity of development of this program set has been supervised by Takahisa Ohno.
!
!=======================================================================
 */
package ciss.phase_viewer.common;

import java.util.Vector;

public class VectorConsistencyChecker {

    private Vector elmAt;
    private Vector elmEl;
    private Vector elm_Not_redundent;
    private int i;
    private int j;
    private int NumEl;

    /**
     * 比較対照のVector二つを設定, その後要素をソートし, さらにredundentでない Vectorも用意する.
     * 
     * @param elmAt_
     *            比較きVector, redundencyがあってよい.
     * @param elmEl_
     *            比較すべきVector, redundencyはないと想定している.
     */
    public VectorConsistencyChecker(Vector elmAt_, Vector elmEl_) {

        int i;
        elmAt = new Vector();
        elmEl = new Vector();
        elm_Not_redundent = new Vector();

        for (i = 0; i < elmAt_.size(); i++) {
            this.elmAt.addElement((String) elmAt_.get(i));
        }
        for (i = 0; i < elmEl_.size(); i++) {
            this.elmEl.addElement((String) elmEl_.get(i));
        }

        this.elmAt.trimToSize();
        this.elmEl.trimToSize();

        elmAt = sortVector(elmAt);
        setDistinctVector();
        elmEl = sortVector(elmEl);

        // System.out.println("first vector, without redundency : "+elm_Not_redundent);
        // System.out.println("second vector                    : "+elmEl);
    }

    /**
     * 引数なしのコンストラクター, できる初期化のみ行う.
     */
    public VectorConsistencyChecker() {
        elmAt = new Vector();
        elmEl = new Vector();
        elm_Not_redundent = new Vector();
    }

    private Vector sortVector(Vector vec) {
        int i, j;
        String stri = new String();
        String strj = new String();
        String str_wk[] = new String[vec.size()];
        int icomp = 0, vecsize;

        try {

            for (i = 0; i < vec.size(); i++) {
                str_wk[i] = (String) vec.get(i);
            }

            for (i = 0; i < vec.size(); i++) {
                for (j = 0; j < vec.size(); j++) {
                    stri = str_wk[i];
                    strj = str_wk[j];
                    icomp = stri.compareTo(strj);
                    if (icomp < 0) {
                        str_wk[j] = stri;
                        str_wk[i] = strj;
                    }
                }
            }

            vecsize = vec.size();
            vec.clear();
            for (i = 0; i < vecsize; i++) {
                vec.add(str_wk[i]);
            }
        } catch (Exception e) {
            System.out.println("At VectorConsistencyChecker.sortVector: ");
            System.out.println("error: " + e);
        }
        return (vec);
    }

    private void setDistinctVector() {
        int i, j;
        String stri = new String();
        String strj = new String();

        try {
            if (elmAt.size() != 0) {
                elm_Not_redundent.add(elmAt.get(0));
                for (i = 0; i < elmAt.size() - 1; i++) {
                    stri = (String) elmAt.get(i);
                    strj = (String) elmAt.get(i + 1);
                    if (!stri.equals(strj)) {
                        elm_Not_redundent.add(strj);
                    }
                }
            }
        } catch (Exception e) {
            System.out
                    .println("At VectorConsistencyChecker.setDistinctVector:");
            System.out.println("error: " + e);
        }
    }

    /**
     * 二つのVectorを比較する.
     * 
     * @param elmAt_
     *            redundencyがあってよいVector
     * @param elmEl_
     *            redundencyを想定していないVector
     * @return 比較結果; - 0: 二つのベクトルは等しい. - -1:
     *         elmAt_の方がredundencyを除いても多くの要素を持っている. - 1: redundencyを除くと,
     *         elmAt_の方が要素の数が少ない. - 2: redundencyを除くと, 二つのVectorのサイズは同じ. .
     */
    public int check(Vector elmAt_, Vector elmEl_) {
        int i, ic;

        for (i = 0; i < elmAt_.size(); i++) {
            this.elmAt.addElement((String) elmAt_.get(i));
        }
        for (i = 0; i < elmEl_.size(); i++) {
            this.elmEl.addElement((String) elmEl_.get(i));
        }

        elmAt = sortVector(elmAt);
        setDistinctVector();
        elmEl = sortVector(elmEl);

        if (elm_Not_redundent.equals(elmEl)) {
            return (0);
        } else {
            if (elm_Not_redundent.size() > elmEl.size()) {
                return (-1);
            } else if (elm_Not_redundent.size() < elmEl.size()) {
                return (1);
            } else {
                return (2);
            }
        }
    }

    /**
     * 二つのVectorを比較する. 対象となるVectorは, コンストラクターで定義したもの.
     * 
     * @return 比較結果; - 0: 二つのベクトルは等しい. - -1:
     *         elmAt_の方がredundencyを除いても多くの要素を持っている. - 1: redundencyを除くと,
     *         elmAt_の方が要素の数が少ない. - 2: redundencyを除くと, 二つのVectorのサイズは同じ. .
     */
    public int check() {

        if (elm_Not_redundent.equals(elmEl)) {
            return (0);
        } else {
            if (elm_Not_redundent.size() > elmEl.size()) {
                return (-1);
            } else if (elm_Not_redundent.size() < elmEl.size()) {
                return (1);
            } else {
                return (2);
            }
        }

    }

    public int overWriteFirstVector() {
        int i;
        elmEl.clear();
        for (i = 0; i < elm_Not_redundent.size(); i++) {
            elmEl.add(elm_Not_redundent.get(i));
        }
        return (0);
    }

    public Vector getFirstVector() {
        return (elmEl);
    }

    /**
     * Vector中の, 「最大要素」のインデックスを取得する.
     * 
     * @param vec
     *            調査するVector
     * @return 最大値のインデックス
     */
    public int getIndexOfMaxVal(Vector vec) {
        int i;
        int imax = 0;
        int vec_max = Integer.parseInt((String) vec.get(0));
        for (i = 1; i < vec.size(); i++) {
            if (Integer.parseInt((String) vec.get(i)) > vec_max) {
                imax = i;
                vec_max = Integer.parseInt((String) vec.get(i));
            }
        }
        return (imax);
    }

    /**
     * とあるVectorの重複の有無を調べる.
     * 
     * @param vec
     *            調査対象のVector.
     * @return 重複がある場合に真を返す.
     */
    public boolean checkRedundency(Vector vec) {
        int i, j;
        boolean bret = false;
        for (i = 0; i < vec.size() - 1; i++) {
            for (j = i + 1; j < vec.size(); j++) {
                if (((String) vec.get(i)).equals(((String) vec.get(j)))) {
                    bret = true;
                    break;
                }
            }
        }

        return (bret);
    }

    /**
     * とあるVectorに, 指定の文字列が存在するか否かを調べる.
     * 
     * @param vec
     *            調査対象のVector.
     * @param str
     *            存在の有無を調べたい文字列.
     * @return strがvec中に存在すれば真.
     */
    public boolean checkRedundency(Vector vec, String str) {
        int i;
        boolean bret = false;
        for (i = 0; i < vec.size(); i++) {
            if (((String) vec.get(i)).equals(str)) {
                bret = true;
                break;
            }
        }

        return (bret);
    }

    /**
     * とあるVectorの各要素がソートされているかどうか調べる.
     * 
     * @param vec
     *            調査対象のVector.
     * @return ソートされていれば真.
     */
    public boolean isAlligned(Vector vec) {
        int i;
        boolean bret = true;
        for (i = 0; i < vec.size(); i++) {
            if (Integer.parseInt((String) vec.get(i)) != i + 1) {
                bret = false;
                break;
            }
        }

        return (bret);
    }

    /**
     * とあるVectorの各要素に重複があるか否か調べる. case-insensative.
     * 
     * @param vec
     *            調査対象のVector.
     */
    public boolean isUnique(Vector vec) {
        int i, j;
        boolean bret = true;
        for (i = 0; i < vec.size(); i++) {
            for (j = i + 1; j < vec.size(); j++) {
                if (!(((String) vec.get(i)).equalsIgnoreCase(((String) vec
                        .get(j))))) {
                    bret = false;
                    break;
                }
            }
        }

        return (bret);
    }

    /**
     * とあるVectorの各要素に指定の文字列があるか否か調べる. case-insensative.
     * 
     * @param vec
     *            調査対象のVector.
     * @param str
     *            存在の有無を調べたい文字列.
     * @return strがvec中に存在しない場合真.
     */
    public boolean isUnique(Vector vec, String str) {
        int i, j;
        boolean bret = true;
        for (i = 0; i < vec.size(); i++) {
            if (!(((String) vec.get(i)).equalsIgnoreCase(str))) {
                bret = false;
                break;
            }
        }

        return (bret);
    }

}
