/*
 * 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.frames.mainframe.impl;

import com.queplix.core.client.app.Application;
import com.queplix.core.client.app.vo.FamgMeta;
import com.queplix.core.client.app.vo.FocusMeta;
import com.queplix.core.client.app.vo.SubFocusMeta;
import com.queplix.core.client.app.vo.TabMeta;
import com.queplix.core.client.common.event.Event;
import com.queplix.core.client.common.event.EventSource;
import com.queplix.core.client.common.ui.resizable.ResizableLazyDeckPanel;
import com.queplix.core.client.controls.form.QForm;
import com.queplix.core.client.frames.mainframe.ViewPropertiesProvider;

/**
 * Postfix FA - Form Area.
 * On sub focus change you should select corresponding SubFocusFA in this
 * class to show contents.
 * Class MainFrameFA contains array of FocusFA.
 * This class FocusFA contains array of SubFocusFA.
 * Class SubFocusFA contains array of TabFA.
 * Class TabFA contains array of QForm.
 *
 * @author Aliaksandr Melnik
 * @since 19 Oct 2006
 */
class FocusFA extends ResizableLazyDeckPanel {
    private ViewPropertiesProvider viewPropertiesProvider;

    // -------------------- public events ------------------------
    public static interface Events extends SubFocusFA.Events {
        Event SUBFOCUS_SELECTED_EVENT = new Event();
    }

    private EventSource eventSource = new EventSource(this);

    public EventSource getEventSource() {
        return eventSource;
    }
    // ----------------- end of public events --------------------

    private SubFocusFA[] subFocusesFA;
    private SubFocusMeta[] subFocusesMeta;

    private int activeSubfocus = -1;

    private String status;

    private boolean fireInitialization;

    public FocusFA(FocusMeta focusMeta,
                   ViewPropertiesProvider viewPropertiesProvider,
                   boolean fireInitialization,
                   FamgMeta.Index indexToActivate) {
        super(focusMeta.getSubFocuses().length);
        this.viewPropertiesProvider = viewPropertiesProvider;
        this.indexToActivate = indexToActivate == null
                ? DEFAULT_INDEX_TO_ACTIVATE:indexToActivate;
        this.fireInitialization = fireInitialization;
        status = Application.getStatus();

        subFocusesMeta = focusMeta.getSubFocuses();
        subFocusesFA = new SubFocusFA[subFocusesMeta.length];

        if(subFocusesMeta.length > 0) {
            activateSubFocus(indexToActivate.subFocus);
        }
    }

    public void setFormsState(int formState) {
        for(int i = 0; i < subFocusesFA.length; i++) {
            if(subFocusesFA[i] != null) {
                subFocusesFA[i].setFormsState(formState);
            }
        }
    }

    protected void createCard(int index) {
        if(index == 0) {
            Application.setStatus(
                    status + " -> subFocus: " + subFocusesMeta[index]
                            .getCaption());
        }
        SubFocusFA subFocusFA = new SubFocusFA(subFocusesMeta[index],
                viewPropertiesProvider, fireInitialization, indexToActivate);
        subFocusFA.getEventSource().addEventListener(
                eventSource); // retranslate events
        remove(index);
        insert(subFocusFA, index);
        subFocusesFA[index] = subFocusFA;
        if(fireInitialization) {
            initialized();
        }
        fireInitialization = true;
    }

    public QForm getForm(FamgMeta.Index index) {
        QForm ret = null;
        SubFocusFA subFocusFA = subFocusesFA[index.subFocus];
        if(subFocusFA != null) {
            ret = subFocusFA.getForm(index);
        }
        return ret;
    }

    public TabFA getTab(TabMeta.Index index) {
        TabFA ret = null;
        SubFocusFA subFocusFA = subFocusesFA[index.subFocus];
        if(subFocusFA != null) {
            ret = subFocusFA.getTab(index);
        }
        return ret;
    }

    public QForm getActiveForm() {
        return subFocusesFA[activeSubfocus].getActiveForm();
    }

    public void activateForm(FamgMeta.Index index) {
        activateSubFocus(index);
        subFocusesFA[activeSubfocus].activateForm(index);
    }

    public void activateTab(TabMeta.Index index) {
        activateSubFocus(index);
        subFocusesFA[activeSubfocus].activateTab(index);
    }

    public void activateSubFocus(SubFocusMeta.Index index) {
        if(index.subFocus != activeSubfocus) {
            activateSubFocus(index.subFocus);
        }
    }

    private void activateSubFocus(int index) {
        activeSubfocus = index;
        showWidget(index);
        eventSource.fireEvent(Events.SUBFOCUS_SELECTED_EVENT);
    }

    public SubFocusFA getSubFocus(SubFocusMeta.Index index) {
        return subFocusesFA[index.subFocus];
    }

    public SubFocusMeta.Index getSelectedSubFocusIndex() {
        return subFocusesMeta[getVisibleWidget()].getIndex();
    }

    public TabMeta.Index getSelectedTabIndex() {
        return subFocusesFA[getVisibleWidget()].getSelectedTabIndex();
    }

    public FamgMeta.Index getSelectedFormIndex() {
        return subFocusesFA[getVisibleWidget()].getSelectedFormIndex();
    }

    public boolean performCommand(FormCommand command,
                                  FamgMeta.Index formIndex) {
        return subFocusesFA[formIndex.subFocus].performCommand(command,
                formIndex);
    }

    /**
     * Called when the object is fully initialized by the creator.
     */
    void initialized() {
        subFocusesFA[activeSubfocus].initialized();
    }

    boolean isInEditMode() {
        for(int i = 0; i < subFocusesFA.length; i++) {
            if(subFocusesFA[i] != null) {
                if(subFocusesFA[i].isInEditMode()) {
                    return true;
                }
            }
        }
        return false;
    }

    void collectUISettings() {
        for(int i = 0; i < subFocusesFA.length; i++) {
            if(subFocusesFA[i] != null) {
                subFocusesFA[i].collectUISettings();
            }
        }
    }

    public FamgMeta.Index getNextExistingFormIndex(int subFocus, int tab,
                                                   int famg) {
        FamgMeta.Index ret = null;
        for(int i = subFocus; i < subFocusesFA.length; i++) {
            if(subFocusesFA[i] != null) {
                FamgMeta.Index nextIndex = subFocusesFA[i]
                        .getNextExistingFormIndex(tab, famg);
                if(nextIndex != null) {
                    ret = nextIndex;
                    break;
                }
            }
            tab = 0;//reset to first
            famg = -1;
        }
        return ret;
    }
}
