<?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:FormItem 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"
            xmlns:validator="org.apache.flex.utilities.developerToolSuite.presentation.behavior.validator.*"
            creationComplete="creationCompleteHandler(event)"
            label="{propertyName}"
            required="true"
            styleName="stackedFormItem">


    <fx:Declarations>
        <parsley:Configure/>


        <validator:ToolPathValidator id="validator" required="true"
                                     source="{this}" property="installationPathValidated"
                                     errorStringResourceString="{errorStringTextResourceString}"
                                     trigger="{toolHomeLocation}"
                                     listener="{toolHomeLocation}"/>
    </fx:Declarations>

    <s:HGroup gap="0">
        <s:TextInput id="toolHomeLocation" text="{propertyValue}"
                     width="240"
                     change="toolHomeLocation_changeHandler(event)"/>
        <mx:Button id="browseButton" label="..." width="28"
                   toolTip="{resourceManager.getString('SettingsWindow', browserDirectoryResourceString)}"
                   click="browseButton_clickHandler(event)"/>
    </s:HGroup>
    <s:helpContent>
        <s:VGroup>
            <s:Label text="{resourceManager.getString('SettingsWindow', helpLabelResourcesString)}"/>
            <s:HGroup>
                <mx:LinkButton label="{helpUrlText}"
                               click="navigateToURL(new URLRequest(helpUrl));"/>
                <mx:LinkButton label="Install"
                               click="navigateToURL(new URLRequest(helpUrl));"/>
            </s:HGroup>
        </s:VGroup>
    </s:helpContent>
    <fx:Script><![CDATA[
        import flash.filesystem.File;

        import mx.events.FlexEvent;

        import org.apache.flex.utilities.developerToolSuite.executor.infrastructure.message.SaveSettingMessage;
        import org.apache.flex.utilities.developerToolSuite.executor.application.nativeProcess.NativeShellHelper;

        import spark.events.TextOperationEvent;

        private var _file:File;
        private var _installationPathValidated:Boolean;

        [Bindable]
        public var propertyName:String;
        [Bindable]
        public var propertyValue:String;
        [Bindable]
        public var toolTipLabelResourceString:String;
        [Bindable]
        public var helpLabelResourcesString:String;
        [Bindable]
        public var helpUrlText:String;
        [Bindable]
        public var helpUrl:String;
        [Bindable]
        public var browserDirectoryResourceString:String;
        [Bindable]
        public var validateToolMessageClass:Class;
        [Bindable]
        public var errorStringTextResourceString:String;

        public var dispatch:Function;

        private function creationCompleteHandler(event:FlexEvent):void {
            validator.validate();
            dispatch(new validateToolMessageClass(propertyValue));
        }

        private function browseButton_clickHandler(event:MouseEvent):void {
            try {
                _file = new File(NativeShellHelper.formatPath(toolHomeLocation.text));
            } catch (err:Error) {
                _file = new File();
            }

            _file.addEventListener(Event.SELECT, file_select);
            _file.browseForDirectory(resourceManager.getString('SettingsWindow', browserDirectoryResourceString));
        }

        private function file_select(evt:Event):void {
            toolHomeLocation.text = _file.nativePath;
            dispatch(new validateToolMessageClass(toolHomeLocation.text));
        }

        private function toolHomeLocation_changeHandler(event:TextOperationEvent):void {
            dispatch(new validateToolMessageClass(toolHomeLocation.text));
        }

        public function get installationPathValidated():Boolean {
            return _installationPathValidated;
        }

        [Bindable]
        public function set installationPathValidated(value:Boolean):void {
            _installationPathValidated = value;
            validator.validate();

            if (_installationPathValidated && toolHomeLocation.text) {
                dispatch(new SaveSettingMessage(propertyName, toolHomeLocation.text));
            }
        }
        ]]></fx:Script>
</s:FormItem>
