using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TechTalk.SpecFlow;
using Calculator.AcceptanceTests.StepHelpers;
using WatiN.Core;
using WatiN.Core.Exceptions;

namespace Calculator.AcceptanceTests.Steps
{
    [Binding]
    public class Calculation
    {
        [Then("the available operators should be \"(.*)\"")]
        public void TheAvailableOperatorsShouldBe(string operators)
        {
            // Arrange
            IOrderedEnumerable<string> availOps = operators.Split(new char[] { ',' }).ToList().OrderBy(o => o);

            // Act
            SelectList select = WebBrowser.Current.SelectList("operator");
            IOrderedEnumerable<string> actualOps = select.Options.Select(o => o.Text)
                                                                 .Where(o => !string.IsNullOrWhiteSpace(o))
                                                                 .OrderBy(o => o);
            string strAvailOps = string.Join(",", availOps);
            string strActualOps = string.Join(",", actualOps);

            // Assert
            Assert.AreEqual(strAvailOps, strActualOps,
                string.Format("SelectList was expected to have the options \"{0}\" but instead has the options \"{1}\".", 
                    strAvailOps, 
                    strActualOps));
        }

        [When("the \"(.*)\" element with id \"(.*)\" contains (.*)")]
        public void TheElementWithIdContainsValue(string element, string id, decimal value)
        {
            // Arrange

            // Act
            TextField pageElement = WebBrowser.Current.TextField(id);

            // Assert
            Assert.AreEqual(element.ToLower(), pageElement.TagName.ToLower(), string.Format("Element with id \"{0}\" was expected to be of type \"{1}\", but instead was of type \"{2}\".", id, element.ToLower(), pageElement.TagName.ToLower()));
            
            // Input the value
            pageElement.TypeText(value.ToString());
        }

        [When("the \"(.*)\" element with id \"(.*)\" contains \"(.*)\"")]
        public void TheElementWithIdContainsString(string element, string id, string op)
        {
            // Arrange

            // Act
            SelectList pageElement = WebBrowser.Current.SelectList(id);

            // Assert
            Assert.AreEqual(element.ToLower(), pageElement.TagName.ToLower(), string.Format("Element with id \"{0}\" was expected to be of type \"{1}\", but instead was of type \"{2}\".", id, element.ToLower(), pageElement.TagName.ToLower()));
            
            // Select the operator
            pageElement.Select(op);
        }

        [Then("the \"(.*)\" element with id \"(.*)\" should contain (.*)")]
        public void TheElementWithIdShouldContain(string element, string id, decimal result)
        {
            // Arrange

            // Act
            Element pageElement = WebBrowser.Current.Element(id);

            // Assert
            Assert.AreEqual(element.ToLower(), pageElement.TagName.ToLower(), string.Format("Element with id \"{0}\" was expected to be of type \"{1}\", but instead was of type \"{2}\".", id, element.ToLower(), pageElement.TagName.ToLower()));
            Assert.AreEqual(result.ToString(), pageElement.InnerHtml, string.Format("Element with id \"{0}\" was expected to have the value \"{1}\", but instead had the value \"{2}\".", id, result, pageElement.InnerHtml));
        }
    }
}
