/*
 * 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.google.gwt.user.client.rpc.SerializableException;

/**
 * Form and main grid metadata container. It describes relationships of form and main grid. Connection has 1..0 to 1..0 type,
 * One of main grid or form can be null.
 *
 * @author Sergey Kozmin
 * @since 16.10.2006, 18:50:52
 */
public class FamgMeta implements IsSerializable {
    private Index index;
    private String formID;
    private FormMeta form;
    private GridMeta grid;

    public FamgMeta(FormMeta form, GridMeta grid, String formID) {
        index = new Index();
        this.formID = formID;
        this.form = form;
        this.grid = grid;
    }

    public FamgMeta() {
        this(new FormMeta(), new GridMeta(), "");
    }

    void initIndexes(TabMeta.Index tabIndex, int famgIndex) {
        index.init(tabIndex, famgIndex);
        initChildrenIndexes();
    }

    private void initChildrenIndexes() {
        form.setIndex(index);
        grid.setIndex(index);
    }

    public FormMeta getForm() {
        return form;
    }

    public void setForm(FormMeta form) {
        this.form = form;
        initChildrenIndexes();
    }

    public GridMeta getGrid() {
        return grid;
    }

    public void setGrid(GridMeta grid) {
        this.grid = grid;
        initChildrenIndexes();
    }

    public Index getIndex() {
        return index;
    }

    public void setIndex(Index index) {
        this.index = index;
    }

    public String getFormID() {
        return formID;
    }

    public String getEntityName() {
        String ret = null;
        if(formID != null) {
            ret = formID.substring(formID.lastIndexOf("__") + 2);
        }
        return ret;
    }

    public void setFormID(String formID) {
        this.formID = formID;
    }

    public boolean isMyQueWeb() {
        return "MyQueWeb".equalsIgnoreCase(formID);
    }

    public static class Index extends TabMeta.Index {
        public int getType() {
            return FAMG;
        }

        private static final String HISTORY_INDEX_SEPARATOR = ".";

        public int famg;

        public void init(TabMeta.Index tabIndex, int famgIndex) {
            super.init(tabIndex, tabIndex.tab);
            this.famg = famgIndex;
        }

        public int hashCode() {
            //each index will not be greater then 32 hence we can use shift register operations.
            return focus << 12 | subFocus << 8 | tab << 4 | famg;
        }

        public boolean equals(Object obj) {
            if(obj == null) {
                return false;
            }
            if(!(obj instanceof Index)) {
                return false;
            } else {
                Index indx = (Index) obj;
                return indx.focus == focus && indx.subFocus == subFocus
                        && indx.tab == tab && indx.famg == famg;
            }
        }

        public String serialize() {
            return serialize(this);
        }

        public static String serialize(Index index) {
            return index.focus + HISTORY_INDEX_SEPARATOR + index.subFocus
                    + HISTORY_INDEX_SEPARATOR + index.tab
                    + HISTORY_INDEX_SEPARATOR + index.famg;
        }

        public static Index deSerialize(String str)
                throws SerializableException {
            if(str == null) {
                throw new SerializableException(
                        "Index could not be null string.");
            }
            Index index = new Index();
            String regexp = ("\\" + HISTORY_INDEX_SEPARATOR);
            String[] strs = str.split(regexp);
            if(strs.length < 4) {
                throw new SerializableException(
                        "Incorrect FAMG index format[" + str +
                                "]. Should be 4 positive integers divided by ["
                                + HISTORY_INDEX_SEPARATOR + "].");
            }
            try {
                index.focus = Integer.parseInt(strs[0]);
                index.subFocus = Integer.parseInt(strs[1]);
                index.tab = Integer.parseInt(strs[2]);
                index.famg = Integer.parseInt(strs[3]);
            } catch (NumberFormatException e) {
                throw new SerializableException(
                        "Incorrect FAMG index format[" + str +
                                "]. Should be 4 positive integers divided by ["
                                + HISTORY_INDEX_SEPARATOR + "].");
            }
            return index;
        }
    }
}
