package com.adobe.ac.view
{
    import com.adobe.ac.vo.Album;
    
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.ui.Mouse;
    
    import mx.binding.utils.BindingUtils;
    import mx.containers.Form;
    import mx.containers.FormItem;
    import mx.controls.Button;
    import mx.controls.CheckBox;
    import mx.controls.TextInput;
    import mx.core.UIComponent;
    import mx.events.FlexEvent;
    import mx.validators.Validator;

    [Bindable]
    public class AlbumFormClass extends Form
    {
        public var artist : TextInput;
        public var title : TextInput;
        public var composerFormItem : FormItem;
        public var composer : TextInput;
        public var classical : CheckBox
        
        public var apply : Button;
        public var cancel : Button;
        
        public var artistValidator : Validator = new Validator();
        public var titleValidator : Validator = new Validator();
        public var composerValidator : Validator = new Validator();
        
        private var _album : Album;
        
        private var _composerEdited : Boolean;
        
        public function AlbumFormClass() 
        {
            addEventListener( FlexEvent.CREATION_COMPLETE, creationCompleteHandler );
        }

        public function get album() : Album
        {
            return _album;
        }
    
        public function set album( album : Album ) : void
        {
            _album = album;
            resetForm();
        }                
        
        private function creationCompleteHandler( event : FlexEvent ) : void
        {
            setupValidator( artistValidator, artist, "Please enter an artist" );
            setupValidator( titleValidator, title, "Please enter an album title" );
            setupValidator( composerValidator, composer, "Please enter a composer" );
            
            artist.addEventListener( Event.CHANGE, updateButtons );
            title.addEventListener( Event.CHANGE, updateButtons );
            classical.addEventListener( MouseEvent.CLICK, changeClassical );
            composer.addEventListener( Event.CHANGE, changeComposer );
            
            apply.addEventListener( MouseEvent.CLICK, applyChanges );
            cancel.addEventListener( MouseEvent.CLICK, cancelChanges );
            
            resetForm();    
        }
        
        private function changeClassical( event : MouseEvent ) : void
        {
            composer.text = "";
            composer.enabled = classical.selected;
            composerFormItem.required = classical.selected;
            resetErrorString( composer );
            _composerEdited = false;
            updateButtons();
        }
        
        private function changeComposer( event : Event ) : void
        { 
            _composerEdited = true;
            updateButtons();
        }            
        
        private function updateButtons( event : Event = null ) : void
        {
            artistValidator.validate();
            titleValidator.validate();
            if ( classical.selected == true && _composerEdited == true )
            {
                composerValidator.validate();
            }
            cancel.enabled = canCancel();
            apply.enabled = canApply();
        }
        
        private function canCancel() : Boolean
        {
            if ( _album.artist != artist.text ||
                 _album.title != title.text ||
                 _album.composer != composer.text ||
                 _album.isClassical != classical.selected )
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        
        private function canApply() : Boolean
        {
            var result : Boolean = cancel.enabled;
            result = result && artist.errorString == ""
            result = result && title.errorString == ""
            if ( classical.selected == true )
            {
                result = result && composer.errorString == "";
                result = result && _composerEdited == true;
            }
            return result;
        }        
        
        private function applyChanges( event : MouseEvent ) : void
        {
            album.artist = artist.text;
            album.title = title.text;
            album.composer = composer.text;
            album.isClassical = classical.selected;
            updateButtons();
        }
        
        private function cancelChanges( event : MouseEvent ) : void
        {
            var album : Album = _album;
            this.album = null;
            this.album = album;
        }
        
        private function resetForm() : void
        {
            if ( album != null )
            {
                title.text = album.title;
                artist.text = album.artist;
                classical.selected = album.isClassical;
                composer.text = album.composer;
                enableTextInputs( true );
                composer.enabled = album.isClassical;
            }
            else
            {
                title.text = "";
                artist.text = "";
                classical.selected = false;
                composer.text = "";
                enableTextInputs( false );
                composer.enabled = false;
            }
            cancel.enabled = false;
            apply.enabled = false;
            _composerEdited = true;
            resetErrorString( artist )
            resetErrorString( title );
            resetErrorString( composer );
        }            
        
        private function enableTextInputs( enabled : Boolean ) : void
        {
            title.enabled = enabled;
            artist.enabled = enabled;
            classical.enabled = enabled;
        }        
        
        private function resetErrorString( component : UIComponent ) : void
        {
            if ( component.errorString.length > 0 )
            {
                component.errorString = "";
            }    
        }
        
        private function setupValidator( validator : Validator, textInput : TextInput, fieldError : String ) : void
        {
            validator.property = "text";
            validator.requiredFieldError = fieldError;
            validator.triggerEvent = "change";
            validator.source = textInput;
            validator.listener = textInput;    
        }
    }
}