<?xml version="1.0" encoding="utf-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(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.apache.org/licenses/LICENSE-2.0

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.
-->
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       xmlns:mx="library://ns.adobe.com/flex/mx"
                       xmlns:parsley="http://www.spicefactory.org/parsley"
                       title="Apache Flex Developer Tool Suite"
                       width="800" height="550"
                       closing="closingHandler(event)">

    <fx:Declarations>
        <parsley:ContextBuilder>
            <parsley:ViewSettings autowireComponents="true"/>
            <parsley:FlexConfig type="{ApplicationContext}"/>
            <parsley:FlexConfig type="{SettingsContext}"/>
            <parsley:FlexConfig type="{ExecutorContext}"/>
        </parsley:ContextBuilder>
        <parsley:Configure/>
    </fx:Declarations>

    <fx:Metadata>
        [ResourceBundle("Application")]
        [ResourceBundle("SettingsWindow")]
    </fx:Metadata>

    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <fx:Script><![CDATA[
        import mx.controls.Alert;
        import mx.logging.Log;
        import mx.logging.LogEventLevel;
        import mx.logging.targets.TraceTarget;
        import mx.managers.PopUpManager;

        import org.apache.flex.utilities.developerToolSuite.executor.domain.ISettingsModel;
        import org.apache.flex.utilities.developerToolSuite.executor.infrastructure.config.ExecutorContext;
        import org.apache.flex.utilities.developerToolSuite.executor.infrastructure.message.ApplicationReadyMessage;
        import org.apache.flex.utilities.developerToolSuite.executor.infrastructure.message.InitApplicationMessage;
        import org.apache.flex.utilities.developerToolSuite.executor.infrastructure.message.SaveSettingMessage;
        import org.apache.flex.utilities.developerToolSuite.executor.infrastructure.message.ValidateAntPathMessage;
        import org.apache.flex.utilities.developerToolSuite.executor.infrastructure.message.ValidateCygwinPathMessage;
        import org.apache.flex.utilities.developerToolSuite.executor.infrastructure.message.ValidateJavaPathMessage;
        import org.apache.flex.utilities.developerToolSuite.executor.infrastructure.message.ValidateMavenPathMessage;
        import org.apache.flex.utilities.developerToolSuite.executor.infrastructure.util.LogUtil;
        import org.apache.flex.utilities.developerToolSuite.infrastructure.event.ModalWindowEvent;
        import org.apache.flex.utilities.developerToolSuite.infrastructure.message.LaunchUIMessage;
        import org.apache.flex.utilities.developerToolSuite.presentation.config.SettingsContext;
        import org.apache.flex.utilities.developerToolSuite.presentation.graphic.menu.ApplicationMenu;

        [Inject]
        [Bindable]
        public var applicationMenu:ApplicationMenu;

        [Inject]
        public var applicationSettings:ISettingsModel;

        [MessageDispatcher]
        public var dispatch:Function;

        private var alert:Alert;

        [Init]
        public function init():void {
            addLog();
            LogUtil.getLogger(this).info('Application initialization');

            dispatch(new InitApplicationMessage());

            alert = Alert.show(resourceManager.getString('Application', 'WELCOME_MSG'), resourceManager.getString('Application', 'WELCOME_TITLE'));
        }

        [MessageHandler]
        public function applicationReady(msg:ApplicationReadyMessage):void {

            PopUpManager.removePopUp(alert);
            menu = applicationMenu;

            if (applicationSettings.appDisplayState) {
                if (applicationSettings.appDisplayState == NativeWindowDisplayState.MAXIMIZED) {
                    nativeWindow.maximize();
                } else {
                    nativeWindow.restore();
                    if (applicationSettings.appBounds) {
                        var bounds:Array = applicationSettings.appBounds.split(",");
                        nativeWindow.bounds = new Rectangle(bounds[0], bounds[1], bounds[2], bounds[3]);
                    }
                }
            } else {
                nativeWindow.bounds = new Rectangle(120, 120, 1200, 825);
            }

            LogUtil.getLogger(this).info('Application ready');

            dispatch(new LaunchUIMessage());
        }

        [MessageHandler(selector='opened')]
        public function modalWindowOpenedHandler(event:ModalWindowEvent):void {
            menu = null;
        }

        [MessageHandler(selector='closed')]
        public function modalWindowClosedHandler(event:ModalWindowEvent):void {
            menu = applicationMenu;
        }

        private function closingHandler(event:Event):void {
            dispatch(new SaveSettingMessage("appBounds", nativeWindow.x + "," + nativeWindow.y + "," + nativeWindow.width + "," + nativeWindow.height));
            dispatch(new SaveSettingMessage("appDisplayState", nativeWindow.displayState));
        }

        private function addLog():void {
            var parsleyLogger:TraceTarget = new TraceTarget();
            parsleyLogger.filters = ["org.spicefactory.*", "mx.*"];
            parsleyLogger.level = LogEventLevel.ERROR;
            parsleyLogger.includeCategory = true;
            parsleyLogger.includeLevel = true;
            parsleyLogger.fieldSeparator = " -> ";
            Log.addTarget(parsleyLogger);

            var devLogger:TraceTarget = new TraceTarget();
            devLogger.filters = ["org.apache.flex.utilities.developerToolSuite.*"];
            devLogger.level = LogEventLevel.ALL;
            devLogger.includeCategory = true;
            devLogger.includeLevel = true;
            devLogger.includeTime = true;
            devLogger.fieldSeparator = " -> ";
            Log.addTarget(devLogger);
        }
        ]]></fx:Script>
</s:WindowedApplication>
