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

import com.queplix.core.client.app.vo.FieldData;
import com.queplix.core.client.app.vo.FieldMeta;
import com.queplix.core.client.app.vo.FieldOnDemandData;
import com.queplix.core.client.common.StringUtil;
import com.queplix.core.client.i18n.I18N;

/**
 * Base class for all on-form controls' implementation classes.
 * Though this class is public, it is for internal use only
 *
 * @author sultan
 */
public abstract class QFormElementModelImpl implements QFormElementModel {
    public static final String DEFAULT_INVALID_ERROR_MESSAGE = I18N
            .getMessages().incorrectControlData();
    public static final String DEFAULT_REQUIRED_FIELD_MESSAGE = I18N
            .getMessages().requiredField();

    private FieldData data;
    private FieldMeta meta;
    private FieldOnDemandData onDemandData;
    private int reportDesignState = QFormElementModel.NOT_IN_REPORT;

    // ===================== Model events for View notification
    public static interface ModelListener {
        public void onModelMetaChanged();

        public void onModelDataChanged();

        public void onDemandModelChanged();

        public void onDesignStateChanged(int reportState);
    }

    private ModelListener modelListener; // only 1 object will listen to the event -- the control's view implementation

    public String getErrorTitle() {
        return DEFAULT_INVALID_ERROR_MESSAGE;
    }

    public void addModelListener(ModelListener listener) {
        modelListener = listener;
    }

    protected void fireModelMetaChanged() {
        if(null != modelListener) {
            modelListener.onModelMetaChanged();
        }
    }

    protected void fireModelDataChanged() {
        if(null != modelListener) {
            modelListener.onModelDataChanged();
        }
    }

    protected void fireOnDemandModelChanged() {
        if(null != modelListener) {
            modelListener.onDemandModelChanged();
        }
    }

    protected void fireReportStateChanged() {
        if(null != modelListener) {
            modelListener.onDesignStateChanged(reportDesignState);
        }
    }
    // ===================== End of Model events for View notification

    public void setCaption(String caption) {
        caption = StringUtil.nullToEmpty(caption);
        FieldMeta baseMeta = getBaseMeta();
        if(null != baseMeta) {
            if(caption.equalsIgnoreCase(baseMeta.getCaption())) {
                getBaseMeta().setCaption(caption);
                fireModelMetaChanged();
            }
        }
    }

    public FieldMeta getBaseMeta() {
        return meta;
    }

    public void setBaseMeta(FieldMeta meta) {
        if(null == meta) {
            throw (new IllegalArgumentException("data cannot be null"));
        } else {
            this.meta = meta;
            fireModelMetaChanged();
        }
    }

    public FieldData getBaseData() {
        return data;
    }

    public void setBaseData(FieldData data) {
        if(null == data) {
            throw (new IllegalArgumentException("Data cannot be null. "));
        } else {
            this.data = data;
            fireModelDataChanged();
        }
    }

    public void setFieldOnDemandData(FieldOnDemandData onDemandData) {
        if(null == onDemandData) {
            throw (new IllegalArgumentException(
                    "On demand data cannot be null. "));
        } else {
            this.onDemandData = onDemandData;
            fireOnDemandModelChanged();
        }
    }

    public FieldOnDemandData getFieldOnDemandData() {
        return onDemandData;
    }

    public int getReportDesignState() {
        return reportDesignState;
    }

    public void setReportDesignState(int newState) {
        if(reportDesignState != newState) {
            reportDesignState = newState;
            fireReportStateChanged();
        }
    }
}
