/*
 *
 * Paros and its related class files.
 * 
 * Paros is an HTTP/HTTPS proxy for assessing web application security.
 * Copyright (C) 2003-2004 Chinotec Technologies Company
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Clarified Artistic License
 * as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Clarified Artistic License for more details.
 * 
 * You should have received a copy of the Clarified Artistic License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.parosproxy.paros.extension;

import java.util.List;
import java.util.Vector;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import org.parosproxy.paros.control.Proxy;
import org.parosproxy.paros.core.proxy.ProxyListener;
import org.parosproxy.paros.model.Model;
import org.parosproxy.paros.model.OptionsParam;
import org.parosproxy.paros.model.Session;
import org.parosproxy.paros.view.AbstractParamDialog;
import org.parosproxy.paros.view.AbstractParamPanel;
import org.parosproxy.paros.view.TabbedPanel;
import org.parosproxy.paros.view.View;


/**
 *
 * To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
public class ExtensionLoader {

    private Vector extensionList = new Vector();
    private Vector hookList = new Vector();

    private View view = null;
    private Model model = null;

    public ExtensionLoader(Model model, View view) {
        
        this.model = model;
        this.view = view;
    }
    
    private void addParamPanel(List panelList, AbstractParamDialog dialog) {
        AbstractParamPanel panel = null;
        String[] ROOT = {};
        for (int i=0; i<panelList.size(); i++) {
            try {
                panel = (AbstractParamPanel) panelList.get(i);
                dialog.addParamPanel(ROOT, panel);
            } catch (Exception e) {
                
            }
        }
        
    }

    public void addExtension(Extension extension) {
        extensionList.add(extension);
    }
    
    private void addTabPanel(List panelList, TabbedPanel tab) {
        AbstractPanel panel = null;
        for (int i=0; i<panelList.size(); i++) {
            try {
                panel = (AbstractPanel) panelList.get(i);
                tab.add(panel, panel.getName());
            } catch (Exception e) {
                
            }
        }
    }
    
    public void destroyAllExtension() {
        for (int i=0; i<getExtensionCount(); i++) {
            getExtension(i).destroy();
        }
        
    }
    
    public Extension getExtension(int i) {
        return (Extension) extensionList.get(i);
    }
    
    public Extension getExtension(String name) {
        if (name == null)
            return null;

        for (int i=0; i<extensionList.size(); i++) {
            Extension p = getExtension(i);
            if (p.getName().equalsIgnoreCase(name)) {
                return p;
            }
        }
        
        return null;
    }
    
    public int getExtensionCount() {
        return extensionList.size();
    }
    
    private void initAllExtension() {

        for (int i=0; i<getExtensionCount(); i++) {
            getExtension(i).init();
        }
    }
    

    
    private void initModelAllExtension(Model model) {
        for (int i=0; i<getExtensionCount(); i++) {
            getExtension(i).initModel(model);
        }
        
    }
    
    private void hookMenu(View view, ExtensionHook hook) {

        if (view == null) {
            return;
        }
        
        if (hook.getHookMenu() == null) {
            return;
        }
        
        ExtensionHookMenu hookMenu = hook.getHookMenu();
        
        // init menus
        List list = null;
        JMenuItem item = null;
        JMenu menu = null;
        JMenu menuTools = view.getMainFrame().getMainMenuBar().getMenuTools();
        JMenu menuEdit = view.getMainFrame().getMainMenuBar().getMenuEdit();
        JMenu menuView = view.getMainFrame().getMainMenuBar().getMenuView();
        
        // process new menus

        JMenuBar bar = view.getMainFrame().getMainMenuBar();
        list = hookMenu.getNewMenus();
        for (int i=0; i<list.size(); i++) {
            menu = (JMenu) list.get(i);
            bar.add(menu, bar.getMenuCount()-2);	// 2 menus at the back (Tools/Help)
        }
        
        // process menu - Tools
        list = hookMenu.getTools();
        int existingCount = 2;
        
        for (int i=0; i<list.size(); i++) {
            item = (JMenuItem) list.get(i);
            if (item == null) continue;
            menuTools.add(item, menuTools.getItemCount()-existingCount);
        }

        // process Edit menu
        list = hookMenu.getEdit();
        
        for (int i=0; i<list.size(); i++) {
            item = (JMenuItem) list.get(i);
            if (item == null) continue;
            menuEdit.add(item, menuEdit.getItemCount());
        }

        // process View menu
        list = hookMenu.getView();
        
        for (int i=0; i<list.size(); i++) {
            item = (JMenuItem) list.get(i);
            if (item == null) continue;
            menuView.add(item, menuView.getItemCount());
        }
        
        // process popup menus
        
        list = hookMenu.getPopupMenus();
        
        for (int i=0; i<list.size(); i++) {
            item = (ExtensionPopupMenu) list.get(i);
            if (item == null) continue;
            view.getPopupList().add(item);
        }

    }


    
    private void hookView(View view, ExtensionHook hook) {
        if (view == null) {
            return;
        }
        
        ExtensionHookView pv = hook.getHookView();
        if (pv == null) {
            return;
        }
        
        addTabPanel(pv.getSelectPanel(), view.getWorkbench().getTabbedSelect());
        addTabPanel(pv.getWorkPanel(), view.getWorkbench().getTabbedWork());
        addTabPanel(pv.getStatusPanel(), view.getWorkbench().getTabbedStatus());
 
        addParamPanel(pv.getSessionPanel(), view.getSessionDialog(""));
        addParamPanel(pv.getOptionsPanel(), view.getOptionsDialog(""));
        
        
    }

    private void initViewAllExtension(View view) {

        if (view == null) {
            return;
        }
        
        for (int i=0; i<getExtensionCount(); i++) {
            getExtension(i).initView(view);
        }

    }

    private void initXMLAllExtension(Session session, OptionsParam options) {
        for (int i=0; i<getExtensionCount(); i++) {
            getExtension(i).initXML(session, options);
        }        
    }
    

    public void startAllExtension() {
        for (int i=0; i<getExtensionCount(); i++) {
            getExtension(i).start();
        }
        
    }


    
    
    private void hookAllExtension() {
        ExtensionHook pluginHook = null;
        for (int i=0; i<getExtensionCount(); i++) {
            pluginHook = new ExtensionHook(model, view);
            getExtension(i).hook(pluginHook);
            hookList.add(pluginHook);
            hookView(view, pluginHook);
            hookMenu(view, pluginHook);
        }
        
        if (view != null) {
            view.getMainFrame().getMainMenuBar().validate();
            view.getMainFrame().validate();
        }

    }
    
    public void startLifeCycle() {
        initAllExtension();
        initModelAllExtension(model);
        initXMLAllExtension(model.getSession(), model.getOptionsParam());
        initViewAllExtension(view);
        
        hookAllExtension();
        startAllExtension();
        
    }
    
    public void stopAllExtension() {
        for (int i=0; i<getExtensionCount(); i++) {
            getExtension(i).stop();
        }
        
    }
    
    public void sessionChangedAllPlugin(Session session) {
        for (int i=0; i<getExtensionCount(); i++) {
            ExtensionHook hook = (ExtensionHook) hookList.get(i);
            List listenerList = hook.getSessionListenerList();
            for (int j=0; j<listenerList.size(); j++) {
                try {
                    SessionChangedListener listener = (SessionChangedListener) listenerList.get(j);
                    if (listener != null) {
                        listener.sessionChanged(session);
                    }
                } catch (Exception e) {}
            }
            
        }
    }
    
    public void optionsChangedAllPlugin(OptionsParam options) {
        for (int i=0; i<getExtensionCount(); i++) {
            ExtensionHook hook = (ExtensionHook) hookList.get(i);
            List listenerList = hook.getOptionsListenerList();
            for (int j=0; j<listenerList.size(); j++) {
                try {
                    OptionsListener listener = (OptionsListener) listenerList.get(j);
                    if (listener != null) {
                        listener.OptionsChanged(options);
                    }
                } catch (Exception e) {}
            }
            
        }
    }
    
    public void hookProxyListener(Proxy proxy) {
        for (int i=0; i<getExtensionCount(); i++) {
            ExtensionHook hook = (ExtensionHook) hookList.get(i);
            List listenerList = hook.getProxyListenerList();
            for (int j=0; j<listenerList.size(); j++) {
                try {
                    ProxyListener listener = (ProxyListener) listenerList.get(j);
                    if (listener != null) {
                        proxy.addProxyListener(listener);
                    }
                } catch (Exception e) {}
            }
        }
        
    }
}
