/*
 * 自在表示テーブル
 *
 * このファイルの利用について
 * このファイルの内容は、個人利用・商用利用に関わらず、一部または全部を、
 * 自由に利用していただいてかまいません。
 * 但し、引用元の表示か、著作者が（有）ワイシステムクリエイトであることを
 * 示す、著作権表示を必ず行ってください。
 * また、このファイルの内容を利用した事により、何らかの不利益を被った場合
 * でも、（有）ワイシステムクリエイトは、一切保証できませんので、利用者ご
 * 自身の責任において、ご利用くださるようお願いします。
 *
 * Copyright (C) 2005 Y System Create Corporation. All Rights Reserved.
 *
 * $Date: 2005/08/13 10:15:10 $
 * $Revision: 1.1 $
 */

/*****************************************************************************
 ** 全体の設定
 ****************************************************************************/


function initAutorc() {

//    AppUtil.EXECUTION = AppUtil.DEBUGLOG;
    AppUtil.initializeApply();

    var autorcTable = document.getElementById("autorcTable1");
    var autorcCtrl = document.getElementById("autorcCtrl");
    var autorcShell = document.getElementById("autorc");
    var autorcButton = document.getElementById("autorcButton");

    var autorcView = new AutorcView(autorcTable, autorcCtrl);
    var autorcModel = new AutorcModel();
    var filter = new Object();
    filter["getViewValue"] = function (value) {

        var returnValue = value;

        if (! value.substring) {

            return value;
        }
        if (12 == value.length || 8 == value.length) {

            returnValue = value.substring(0, 4);
            returnValue += "/";
            returnValue += value.substring(4, 6);
            returnValue += "/";
            returnValue += value.substring(6, 8);

            if (12 == value.length) {
                /*
                 * 年月日時分
                 */
                returnValue += " ";
                returnValue += value.substring(8, 10);
                returnValue += ":";
                returnValue += value.substring(10, 12);
            }
        }

        return returnValue;
    }
    autorcModel.addViewFilter("date", filter);

    var xmlLSImplement = new XmlLSImplement();
    var xmlDoc = xmlLSImplement.perseFromURI("./booklist.xml");
    //var xmlDoc = xmlLSImplement.perseFromURI("./tips.xml");
    autorcModel.addRows(xmlDoc);
    autorcView.setModel(autorcModel);

    autorcCtrl.onfocus = function (e) {

//        autorcTable.style.border = "thick solid red";
//        AppUtil.printLog("フォーカスが来た");
        HtmlUtil.addClassValue(autorcShell, "onfocus");
    }
    autorcCtrl.onblur = function (e) {

//        autorcTable.style.outline = "";
//        AppUtil.printLog("フォーカスが行った");
        HtmlUtil.removeClassValue(autorcShell, "onfocus");
    }
    autorcView.invokeFocusToController();

    autorcButton.onclick = function () {

        var autorcSelect = document.getElementById("autorcSelect");
        if (0 == autorcSelect.selectedIndex) {
            xmlDoc = xmlLSImplement.perseFromURI("./booklist.xml");
        }
        else {
            xmlDoc = xmlLSImplement.perseFromURI("./tips.xml");
        }
//        autorcView = new AutorcView(autorcTable, autorcCtrl);
//        autorcModel = new AutorcModel();
//        autorcModel.addViewFilter("date", filter);
//        autorcModel.addRows(xmlDoc);
//        autorcView.setModel(autorcModel);
//        autorcModel.addRows(xmlDoc);
        autorcView.init();
        autorcModel.allClear();
        autorcModel.addRows(xmlDoc);
        autorcModel.fireTableChanged(null);
    }
}


/*****************************************************************************
 * 一覧ビュー
 ****************************************************************************/
AutorcView.prototype = new TableView();
/**
 * コンストラクタ
 */
function AutorcView(targetTable, controller) {

    if (null == targetTable) {
        return;
    }
    this.initTableView(targetTable, controller);
}

/**
 * テーブル表示の初期化を行う。
 * 全体の初期化と、テーブルボディー部以外の内容の表示などを行う。
 * 必ず実装する必要がある。
 */
AutorcView.prototype.initializeView = function () {

//    this.init();

    if (null != this.model) {

        var columnCount = this.model.getColumnCount();
        columnCount = (-1 == columnCount) ?
            this.model.getColumnCountAt(i) : columnCount;

        var theadRows = this.jsTable.table.tHead.rows;
        var theadRow = theadRows.item(0);
        var theadCell = theadRow.cells.item(0);

        var row = this.jsTable.getRowFromBodiesAt(0);
        var cell = row.cells.item(0);

        for (var j = 0; j < (columnCount - 1); j ++) {

            var theadCellElement = theadRow.insertCell(-1);
            DomUtil.deepClone2(theadCellElement, theadCell);

            var cellElement = row.insertCell(-1);
            DomUtil.deepClone2(cellElement, cell);
        }

        var theadCells = theadRow.cells;
        var cells = row.cells;
        for (var j = 0; j < columnCount; j ++) {

            var columnTitleView =
                DomUtil.getElementByAttributeValue(theadCells.item(j),
                                                   "className",
                                                   "columnTitleView");
            DomUtil.setTextValue(columnTitleView, this.model.getColumnTitleAt(j));

            HtmlUtil.addClassValue(cells.item(j), this.model.getColumnNameAt(j));
        }

        /*
         * モデルが設定済みの場合は、モデルの行数にテーブルの行数が
         * 足りない場合、その分を追加する。
         */
        var modelRowCount = this.model.getRowCount();
        var bodiesRowCount = this.jsTable.getBodiesRowCount();
        var count = modelRowCount - bodiesRowCount;

        for (var i = 0; i < count; i ++) {

            var rowElement = this.jsTable.insertRowAt(-1);
            DomUtil.deepClone2(rowElement, row);
        }
    }

    this.noneDisplayEditor();
    var rows = this.tableElement.rows;

    for (var i = 0; i < rows.length; i ++) {

        var row = rows.item(i);
        HtmlUtil.removeClassValue(row, TableView.selectRowClass);
        HtmlUtil.addClassValue(row, TableView.nonSelectRowClass);

        for (var j = 0; j < row.cells.length; j ++) {

            var cell = row.cells.item(j);
            HtmlUtil.removeClassValue(cell, TableView.selectColumnClass);
            HtmlUtil.addClassValue(cell, TableView.nonSelectColumnClass);
            HtmlUtil.removeClassValue(cell, TableView.editableCellClass);
            HtmlUtil.addClassValue(cell, TableView.nonEditableCellClass);
        }
    }

    if (this.selectedRow == -1) {

        this.selectedRow = 0;
    }
    this.selectRow();
    this.selectColumn();
}
/*
 * テーブルの内容を、初期状態にする。
 */
AutorcView.prototype.init = function () {

    /*
     * 一旦すべてのボディ行を削除し、ヘッダ行のセルも削除する。
     */
    var bodiesRowCount = this.jsTable.getBodiesRowCount();
    for (var i = 0; i < (bodiesRowCount - 1); i ++) {
        this.jsTable.table.deleteRow(-1);
    }
    var bodiesRow = this.jsTable.getRowFromBodiesAt(0);
    var cellsCount = bodiesRow.cells.length;
    for (var i = 0; i < (cellsCount - 1); i ++) {
        bodiesRow.deleteCell(-1);
    }

    var theadRows = this.jsTable.table.tHead.rows;
    var theadRow = theadRows.item(0);
    cellsCount = theadRow.cells.length;
    for (var i = 0; i < (cellsCount - 1); i ++) {
        theadRow.deleteCell(-1);
    }
    this.selectedRow = 0;
    this.selectedColumn = 0;
}
AutorcView.prototype.enter = function () {
}

/*****************************************************************************
 * データモデル
 ****************************************************************************/
AutorcModel.prototype = new DefaultTableModel();

/**
 * コンストラクタ
 */
function AutorcModel() {

    this.initTableModel();
    this.columnCount = -1;
    this.rows = new Array();
    this.names = new Array();
    this.titles = new Array();
    this.viewFilters = new Object();
    this.isReadonlyByRow = new Array();
    this.isReadonlyByColumn = new Array();
    this.isReadonlyByCell = new Object();
}


/**
 * 表示用フィルタの追加
 */
AutorcModel.prototype.addViewFilter = function (name, filter) {

    if (! name) {

        throw WebApplyUtil.createException(
                new Error(),
                "AutorcModel#addViewFilter:"+
                "IllegalArgument:"+
                "name is null.");
    }

    if (! filter || ! filter.getViewValue) {

        throw WebApplyUtil.createException(
                new Error(),
                "AutorcModel#addViewFilter:"+
                "IllegalArgument:"+
                "filter is null.");
    }
    this.viewFilters[name] = filter;
}


/**
 * 指定セルの表示用の値を取得する。
 * @param rowIndex : 数値 : 値を取得するセルの行インデックス。
 * @param columnIndex : 数値 : 値を取得するセルの列インデックス。
 * @return モデルが格納している値
 */
AutorcModel.prototype.getValueAt = function (rowIndex, columnIndex) {

    var value =  this.getEditableValueAt(rowIndex, columnIndex);
    var name = this.getColumnNameAt(columnIndex);
    var filter = this.viewFilters[name];
    if (! filter) {
        return value;
    }
    else {
        return filter.getViewValue(value);
    }
}


/**
 * 行の追加
 * 渡されたXMLドキュメントより、データを取得して、モデルに追加する。
 * @param xmlDoc :  : 追加するデータを格納しているXMLドキュメント。
 */
AutorcModel.prototype.addRows = function (xmlDoc) {

    var cinfs = xmlDoc.getElementsByTagName("cinf");
    if (null == cinfs || 0 == cinfs.length) {
        // 例外
        return;
    }
    for (var i = 0; i < cinfs.length; i ++) {

        this.names[i] = cinfs.item(i).getAttribute("name");
        this.titles[i] = cinfs.item(i).getAttribute("title");
        var readonly = cinfs.item(i).getAttribute("readonly");
        if (readonly) {
            this.isReadonlyByColumn[i] = true;
        }
    }
    this.columnCount = cinfs.length;

    var rows = xmlDoc.getElementsByTagName("r");
    if (null == rows || 0 == rows.length) {
        // 例外
        return ;
    }
    var currentRowCount = this.rows.length;
    for (var i = 0; i < rows.length; i ++) {
        var cells = rows.item(i).getElementsByTagName("c");
        var readonly = rows.item(i).getAttribute("readonly");
        if (readonly) {
            this.isReadonlyByRow[i] = true;
        }
        if (null == cells || 0 == cells.length) {
            // 例外
            return ;
        }
        var rowValues = new Array();
        for (var j = 0; j < cells.length; j ++) {
            var cell = cells.item(j);
            var cellValue = "";
            if (cell.hasChildNodes()) {
                cellValue = cell.firstChild.nodeValue;
            }
            rowValues[j] = cellValue;
            var readonly = cell.getAttribute("readonly");
            if (readonly) {
                this.isReadonlyByCell[""+i+"-"+j] = true;
            }
        }
        this.rows[currentRowCount + i] = rowValues;
    }
}

/**
 * すべての行をクリアする。
 */
AutorcModel.prototype.allClear = function () {

    this.columnCount = -1;
    this.rows = new Array();
    this.names = new Array();
    this.titles = new Array();
    this.isReadonlyByRow = new Array();
    this.isReadonlyByColumn = new Array();
    this.isReadonlyByCell = new Object();
}
/**
 * 列のタイトルを返す。
 * @param columnIndex : 数値 : 列インデックス。
 * @return 文字列 : 指定カラムのタイトル。
 */
AutorcModel.prototype.getColumnTitleAt = function (columnIndex) {

    return this.titles[columnIndex];
}

/**
 * 列の名前を返す。
 * @param columnIndex : 数値 : 列インデックス。
 * @return 文字列 : 指定カラムの名前。
 *         セルのクラスに設定する。
 */
AutorcModel.prototype.getColumnNameAt = function (columnIndex) {

    return this.names[columnIndex];
}

/**
 * 編集可否判定
 * 指定セルが編集可能かどうかを返す。
 * @param rowIndex : 数値 : 行インデックス。
 * @param columnIndex : 数値 : 列インデックス。
 * @return 必ずtrue
 */
AutorcModel.prototype.isCellEditable = function (rowIndex, columnIndex) {

    var isReadonly = true;
    if (this.isReadonlyByColumn[columnIndex]) {
        isReadonly = false;
    }
    if (this.isReadonlyByRow[rowIndex]) {
        isReadonly = false;
    }
    if (this.isReadonlyByCell[""+rowIndex+"-"+columnIndex]) {
        isReadonly = false;
    }
    return isReadonly;
}
