/*
 * 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.app.vo.PortalConfigMeta;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * Application Meta Data.
 *
 * @author Sultan Tezadov
 * @since 28 Sep 2006
 */
public class MetaData implements IsSerializable {
    private ProductMeta productMeta;
    private int timeZoneOffset;
    private SavedSearchObject[] savedSearches;
    private FocusMeta[] focuses;
    private GridMeta adhocReportsMeta;
    private PortalConfigMeta portalConfigMeta;
    private UserProfile userProfile;
    /**
     * Data that is specific for application
     * Map has {@link String} as key and {@link String} values
     */
    private Map applicationSpecificData;
    private FocusMeta.Index defaultFocusIndex;
    private int sessionTimeoutMinutes;
    private int sessionTimeoutWarnBeforeMinutes;
    private int checkMailTimeout;

    /**
     * Creates a new instance of MetaData
     */
    public MetaData() {
        this(new FocusMeta[0]);
    }

    public MetaData(FocusMeta[] focuses) {
        this.focuses = focuses;
        initChildrenIndexes();
    }

    public void setTimeZoneOffset(int offset) {
        this.timeZoneOffset = offset;
    }

    public int getTimeZoneOffset() {
        return this.timeZoneOffset;
    }

    public void initIndexes() {
        initChildrenIndexes();
    }

    private void initChildrenIndexes() {
        for(int i = 0; i < focuses.length; i++) {
            focuses[i].initIndexes(i);
        }
    }

    public int getSessionTimeoutMinutes() {
        return sessionTimeoutMinutes;
    }

    public void setSessionTimeoutMinutes(int sessionTimeoutMinutes) {
        this.sessionTimeoutMinutes = sessionTimeoutMinutes;
    }

    public int getSessionTimeoutWarnBeforeMinutes() {
        return sessionTimeoutWarnBeforeMinutes;
    }

    public void setSessionTimeoutWarnBeforeMinutes(
            int sessionTimeoutWarnBeforeMinutes) {
        this.sessionTimeoutWarnBeforeMinutes = sessionTimeoutWarnBeforeMinutes;
    }

    public FocusMeta[] getFocuses() {
        return focuses;
    }

    public FamgMeta getFamgMeta(FamgMeta.Index index) {
        return focuses[index.focus].getFamgMeta(index);
    }

    public TabMeta getTabMeta(TabMeta.Index index) {
        return focuses[index.focus].getTabMeta(index);
    }

    public TabMeta getTabMeta(String focusName, String subFocusName,
                              String tabName) {
        TabMeta tabMeta = null;
        for(int i = 0; i < focuses.length; i++) {
            if(focuses[i].getFocusName().equalsIgnoreCase(focusName)) {
                tabMeta = focuses[i].getTabMeta(subFocusName, tabName);
                break;
            }
        }
        return tabMeta;
    }

    public void setFocuses(FocusMeta[] focuses) {
        this.focuses = focuses;
        initChildrenIndexes();
    }

    public FamgMeta.Index getFormIndex(String focusName, String subFocusName,
                                       String tabName, String entityName) {
        FamgMeta.Index index = null;
        for(int i = 0; i < focuses.length; i++) {
            if(focuses[i].getFocusName().equalsIgnoreCase(focusName)) {
                index = focuses[i].getFormIndex(subFocusName, tabName,
                        entityName);
                break;
            }
        }
        return index;
    }

    public TabMeta.Index getTabIndex(String focusName, String subFocusName,
                                     String tabName) {
        TabMeta tabMeta = getTabMeta(focusName, subFocusName, tabName);
        return (tabMeta != null) ? tabMeta.getIndex():null;
    }

    public SubFocusMeta.Index getSubFocusIndex(String focusName,
                                               String subFocusName) {
        SubFocusMeta.Index index = null;
        for(int i = 0; i < focuses.length; i++) {
            if(focuses[i].getFocusName().equalsIgnoreCase(focusName)) {
                index = focuses[i].getSubFocusIndex(subFocusName);
                break;
            }
        }
        return index;
    }

    public FocusMeta.Index getFocusIndex(String focusName) {
        FocusMeta.Index index = null;
        for(int i = 0; i < focuses.length; i++) {
            if(focuses[i].getFocusName().equalsIgnoreCase(focusName)) {
                index = focuses[i].getIndex();
                break;
            }
        }
        return index;
    }

    /**
     * Returns one of:
     * FamgMeta.Index
     * TabMeta.Index
     * SubFocusMeta.Index
     * FocusMeta.Index
     * by the given id.
     */
    public FocusMeta.Index getIndexByID(String id) {
        FocusMeta.Index index = null;
        if(id != null) {
            String[] tokens = id.split("__");
            if(tokens.length == 4) {
                index = getFormIndex(tokens[0], tokens[1], tokens[2],
                        tokens[3]);
            } else if(tokens.length == 3) {
                index = getTabIndex(tokens[0], tokens[1], tokens[2]);
            } else if(tokens.length == 2) {
                index = getSubFocusIndex(tokens[0], tokens[1]);
            } else if(tokens.length == 1) {
                index = getFocusIndex(tokens[0]);
            }
        }
        return index;
    }

    public String getFormID(FamgMeta.Index index) {
        return focuses[index.focus].getFormID(index);
    }

    public GridMeta getGridMeta(FamgMeta.Index index) {
        FocusMeta focus = focuses[index.focus];
        SubFocusMeta subFocus = focus.getSubFocuses()[index.subFocus];
        TabMeta tab = subFocus.getTabs()[index.tab];
        FamgMeta famg = tab.getFamgs()[index.famg];
        return famg.getGrid();
    }

    public UserProfile getUserProfile() {
        return userProfile;
    }

    public void setUserProfile(UserProfile userProfile) {
        this.userProfile = userProfile;
    }

    public GridMeta getAdhocReportsMeta() {
        return adhocReportsMeta;
    }

    public void setAdhocReportsMeta(GridMeta adhocReportsMeta) {
        this.adhocReportsMeta = adhocReportsMeta;
    }

    /**
     * Couldn't be a null object
     *
     * @return parameters map
     */
    public Map getApplicationSpecificData() {
        return applicationSpecificData;
    }

    public void setApplicationSpecificData(Map applicationSpecificData) {
        if(applicationSpecificData != null) {
            this.applicationSpecificData = applicationSpecificData;
        } else {
            this.applicationSpecificData = new HashMap();
        }
    }

    public FocusMeta.Index getDefaultFocusIndex() {
        return defaultFocusIndex;
    }

    public void setDefaultFocusIndex(FocusMeta.Index defaultFocusIndex) {
        this.defaultFocusIndex = defaultFocusIndex;
    }

    public ArrayList getAllTabMetas() {
        ArrayList al = new ArrayList();
        for(int i = 0; i < focuses.length; i++) {
            al.addAll(focuses[i].getAllTabMetas());
        }
        return al;
    }

    public FocusMeta getFocusMeta(FocusMeta.Index index) {
        return focuses[index.focus];
    }

    public ProductMeta getProductMeta() {
        return productMeta;
    }

    public void setProductMeta(ProductMeta productMeta) {
        this.productMeta = productMeta;
    }

    public FormMeta getFormMeta(FamgMeta.Index index) {
        return getFamgMeta(index).getForm();
    }

    public PortalConfigMeta getPortalConfigMeta() {
        return portalConfigMeta;
    }

    public void setPortalConfigMeta(PortalConfigMeta portalConfigMeta) {
        this.portalConfigMeta = portalConfigMeta;
    }

    public int getCheckMailTimeout() {
        return checkMailTimeout;
    }

    public void setCheckMailTimeout(int checkMailTimeout) {
        this.checkMailTimeout = checkMailTimeout;
    }
}
