/*
 * 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.modules.config.ejb;

import com.queplix.core.modules.config.jxb.ContextMenu;
import com.queplix.core.modules.config.jxb.ContextMenuForm;
import com.queplix.core.modules.config.jxb.MenuItem;
import com.queplix.core.modules.config.utils.ConfigPropertyFactory;
import com.queplix.core.utils.JNDINames;
import com.queplix.core.utils.cache.Cache;
import com.queplix.core.utils.ejb.AbstractSessionEJB;
import com.queplix.core.utils.xml.XMLFactory;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Facade EJB for ContextMenu management.
 *
 * @author [MVT] Michael Trofimov
 * @version $Revision$ $Date$
 */
public class ContextMenuConfigManagerEJB extends AbstractSessionEJB {

    /**
     * Initialize bean
     */
    public void ejbCreate() {
        INFO(getClass().getName() + " create - " + hashCode());
    }

    // ---------------------------------------------------------------
    // ContextMenu management.
    // ---------------------------------------------------------------

    /**
     * Returns array of all ContextMenu objects
     */
    public ContextMenu[] getContextMenus() {
        long time = System.currentTimeMillis();

        if(getLogger().isDebugEnabled()) {
            DEBUG("Try to get all context menu objects");
        }
        ContextMenu[] contextMenus;

        Cache cache = ConfigPropertyFactory.getInstance()
                .getContextMenuConfigCache();
        if(cache.isOpen()) {
            contextMenus = ConfigPropertyFactory.getInstance()
                    .getContextMenuConfigDAO().loadContextMenusVO();

            synchronized(cache) {
                cache.clear();
                if(contextMenus != null) {
                    for(int i = 0; i < contextMenus.length; i++) {
                        ContextMenu contextMenu = contextMenus[i];
                        cache.put(contextMenu.getName(), contextMenu);
                    }
                }
                cache.close();
            }

        } else {
            List<ContextMenu> menus = new ArrayList<ContextMenu>();
            for(Iterator it = cache.values().iterator(); it.hasNext();) {
                menus.add((ContextMenu) it.next());
            }
            contextMenus = menus.toArray(new ContextMenu[menus.size()]);
        }

        if(getLogger().isDebugEnabled()) {
            DEBUG("Get all context menus - ok. Time (ms): " + (
                    System.currentTimeMillis() - time));
        }

        return contextMenus;
    }

    public ContextMenu getContextMenuByForm(String formName) {
        if(formName == null) {
            throw new IllegalArgumentException("formName could not be a null");
        }

        ContextMenu result = new ContextMenu();
//        XMLFactory.getXMLBinding().clone(contextMenu, ContextMenu.class);

        ContextMenu[] menus = getContextMenus();
        for(ContextMenu menu : menus) {
            for(ContextMenuForm menuForm : menu.getContextMenuForm()) {
                if(formName.equals(menuForm.getName())) {
//                    return cloneContextMenu(menu);
                    joinContextMenu(result, menu);
                }
            }
        }
        return result;
    }

    private void joinContextMenu(ContextMenu dest, ContextMenu src) {
        List<String> formNames = new ArrayList<String>();
        for(ContextMenuForm form : dest.getContextMenuForm()) {
            formNames.add(form.getName());
        }
        for(ContextMenuForm form : src.getContextMenuForm()) {
            if(formNames.contains(form.getName())) {
                continue;
            }

            dest.addContextMenuForm(form);
            formNames.add(form.getName());
        }

        int idx = dest.getMenuItemCount();
        for(MenuItem menuItem : src.getMenuItem()) {
            MenuItem item = (MenuItem) XMLFactory.getXMLBinding().clone(
                    menuItem, MenuItem.class);
            item.setOrder(idx++);
            dest.addMenuItem(item);
        }
    }


    public ContextMenu getLocalizedContextMenu(String langId,
                                               ContextMenu contextMenu) {
        if(contextMenu == null) {
            throw new IllegalArgumentException(
                    "contextMenu could not be a null");
        }

        ContextMenu result = cloneContextMenu(contextMenu);
        localizeContextMenu(langId, result);
        return result;
    }

    /**
     * Fills in the array of ContextMenus objects.
     *
     * @param contextMenus array of ContextMenus objects
     * @return Number of affected records
     */
    public int fillContextMenus(ContextMenu[] contextMenus) {

        long time = System.currentTimeMillis();
        DEBUG("Try to fill all context menu configs");

        Cache cache = ConfigPropertyFactory.getInstance()
                .getContextMenuConfigCache();
        cache.clear();

        ConfigPropertyFactory.getInstance().getContextMenuConfigDAO()
                .clearContextMenusVO();

        int updated = ConfigPropertyFactory.getInstance()
                .getContextMenuConfigDAO().storeContextMenusVO(contextMenus);

        updateCaptions(contextMenus);

        DEBUG("Fill all context menu configs. Count " + updated +
                ". Time (ms): " + (System.currentTimeMillis() - time));

        return updated;
    }

    private void updateCaptions(ContextMenu[] contextMenus) {
        CaptionManagerLocal cml = getCaptonManagerLocal();

        for(ContextMenu contextMenu : contextMenus) {
            for(MenuItem menuItem : contextMenu.getMenuItem()) {
                if(menuItem.getCaptions() != null) {
                    cml.fillMenuItemCaptions(menuItem.getName(),
                            menuItem.getCaptions());
                }
            }
        }
    }

    private ContextMenu cloneContextMenu(ContextMenu contextMenu) {
        return (ContextMenu) XMLFactory.getXMLBinding().clone(contextMenu,
                ContextMenu.class);

    }

    private void localizeContextMenu(String langId, ContextMenu contextMenu) {
        CaptionManagerLocal manager = getCaptonManagerLocal();
        for(MenuItem menuItem : contextMenu.getMenuItem()) {
            menuItem.setCaption(manager.getMenuItemCaption(langId,
                    menuItem.getName()));
        }
    }

    private CaptionManagerLocal getCaptonManagerLocal() {
        return (CaptionManagerLocal) getLocalObject(
                JNDINames.CaptionManager, CaptionManagerLocalHome.class);
    }


}
