/// <summary>
 /// Called when a prompt should be displayed for a specific
 /// input field.
 /// </summary>
 /// <param name="fieldDetails">The details of the field to be displayed.</param>
 protected override void ShowFieldPrompt(FieldDetails fieldDetails)
 {
     // For a simple prompt there won't be any field name.
     // In this case don't write anything
     if (!string.IsNullOrEmpty(fieldDetails.Name))
     {
         this.hostOutput.WriteOutput(
             fieldDetails.Name + ": ",
             false);
     }
 }
 /// <summary>
 /// Called when a prompt should be displayed for a specific
 /// input field.
 /// </summary>
 /// <param name="fieldDetails">The details of the field to be displayed.</param>
 protected override void ShowFieldPrompt(FieldDetails fieldDetails)
 {
     // For a simple prompt there won't be any field name.
     // In this case don't write anything
     if (!string.IsNullOrEmpty(fieldDetails.Name))
     {
         this.consoleHost.WriteOutput(
             fieldDetails.Name + ": ",
             false);
     }
 }
        private bool ShowNextPrompt()
        {
            if (this.currentCollectionField != null)
            {
                // Continuing collection entry
                this.currentCollectionIndex++;
                this.currentField.Name =
                    string.Format(
                        "{0}[{1}]",
                        this.currentCollectionField.Name,
                        this.currentCollectionIndex);
            }
            else
            {
                // Have we shown all the prompts already?
                if (this.currentFieldIndex >= this.Fields.Length)
                {
                    return(false);
                }

                this.currentField = this.Fields[this.currentFieldIndex];

                if (this.currentField.IsCollection)
                {
                    this.currentCollectionIndex = 0;
                    this.currentCollectionField = this.currentField;
                    this.currentCollectionItems = new ArrayList();

                    this.currentField =
                        new FieldDetails(
                            string.Format(
                                "{0}[{1}]",
                                this.currentCollectionField.Name,
                                this.currentCollectionIndex),
                            this.currentCollectionField.Label,
                            this.currentCollectionField.ElementType,
                            true,
                            null);
                }

                this.currentFieldIndex++;
            }

            this.ShowFieldPrompt(this.currentField);
            return(true);
        }
        private FieldDetails GetNextField()
        {
            FieldDetails nextField = this.currentField?.GetNextField();

            if (nextField == null)
            {
                this.currentFieldIndex++;

                // Have we shown all the prompts already?
                if (this.currentFieldIndex < this.Fields.Length)
                {
                    nextField = this.Fields[this.currentFieldIndex];
                }
            }

            this.currentField = nextField;
            return(nextField);
        }
        protected override void ShowFieldPrompt(FieldDetails fieldDetails)
        {
            // Write the prompt to the console first so that there's a record
            // of it occurring
            base.ShowFieldPrompt(fieldDetails);

            messageSender
                .SendRequest(
                    ShowInputPromptRequest.Type,
                    new ShowInputPromptRequest
                    {
                        Name = fieldDetails.Name,
                        Label = fieldDetails.Label
                    }, true)
                .ContinueWith(HandlePromptResponse)
                .ConfigureAwait(false);
        }
        private bool ShowNextPrompt()
        {
            if (this.currentCollectionField != null)
            {
                // Continuing collection entry
                this.currentCollectionIndex++;
                this.currentField.Name =
                    string.Format(
                        "{0}[{1}]",
                        this.currentCollectionField.Name,
                        this.currentCollectionIndex);
            }
            else
            {
                // Have we shown all the prompts already?
                if (this.currentFieldIndex >= this.Fields.Length)
                {
                    return false;
                }

                this.currentField = this.Fields[this.currentFieldIndex];

                if (this.currentField.IsCollection)
                {
                    this.currentCollectionIndex = 0;
                    this.currentCollectionField = this.currentField;
                    this.currentCollectionItems = new ArrayList();

                    this.currentField =
                        new FieldDetails(
                            string.Format(
                                "{0}[{1}]",
                                this.currentCollectionField.Name,
                                this.currentCollectionIndex),
                            this.currentCollectionField.Label,
                            this.currentCollectionField.ElementType,
                            true,
                            null);
                }

                this.currentFieldIndex++;
            }

            this.ShowFieldPrompt(this.currentField);
            return true;
        }
 /// <summary>
 /// Called when a prompt should be displayed for a specific
 /// input field.
 /// </summary>
 /// <param name="fieldDetails">The details of the field to be displayed.</param>
 protected abstract void ShowFieldPrompt(FieldDetails fieldDetails);
        /// <summary>
        /// Implements behavior to handle the user's response.
        /// </summary>
        /// <param name="responseString">The string representing the user's response.</param>
        /// <returns>
        /// True if the prompt is complete, false if the prompt is 
        /// still waiting for a valid response.
        /// </returns>
        public override bool HandleResponse(string responseString)
        {
            if (this.currentField == null)
            {
                // TODO: Assert
            }

            // TODO: Is string empty?  Use default or finish prompt?
            object responseValue = responseString;

            try
            {
                responseValue = 
                    LanguagePrimitives.ConvertTo(
                        responseString,
                        this.currentField.FieldType,
                        CultureInfo.CurrentCulture);
            }
            catch (PSInvalidCastException e)
            {
                // Show an error and redisplay the same field
                this.ShowErrorMessage(e.InnerException);
                this.ShowFieldPrompt(this.currentField);
                return false;
            }

            if (this.currentCollectionField != null)
            {
                if (responseString.Length == 0)
                {
                    object collection = this.currentCollectionItems;

                    // Should the result collection be an array?
                    if (this.currentCollectionField.FieldType.IsArray)
                    {
                        // Convert the ArrayList to an array
                        collection =
                            this.currentCollectionItems.ToArray(
                                this.currentCollectionField.ElementType);
                    }

                    // Collection entry is done, save the items and clean up state
                    this.fieldValues.Add(
                        this.currentCollectionField.Name,
                        collection);

                    this.currentField = this.currentCollectionField;
                    this.currentCollectionField = null;
                    this.currentCollectionItems = null;
                }
                else
                {
                    // Add the item to the collection
                    this.currentCollectionItems.Add(responseValue);
                }
            }
            else
            {
                this.fieldValues.Add(this.currentField.Name, responseValue);
            }

            // If there are no more fields to show the prompt is complete
            if (this.ShowNextPrompt() == false)
            {
                this.promptTask.SetResult(this.fieldValues);
                return true;
            }

            // Prompt is still active
            return false;
        }
        /// <summary>
        /// Prompts the user for a line (or lines) of input.
        /// </summary>
        /// <param name="promptCaption">
        /// A title shown before the series of input fields.
        /// </param>
        /// <param name="promptMessage">
        /// A descritpive message shown before the series of input fields.
        /// </param>
        /// <param name="fields">
        /// An array of FieldDetails items to be displayed which prompt the
        /// user for input of a specific type.
        /// </param>
        /// <param name="cancellationToken">
        /// A CancellationToken that can be used to cancel the prompt.
        /// </param>
        /// <returns>
        /// A Task instance that can be monitored for completion to get
        /// the user's input.
        /// </returns>
        public Task<Dictionary<string, object>> PromptForInput(
            string promptCaption,
            string promptMessage,
            FieldDetails[] fields,
            CancellationToken cancellationToken)
        {
            this.promptTask = new TaskCompletionSource<Dictionary<string, object>>();

            // Cancel the TaskCompletionSource if the caller cancels the task
            cancellationToken.Register(this.CancelPrompt, true);

            this.Fields = fields;

            this.ShowPromptMessage(promptCaption, promptMessage);
            this.ShowNextPrompt();

            return this.promptTask.Task;
        }
        protected override void ShowFieldPrompt(FieldDetails fieldDetails)
        {
            base.ShowFieldPrompt(fieldDetails);

            // Raise the task for the first field prompt shown
            if (this.promptShownTask != null &&
                this.promptShownTask.Task.Status == TaskStatus.WaitingForActivation)
            {
                this.promptShownTask.SetResult(true);
            }
        }
 /// <summary>
 /// Called when a prompt should be displayed for a specific
 /// input field.
 /// </summary>
 /// <param name="fieldDetails">The details of the field to be displayed.</param>
 protected abstract void ShowFieldPrompt(FieldDetails fieldDetails);
        /// <summary>
        /// Implements behavior to handle the user's response.
        /// </summary>
        /// <param name="responseString">The string representing the user's response.</param>
        /// <returns>
        /// True if the prompt is complete, false if the prompt is
        /// still waiting for a valid response.
        /// </returns>
        public override bool HandleResponse(string responseString)
        {
            if (this.currentField == null)
            {
                // TODO: Assert
            }

            // TODO: Is string empty?  Use default or finish prompt?
            object responseValue = responseString;

            try
            {
                responseValue =
                    LanguagePrimitives.ConvertTo(
                        responseString,
                        this.currentField.FieldType,
                        CultureInfo.CurrentCulture);
            }
            catch (PSInvalidCastException e)
            {
                // Show an error and redisplay the same field
                this.ShowErrorMessage(e.InnerException);
                this.ShowFieldPrompt(this.currentField);
                return(false);
            }

            if (this.currentCollectionField != null)
            {
                if (responseString.Length == 0)
                {
                    object collection = this.currentCollectionItems;

                    // Should the result collection be an array?
                    if (this.currentCollectionField.FieldType.IsArray)
                    {
                        // Convert the ArrayList to an array
                        collection =
                            this.currentCollectionItems.ToArray(
                                this.currentCollectionField.ElementType);
                    }

                    // Collection entry is done, save the items and clean up state
                    this.fieldValues.Add(
                        this.currentCollectionField.Name,
                        collection);

                    this.currentField           = this.currentCollectionField;
                    this.currentCollectionField = null;
                    this.currentCollectionItems = null;
                }
                else
                {
                    // Add the item to the collection
                    this.currentCollectionItems.Add(responseValue);
                }
            }
            else
            {
                this.fieldValues.Add(this.currentField.Name, responseValue);
            }

            // If there are no more fields to show the prompt is complete
            if (this.ShowNextPrompt() == false)
            {
                this.promptTask.SetResult(this.fieldValues);
                return(true);
            }

            // Prompt is still active
            return(false);
        }
 protected override void ShowFieldPrompt(FieldDetails fieldDetails)
 {
     this.LastField = fieldDetails;
 }