/*
 * {{{ header & license
 * Copyright (c) 2004 Joshua Marinacci
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * 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
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public 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.xhtmlrenderer.demo.browser;

import org.xhtmlrenderer.demo.browser.actions.ZoomAction;
import org.xhtmlrenderer.swing.*;
import org.xhtmlrenderer.util.Configuration;
import org.xhtmlrenderer.util.Uu;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.List;

/**
 * Description of the Class
 *
 * @author empty
 */
public class BrowserMenuBar extends JMenuBar {
    /**
     * Description of the Field
     */
    BrowserStartup root;

    /**
     * Description of the Field
     */
    JMenu file;
    /**
     * Description of the Field
     */
    JMenu edit;
    /**
     * Description of the Field
     */
    JMenu view;
    /**
     * Description of the Field
     */
    JMenu go;
    /**
     * Description of the Field
     */
    JMenuItem view_source;
    /**
     * Description of the Field
     */
    JMenu debug;
    /**
     * Description of the Field
     */
    JMenu demos;
    /**
     *
     */
    private String lastDemoOpened;

    /**
     * Description of the Field
     */
    private Map allDemos;
    private JMenu help;

    /**
     * Constructor for the BrowserMenuBar object
     *
     * @param root PARAM
     */
    public BrowserMenuBar(BrowserStartup root) {
        this.root = root;
    }

    /**
     * Description of the Method
     */
    public void init() {
        file = new JMenu("Browser");
        file.setMnemonic('B');

        debug = new JMenu("Debug");
        debug.setMnemonic('U');

        demos = new JMenu("Demos");
        demos.setMnemonic('D');

        view = new JMenu("View");
        view.setMnemonic('V');

        help = new JMenu("Help");
        help.setMnemonic('H');

        view_source = new JMenuItem("Page Source");
        view_source.setEnabled(false);
        view.add(root.actions.stop);
        view.add(root.actions.refresh);
        view.add(root.actions.reload);
        view.add(new JSeparator());
        JMenu text_size = new JMenu("Text Size");
        text_size.setMnemonic('T');
        text_size.add(root.actions.increase_font);
        text_size.add(root.actions.decrease_font);
        text_size.add(new JSeparator());
        text_size.add(root.actions.reset_font);
        view.add(text_size);

        go = new JMenu("Go");
        go.setMnemonic('G');
    }


    /**
     * Description of the Method
     */
    public void createLayout() {
        final ScalableXHTMLPanel panel = root.panel.view;

        file.add(root.actions.open_file);
        file.add(new JSeparator());
        file.add(root.actions.export_pdf);
        file.add(new JSeparator());
        file.add(root.actions.quit);
        add(file);

        /*
        // TODO: we can get the document and format it, but need syntax highlighting
        // and a tab or separate window, dialog, etc.
        view_source.setAction(new ViewSourceAction(panel));
        view.add(view_source);
        */

        JMenu zoom = new JMenu("Zoom");
        zoom.setMnemonic('Z');
        ScaleFactor[] factors = this.initializeScales();
        ButtonGroup zoomGroup = new ButtonGroup();
        for (int i = 0; i < factors.length; i++) {
            ScaleFactor factor = factors[i];
            JRadioButtonMenuItem item = new JRadioButtonMenuItem(new ZoomAction(panel, factor));

            if (factor.isNotZoomed()) item.setSelected(true);

            zoomGroup.add(item);
            zoom.add(item);
        }
        view.add(new JSeparator());
        view.add(zoom);
        view.add(new JSeparator());
        view.add(new JCheckBoxMenuItem(root.actions.print_preview));
        add(view);

        go.add(root.actions.forward);
        go.add(root.actions.backward);

        add(go);

        demos.add(new NextDemoAction());
        demos.add(new PriorDemoAction());
        demos.add(new JSeparator());
        allDemos = new LinkedHashMap();

        populateDemoList();

        for (Iterator iter = allDemos.keySet().iterator(); iter.hasNext();) {
            String s = (String) iter.next();
            demos.add(new LoadAction(s, (String) allDemos.get(s)));
        }

        add(demos);

        JMenu debugShow = new JMenu("Show");
        debug.add(debugShow);
        debugShow.setMnemonic('S');

        debugShow.add(new JCheckBoxMenuItem(new BoxOutlinesAction()));
        debugShow.add(new JCheckBoxMenuItem(new LineBoxOutlinesAction()));
        debugShow.add(new JCheckBoxMenuItem(new InlineBoxesAction()));
        debugShow.add(new JCheckBoxMenuItem(new FontMetricsAction()));

        JMenu anti = new JMenu("Anti Aliasing");
        ButtonGroup anti_level = new ButtonGroup();
        addLevel(anti, anti_level, "None", -1);
        addLevel(anti, anti_level, "Low", 25).setSelected(true);
        addLevel(anti, anti_level, "Medium", 12);
        addLevel(anti, anti_level, "High", 0);
        debug.add(anti);


        debug.add(new ShowDOMInspectorAction());
        debug.add(new AbstractAction("Validation Console") {
            public void actionPerformed(ActionEvent evt) {
                if (root.validation_console == null) {
                    root.validation_console = new JFrame("Validation Console");
                    JFrame frame = root.validation_console;
                    JTextArea jta = new JTextArea();

                    root.error_handler.setTextArea(jta);

                    jta.setEditable(false);
                    jta.setLineWrap(true);
                    jta.setText("Validation Console: XML Parsing Error Messages");

                    frame.getContentPane().setLayout(new BorderLayout());
                    frame.getContentPane().add(new JScrollPane(jta), "Center");
                    JButton close = new JButton("Close");
                    frame.getContentPane().add(close, "South");
                    close.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent evt) {
                            root.validation_console.setVisible(false);
                        }
                    });

                    frame.pack();
                    frame.setSize(400, 300);
                }
                root.validation_console.setVisible(true);
            }
        });

        debug.add(root.actions.generate_diff);
        add(debug);

        help.add(root.actions.usersManual);
        help.add(new JSeparator());
        help.add(root.actions.aboutPage);
        add(help);
    }

    private void populateDemoList() {
        List demoList = new ArrayList();
        URL url = BrowserMenuBar.class.getResource("/demos/file-list.txt");
        if (url != null) {
            try {
                InputStream is = url.openStream();
                InputStreamReader reader = new InputStreamReader(is);
                LineNumberReader lnr = new LineNumberReader(reader);
                String line = null;
                while ((line = lnr.readLine()) != null) {
                    demoList.add(line);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            for (Iterator itr = demoList.iterator(); itr.hasNext();) {
                String s = (String) itr.next();
                String s1[] = s.split(",");
                allDemos.put(s1[0], s1[1]);
            }
        }
    }

    private JRadioButtonMenuItem addLevel(JMenu menu, ButtonGroup group, String title, int level) {
        JRadioButtonMenuItem item = new JRadioButtonMenuItem(new AntiAliasedAction(title, level));
        group.add(item);
        menu.add(item);
        return item;
    }


    /**
     * Description of the Method
     */
    public void createActions() {
        if (Configuration.isTrue("xr.use.listeners", true)) {
            List l = root.panel.view.getMouseTrackingListeners();
            for (Iterator i = l.iterator(); i.hasNext(); ) {
                FSMouseListener listener = (FSMouseListener)i.next();
                if ( listener instanceof LinkListener ) {
                    root.panel.view.removeMouseTrackingListener(listener);
                }
            }

            root.panel.view.addMouseTrackingListener(new LinkListener() {
               public void linkClicked(BasicPanel panel, String uri) {
                   if (uri.startsWith("demoNav")) {
                       String pg = uri.split(":")[1];
                       if (pg.equals("back")) {
                           navigateToPriorDemo();
                       } else {
                           navigateToNextDemo();
                       }
                   } else {
                       super.linkClicked(panel, uri);
                   }
               } 
            });
        }
    }

    private ScaleFactor[] initializeScales() {
        ScaleFactor[] scales = new ScaleFactor[11];
        int i = 0;
        scales[i++] = new ScaleFactor(1.0d, "Normal (100%)");
        scales[i++] = new ScaleFactor(2.0d, "200%");
        scales[i++] = new ScaleFactor(1.5d, "150%");
        scales[i++] = new ScaleFactor(0.85d, "85%");
        scales[i++] = new ScaleFactor(0.75d, "75%");
        scales[i++] = new ScaleFactor(0.5d, "50%");
        scales[i++] = new ScaleFactor(0.33d, "33%");
        scales[i++] = new ScaleFactor(0.25d, "25%");
        scales[i++] = new ScaleFactor(ScaleFactor.PAGE_WIDTH, "Page width");
        scales[i++] = new ScaleFactor(ScaleFactor.PAGE_HEIGHT, "Page height");
        scales[i++] = new ScaleFactor(ScaleFactor.PAGE_WHOLE, "Whole page");
        return scales;
    }

    /**
     * Description of the Class
     *
     * @author empty
     */
    class ShowDOMInspectorAction extends AbstractAction {
        /**
         * Description of the Field
         */
        private DOMInspector inspector;
        /**
         * Description of the Field
         */
        private JFrame inspectorFrame;

        /**
         * Constructor for the ShowDOMInspectorAction object
         */
        ShowDOMInspectorAction() {
            super("DOM Tree Inspector");
            putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_D));
        }

        /**
         * Description of the Method
         *
         * @param evt PARAM
         */
        public void actionPerformed(ActionEvent evt) {
            if (inspectorFrame == null) {
                inspectorFrame = new JFrame("DOM Tree Inspector");
            }
            if (inspector == null) {
                inspector = new DOMInspector(root.panel.view.getDocument(), root.panel.view.getSharedContext(), root.panel.view.getSharedContext().getCss());

                inspectorFrame.getContentPane().add(inspector);

                inspectorFrame.pack();
                inspectorFrame.setSize(500, 600);
                inspectorFrame.show();
            } else {
                inspector.setForDocument(root.panel.view.getDocument(), root.panel.view.getSharedContext(), root.panel.view.getSharedContext().getCss());
            }
            inspectorFrame.show();
        }
    }

    /**
     * Description of the Class
     *
     * @author empty
     */
    class BoxOutlinesAction extends AbstractAction {
        /**
         * Constructor for the BoxOutlinesAction object
         */
        BoxOutlinesAction() {
            super("Show Box Outlines");
            putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_B));
        }

        /**
         * Description of the Method
         *
         * @param evt PARAM
         */
        public void actionPerformed(ActionEvent evt) {
            root.panel.view.getSharedContext().setDebug_draw_boxes(!root.panel.view.getSharedContext().debugDrawBoxes());
            root.panel.view.repaint();
        }
    }

    /**
     * Description of the Class
     *
     * @author empty
     */
    class LineBoxOutlinesAction extends AbstractAction {
        /**
         * Constructor for the LineBoxOutlinesAction object
         */
        LineBoxOutlinesAction() {
            super("Show Line Box Outlines");
            putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_L));
        }

        /**
         * Description of the Method
         *
         * @param evt PARAM
         */
        public void actionPerformed(ActionEvent evt) {
            root.panel.view.getSharedContext().setDebug_draw_line_boxes(!root.panel.view.getSharedContext().debugDrawLineBoxes());
            root.panel.view.repaint();
        }
    }

    /**
     * Description of the Class
     *
     * @author empty
     */
    class InlineBoxesAction extends AbstractAction {
        /**
         * Constructor for the InlineBoxesAction object
         */
        InlineBoxesAction() {
            super("Show Inline Boxes");
            putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_I));
        }

        /**
         * Description of the Method
         *
         * @param evt PARAM
         */
        public void actionPerformed(ActionEvent evt) {
            root.panel.view.getSharedContext().setDebug_draw_inline_boxes(!root.panel.view.getSharedContext().debugDrawInlineBoxes());
            root.panel.view.repaint();
        }
    }

    class FontMetricsAction extends AbstractAction {
        /**
         * Constructor for the InlineBoxesAction object
         */
        FontMetricsAction() {
            super("Show Font Metrics");
            putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_F));
        }

        /**
         * Description of the Method
         *
         * @param evt PARAM
         */
        public void actionPerformed(ActionEvent evt) {
            root.panel.view.getSharedContext().setDebug_draw_font_metrics(!root.panel.view.getSharedContext().debugDrawFontMetrics());
            root.panel.view.repaint();
        }
    }

    class NextDemoAction extends AbstractAction {

        public NextDemoAction() {
            super("Next Demo Page");
            putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_N));
            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
        }

        /**
         * Invoked when an action occurs.
         */
        public void actionPerformed(ActionEvent e) {
            navigateToNextDemo();
        }
    }

    public void navigateToNextDemo() {
        String nextPage = null;
        for (Iterator iter = allDemos.keySet().iterator(); iter.hasNext();) {
            String s = (String) iter.next();
            if (s.equals(lastDemoOpened)) {
                if (iter.hasNext()) {
                    nextPage = (String) iter.next();
                    break;
                }
            }
        }
        if (nextPage == null) {
            // go to first page
            Iterator iter = allDemos.keySet().iterator();
            nextPage = (String) iter.next();
        }

        try {
            root.panel.loadPage((String) allDemos.get(nextPage));
            lastDemoOpened = nextPage;
        } catch (Exception ex) {
            Uu.p(ex);
        }
    }

    class PriorDemoAction extends AbstractAction {

        public PriorDemoAction() {
            super("Prior Demo Page");
            putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_P));
            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_P, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
        }

        /**
         * Invoked when an action occurs.
         */
        public void actionPerformed(ActionEvent e) {
            navigateToPriorDemo();
        }
    }

    public void navigateToPriorDemo() {
        String priorPage = null;
        for (Iterator iter = allDemos.keySet().iterator(); iter.hasNext();) {
            String s = (String) iter.next();
            if (s.equals(lastDemoOpened)) {
                break;
            }
            priorPage = s;
        }
        if (priorPage == null) {
            // go to last page
            Iterator iter = allDemos.keySet().iterator();
            while (iter.hasNext()) {
                priorPage = (String) iter.next();
            }
        }

        try {
            root.panel.loadPage((String) allDemos.get(priorPage));
            lastDemoOpened = priorPage;
        } catch (Exception ex) {
            Uu.p(ex);
        }
    }

    /**
     * Description of the Class
     *
     * @author empty
     */
    class LoadAction extends AbstractAction {
        /**
         * Description of the Field
         */
        protected String url;

        private String pageName;

        /**
         * Constructor for the LoadAction object
         *
         * @param name PARAM
         * @param url  PARAM
         */
        public LoadAction(String name, String url) {
            super(name);
            pageName = name;
            this.url = url;
        }

        /**
         * Description of the Method
         *
         * @param evt PARAM
         */
        public void actionPerformed(ActionEvent evt) {
            try {
                root.panel.loadPage(url);
                lastDemoOpened = pageName;
            } catch (Exception ex) {
                Uu.p(ex);
            }
        }

    }

    class AntiAliasedAction extends AbstractAction {
        int fontSizeThreshold;

        AntiAliasedAction(String text, int fontSizeThreshold) {
            super(text);
            this.fontSizeThreshold = fontSizeThreshold;
        }

        public void actionPerformed(ActionEvent evt) {
            root.panel.view.getSharedContext().getTextRenderer().setSmoothingThreshold(fontSizeThreshold);
            root.panel.view.repaint();
        }
    }

}


/**
 * Description of the Class
 *
 * @author empty
 */
class EmptyAction extends AbstractAction {
    public EmptyAction(String name, Icon icon) {
        this(name, "", icon);
    }

    public EmptyAction(String name, String shortDesc, Icon icon) {
        super(name, icon);
        putValue(Action.SHORT_DESCRIPTION, shortDesc);
    }

    /**
     * Constructor for the EmptyAction object
     *
     * @param name  PARAM
     * @param accel PARAM
     */
    public EmptyAction(String name, int accel) {
        this(name);
        putValue(Action.ACCELERATOR_KEY,
                KeyStroke.getKeyStroke(accel,
                        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
    }

    /**
     * Constructor for the EmptyAction object
     *
     * @param name PARAM
     */
    public EmptyAction(String name) {
        super(name);
    }

    /**
     * Description of the Method
     *
     * @param evt PARAM
     */
    public void actionPerformed(ActionEvent evt) {
    }
}

/*
* $Id: BrowserMenuBar.java,v 1.50 2009/03/22 15:13:24 pdoubleya Exp $
*
* $Log: BrowserMenuBar.java,v $
* Revision 1.50  2009/03/22 15:13:24  pdoubleya
* Follow up for removing Minium AA: font "smoothing level" now deprecated. Changed to use font smoothing threshold alone. Remove corresponding property from configuration file.
*
* Revision 1.49  2009/03/22 12:27:38  pdoubleya
* Remove Minium anti-aliasing library as sources are not available. Removed jar and all references to it. For R8 release.
*
* Revision 1.48  2009/02/15 19:57:49  pdoubleya
* Remove references to "r7", and move browser demos to top-level xhtml directory.
*
* Revision 1.47  2008/09/06 18:44:29  peterbrant
* Add PDF export to browser (patch from Mykola Gurov)
*
* Revision 1.46  2007/11/01 00:18:31  peterbrant
* Adapt to R7 mouse tracking API
*
* Revision 1.45  2007/07/14 17:38:17  pdoubleya
* fix menu accelerator assignments to be cross-platform compatible (esp. with OS X)
*
* Revision 1.44  2007/07/13 13:32:31  pdoubleya
* Add webstart entry point for browser with no URL or File/open option. Move Zoom to menu entry, add warning on first zoom. Move preview to menu entry. Reorganize launch method a little to allow for multiple entry points.
*
* Revision 1.43  2007/05/24 13:22:39  peterbrant
* Optimize and clean up hover and link listeners
*
* Patch from Sean Bright
*
* Revision 1.42  2007/04/12 12:39:25  peterbrant
* Fix NPE if demo list is not found
*
* Revision 1.41  2007/04/11 21:07:02  pdoubleya
* Prepare to point to R7 versions of files
*
* Revision 1.40  2007/02/07 16:33:38  peterbrant
* Initial commit of rewritten table support and associated refactorings
*
* Revision 1.39  2006/08/06 21:27:00  pdoubleya
* Removed printing for R6.
*
* Revision 1.38  2006/07/31 14:20:54  pdoubleya
* Bunch of cleanups and fixes. Now using a toolbar for actions, added Home button, next/prev navigation actions to facilitate demo file browsing, loading demo pages from a list, about dlg and link to user's manual.
*
* Revision 1.37  2006/01/09 23:24:53  peterbrant
* Provide config key to not use link and hover listeners (one of which currently leaks memory horribly)
*
* Revision 1.36  2005/10/27 00:08:50  tobega
* Sorted out Context into RenderingContext and LayoutContext
*
* Revision 1.35  2005/10/20 20:31:04  pdoubleya
* Cleaned imports.
*
* Revision 1.34  2005/08/16 22:46:27  joshy
* added new demos, streamlined downloads
*
* Revision 1.33  2005/07/31 01:12:29  joshy
* updated browser demos, about box demos, and added pack200 to the distro
*
* Revision 1.32  2005/07/21 21:51:07  joshy
* added new demos to browser
*
* Revision 1.31  2005/07/13 22:49:14  joshy
* updates to get the jnlp to work without being signed
*
* Revision 1.30  2005/03/28 20:03:14  pdoubleya
* Icon/menu bar assignments.
*
* Revision 1.29  2005/03/28 19:04:17  pdoubleya
* Moved text size controls on menu, cleaned list of pages.
*
* Revision 1.28  2005/01/29 12:24:57  pdoubleya
* .
*
* Revision 1.27  2005/01/25 11:51:39  pdoubleya
* Added next and prior page; refactored demos into Map for manipulation.
*
* Revision 1.26  2004/12/29 10:39:38  tobega
* Separated current state Context into LayoutContext and the rest into SharedContext.
*
* Revision 1.25  2004/12/29 07:35:40  tobega
* Prepared for cloned Context instances by encapsulating fields
*
* Revision 1.24  2004/12/12 16:11:04  tobega
* Fixed bug concerning order of inline content. Added a demo for pseudo-elements.
*
* Revision 1.23  2004/12/12 03:33:06  tobega
* Renamed x and u to avoid confusing IDE. But that got cvs in a twist. See if this does it
*
* Revision 1.22  2004/12/12 02:53:49  tobega
* Making progress
*
* Revision 1.21  2004/12/09 18:03:11  joshy
* added game screen to browser
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.20  2004/11/17 00:45:58  joshy
* added link demo
*
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.18  2004/11/16 03:43:25  joshy
* first pass at printing support
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.17  2004/11/15 14:50:45  joshy
* removed text code
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.16  2004/11/15 14:50:26  joshy
* font threshold support
*
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.15  2004/11/14 21:33:46  joshy
* new font rendering interface support
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.14  2004/11/12 20:25:16  joshy
* added hover support to the browser
* created hover demo
* fixed bug with inline borders
*
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.13  2004/11/10 17:28:53  joshy
* initial support for anti-aliased text w/ minium
*
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.12  2004/11/10 04:53:59  tobega
* cleaned up
*
* Revision 1.11  2004/11/09 15:53:47  joshy
* initial support for hover (currently disabled)
* moved justification code into it's own class in a new subpackage for inline
* layout (because it's so blooming complicated)
*
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.10  2004/11/09 03:52:25  joshy
* added financial report demo
*
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.9  2004/11/09 00:36:07  joshy
* fixed more text alignment
* added menu item to show font metrics
*
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.8  2004/11/07 23:24:19  joshy
* added menu item to generate diffs
* added diffs for multi-colored borders and inline borders
*
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.7  2004/11/05 18:48:42  joshy
* added alice demo to the browser
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.6  2004/11/03 23:54:32  joshy
* added hamlet and tables to the browser
* more support for absolute layout
* added absolute layout unit tests
* removed more dead code and moved code into layout factory
*
*
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.5  2004/10/28 14:18:22  joshy
* cleaned up the htmlpanel and made more of the variables protected
* fixed the bug where the body is too small for the viewport
* fixed the bug where the screen isn't re-laid out when the window is resized
*
* Issue number:
* Obtained from:
* Submitted by:
* Reviewed by:
*
* Revision 1.4  2004/10/23 14:38:58  pdoubleya
* Re-formatted using JavaStyle tool.
* Cleaned imports to resolve wildcards except for common packages (java.io, java.util, etc)
* Added CVS log comments at bottom.
*
*
*/

