/*
 * 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.StringUtil;

/**
 * Class store data for the single entity object.
 *
 * @author Sergey Kozmin
 */
public class EntityData implements IsSerializable {
    private FieldData[] fields;
    private Long rowID;
    private String entityID;

    public EntityData(String entityID, Long rowID, FieldData[] fields) {
        this.rowID = rowID;
        this.entityID = entityID;
        if(fields != null) {
            this.fields = fields;
        } else {
            this.fields = new FieldData[0];
        }
    }

    public EntityData() {
        this("", new Long(-1), null);
    }

    /**
     * @return fields data. couldn't be null
     */
    public FieldData[] getFields() {
        return fields;
    }

    public void setFields(FieldData[] fields) {
        if(fields != null) {
            this.fields = fields;
        }
    }

    public String getEntityID() {
        return entityID;
    }

    public void setEntityID(String entityID) {
        this.entityID = entityID;
    }

    public Long getRowID() {
        return rowID;
    }

    public void setRowID(Long rowID) {
        this.rowID = rowID;
    }

    public FieldData getFieldById(String fieldId) {
        FieldData fieldData = null;
        for(int i = 0; i < fields.length; i++) {
            if(fields[i].getFieldID().equalsIgnoreCase(fieldId)) {
                fieldData = fields[i];
                break;
            }
        }
        return fieldData;
    }

    /**
     * @return the number of not empty fields.
     */
    public int countNotEmptyFields() {
        int counter = 0;
        for(int i = 0; i < fields.length; i++) {
            if(!fields[i].isEmpty()) {
                counter++;
            }
        }
        return counter;
    }

    /**
     * The array is not empty only if method {@link #countNotEmptyFields()}
     * returns the value that is great then 0.
     *
     * @return new instance of array, that contians only not empty fields.
     */
    public FieldData[] getNotEmptyFields() {
        FieldData[] ret = new FieldData[countNotEmptyFields()];

        for(int i = 0, retCounter = 0; i < fields.length; i++) {
            if(!fields[i].isEmpty()) {
                ret[retCounter++] = fields[i];
            }
        }

        return ret;
    }

    public EntityData cloneEntity() {
        FieldData[] clonedFields = new FieldData[fields.length];
        for(int i = 0; i < clonedFields.length; i++) {
            clonedFields[i] = fields[i].cloneData();
        }
        Long rowId = new Long(rowID != null ? rowID.longValue():-1);
        return new EntityData(entityID, rowId, clonedFields);
    }

    public boolean equalsToEntity(EntityData data) {
        boolean idsEq = (rowID != null) ? rowID.equals(data.rowID)
                :data.rowID == null;

        boolean nameEq = StringUtil.isStringsEqualsIgnoreNulls(entityID,
                data.entityID);

        if(idsEq && nameEq) {
            boolean ret = true;
            if(fields.length != data.fields.length) {
                ret = false;
            }
            for(int i = 0; i < fields.length; i++) {
                if(!fields[i].equals(data.fields[i])) {
                    ret = false;
                    break;
                }
            }
            return ret;
        } else {
            return false;
        }
    }
}
