/*
 * MMCDApplication.java
 *
 * Created on 15 �ubat 2005 Sal�, 21:13
 */

package com.isoft.mmcd.application ;

import com.isoft.mmcd.engine.* ;

import com.isoft.mmcd.skin.* ;
import com.isoft.mmcd.exceptions.* ;

import com.isoft.mmcd.utils.cfgreader.* ;

import javax.swing.* ;

import java.util.* ;
import java.awt.* ;

/**
 *
 * @author Fatih
 */
public class MMCDApplication implements java.io.Serializable
{
    static
    {
        boolean assertsEnabled = false ;
        assert ( assertsEnabled = true ) == true ; // Intentional side effect!!!
        if( !assertsEnabled )
            throw new RuntimeException( "Asserts must be enabled!!! Add -ea parameter to JVM" ) ;
    }

    protected MCCompoundProperty configuration = null ;

    protected MMCDWindow window = null ;

    protected Engine engine = null ;

    private MCCompoundProperty layoutProps[] = null ;

    public MCCompoundProperty getConfiguration( )
    {
        return configuration ;
    }

    public void setConfiguration( MCCompoundProperty appConfiguration )
    {
        this.configuration = appConfiguration ;
    }

    public void startup( )
    {
        getMainWindow( ).setVisible( true ) ;
    }

    public void init( Engine engine, MCCompoundProperty prop ) throws MMCDException
    {
        setEngine( engine ) ;
        setConfiguration( prop ) ;
    }

    public void buildMainWindow( Engine engine, MCCompoundProperty prop[] ) throws MMCDException
    {
        if( prop != null )
            this.layoutProps = prop ;

        setEngine( engine ) ;
        // main window must be defined
        setMainWindow( ( MMCDWindow )getEngine( ).getSkin( ).getWidgetPool( ).getWidget( "mainwindow" ) ) ;

        getMainWindow( ).getContentPane( ).setLayout( null ) ;

        traverseLayoutHierarchy( getMainWindow( ).getContentPane( ), this.layoutProps[ 0 ] ) ;

        getMainWindow( ).addComponentListener( engine.getSkin( ) ) ;

        getMainWindow( ).validate( ) ;
        getMainWindow( ).getContentPane( ).validate( ) ;
        engine.getSkin( ).resizeRecursively( getMainWindow( ) ) ;
        getMainWindow( ).pack( ) ;
        getMainWindow( ).validate( ) ;

        for( int i = 1; i < this.layoutProps.length; ++i )
        {
            Widget wd = getEngine( ).getSkin( ).getWidgetPool( ).getWidget( this.layoutProps[ i ].getTypelessName( ) ) ;
            if( wd instanceof MMCDWindow )
            {
                MMCDWindow win = ( MMCDWindow )wd ;
                traverseLayoutHierarchy( win.getContentPane( ), this.layoutProps[ i ] ) ;
                //                win.addComponentListener( engine.getSkin( ) ) ;
                //                win.validate( ) ;
                //                win.getContentPane( ).validate( ) ;
                //                engine.getSkin( ).resizeRecursively( win ) ;
                //                win.pack( ) ;
                //                win.validate( ) ;
            }
            else if( wd instanceof Container )
                traverseLayoutHierarchy( ( Container )wd, this.layoutProps[ i ] ) ;
        }

        // after we are done with the windows, not build the menus
        buildPopUpMenus( ) ;

        setUpZOrders( ) ;

        getMainWindow( ).validate( ) ;
        getMainWindow( ).getContentPane( ).validate( ) ;
        engine.getSkin( ).resizeRecursively( getMainWindow( ) ) ;
        getMainWindow( ).pack( ) ;
        getMainWindow( ).validate( ) ;
    }

    public MMCDWindow getMainWindow( )
    {
        return window ;
    }

    public void setMainWindow( MMCDWindow window )
    {
        this.window = window ;
    }

    public Engine getEngine( )
    {
        return engine ;
    }

    public void setEngine( Engine engine )
    {
        this.engine = engine ;
    }

    protected void traverseLayoutHierarchy( Container parent, MCPropertyBase property )
    {
        if( property != null && !property.isAtomic( ) )
        {
            Vector v = ( ( MCCompoundProperty )property ).getProperties( ) ;

            for( int i = 0; i < v.size( ); ++i )
            {
                MCPropertyBase prop = ( ( MCPropertyBase )v.elementAt( i ) ) ;
                JComponent component = getEngine( ).getSkin( ).getWidgetPool( ).getJComponent( prop.getTypelessName( ) ) ;
                System.err.println( "initializing widget:" + prop.getTypelessName( ) ) ;
                if( !prop.isAtomic( ) )
                    traverseLayoutHierarchy( component, prop ) ;
                if( component instanceof ScrollableWidget )
                    parent.add( ( ( ScrollableWidget )component ).getScrollPane( ) ) ;
                else
                    parent.add( component ) ;
            }
        }
    }

    protected void buildPopUpMenus( )
    {
        ArrayList alist = getEngine( ).getSkin( ).getWidgetPool( ).getWidgetsAsArrayList( ) ;

        for( int i = 0; i < alist.size( ); ++i )
        {
            Widget w = ( Widget )alist.get( i ) ;
            if( w instanceof JComponent )
            {
                JComponent comp = ( JComponent )w ;
                if( w.getPopUpMenuName( ) != null && w.getPopUpMenuName( ).length( ) > 0 )
                    comp.setComponentPopupMenu( ( JPopupMenu )getEngine( ).getSkin( ).getWidgetPool( ).getJComponent( w.getPopUpMenuName( ) ) ) ;
            }
        }

    }

    protected void setUpZOrders( )
    {
        ArrayList alist = getEngine( ).getSkin( ).getWidgetPool( ).getWidgetsAsArrayList( ) ;

        for( int i = 0; i < alist.size( ); ++i )
        {
            Widget w = ( Widget )alist.get( i ) ;
            if( w instanceof JComponent )
            {
                JComponent comp = ( JComponent )w ;
                if( w.getZIndex( ) > -1 )
                    comp.getParent( ).setComponentZOrder( comp, w.getZIndex( ) ) ;
            }
        }

    }

    public void freeAllResources( )
    {
        configuration = null ;
        window = null ;
        engine = null ;
    }

}