/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */

package com.queplix.core.client.app.vo;

import com.google.gwt.user.client.rpc.IsSerializable;
import com.queplix.core.client.common.CollectionsHelper;
import com.queplix.core.client.common.StringUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * Represents grid data, that will be responsed on client request.
 *
 * @author Sergey Kozmin
 * @since 18.10.2006, 12:00:15
 */
public class GridData implements IsSerializable {
    private String entityName;
    private RowData[] rows;

    public GridData(RowData[] rows, String entityName) {
        this.entityName = entityName;
        if(rows != null) {
            this.rows = rows;
        } else {
            this.rows = new RowData[0];
        }
    }

    public GridData() {
        this(null, "def_entity_name");
    }

    public RowData[] getRows() {
        return rows;
    }

    public void setRows(RowData[] rows) {
        if(rows != null) {
            this.rows = rows;
        }
    }

    public void insertRow(RowData insertingRow) {
        if(insertingRow != null) {
            RowData[] tmpRows = new RowData[rows.length + 1];
            int i = 0;
            for(; i < rows.length; i++) {
                tmpRows[i] = rows[i];
            }
            tmpRows[i] = insertingRow;
            rows = tmpRows;
        }
    }

    /**
     * removes row with the given id
     *
     * @param rowId row id
     * @return was the element deleted
     */
    public boolean removeRow(Long rowId) {
        int index = getRowIndexByID(rowId);
        return removeRow(index);
    }

    /**
     * removes row with the given index
     *
     * @param index index in array
     * @return was the element deleted
     */
    public boolean removeRow(int index) {
        if(index >= 0 && index < rows.length) {
            RowData[] newRows = new RowData[rows.length - 1];
            for(int i = 0, newCounter = 0; i < rows.length; i++) {
                if(i != index) {
                    newRows[newCounter] = rows[i];
                    newCounter++;
                }
            }
            rows = newRows;
            return true;
        }
        return false;
    }

    /**
     * removes rows with the given indexes
     *
     * @param indexes list of indexes List<Integer>
     * @return was any record removed from rows.
     */
    public boolean removeRows(List indexes) {
        boolean ret = false;
        if(indexes != null && indexes.size() > 0) {
            List newRows = new ArrayList();
            for(int i = 0; i < rows.length; i++) {
                if(!indexes.contains(new Integer(i))) {
                    newRows.add(rows[i]);
                } else {
                    ret = true;
                }
            }
            rows = new RowData[newRows.size()];
            CollectionsHelper.copyToArray(newRows, rows);
        }
        return ret;
    }

    public void clearRecords() {
        rows = new RowData[0];
    }

    /**
     * Search row data by the given record id.
     *
     * @param recordId searching entity id.
     * @return row data for the given id, or null if such entity id is not presented in grid data.
     */
    public RowData getRowByID(Long recordId) {
        int index = getRowIndexByID(recordId);
        if(index >= 0) {
            return rows[index];
        } else {
            return null;
        }
    }

    /**
     * Search row index in data.
     *
     * @param recordId searching entity id.
     * @return integer greater or equal to 0 if record found otherwise return integer less then 0.
     */
    public int getRowIndexByID(Long recordId) {
        if(rows != null) {
            for(int i = 0; i < rows.length; i++) {
                if(rows[i].getId().equals(recordId)) {
                    return i;
                }
            }
        }
        return -1;
    }

    public GridData cloneGrid() {
        RowData[] clonedRows = new RowData[rows.length];
        for(int i = 0; i < clonedRows.length; i++) {
            clonedRows[i] = rows[i].cloneData();
        }
        return new GridData(clonedRows, entityName);
    }

    public boolean equalsToGrid(GridData grid) {
        boolean ret = false;
        if(grid != null && grid.rows.length == rows.length
                && StringUtil.isStringsEqualsIgnoreNulls(grid.entityName,
                entityName)) {

            ret = true;
            for(int i = 0; i < rows.length; i++) {
                if(!rows[i].equalsToRow(grid.rows[i])) {
                    ret = false;
                    break;
                }
            }
        }
        return ret;
    }

    public boolean isEmpty() {
        return rows.length <= 0;
    }

    public String getEntityName() {
        return entityName;
    }

    public void setEntityName(String entityName) {
        this.entityName = entityName;
    }
}
