 import Validation
 import FormTextField
 
+enum FieldType {
+    case Header, Field
+}
+
+struct Field {
+    let type: FieldType
+    let title: String
+    let placeholder: String?
+    var inputType: FormTextFieldInputType = .Default
+    var inputValidator: InputValidatable?
+    var formatter: Formattable?
+
+    init(type: FieldType, title: String, placeholder: String? = nil) {
+        self.type = type
+        self.title = title
+        self.placeholder = placeholder
+    }
+}
+
 class Controller: UITableViewController {
+    lazy var items: [Field] = {
+        var items = [Field]()
+
+        items.append(Field(type: .Header, title: "Cardholder"))
+
+        var requiredValidation = Validation()
+        requiredValidation.required = true
+        let requiredInputValidator = InputValidator(validation: requiredValidation)
+
+        var firstNameField = Field(type: .Field, title: "First name")
+        firstNameField.inputType = .Name
+        firstNameField.inputValidator = requiredInputValidator
+        items.append(firstNameField)
+
+        var lastNameField = Field(type: .Field, title: "Last name")
+        lastNameField.inputType = .Name
+        lastNameField.inputValidator = requiredInputValidator
+        items.append(lastNameField)
+
+        items.append(Field(type: .Header, title: "Billing info"))
+
+        var cardNumberField = Field(type: .Field, title: "Number", placeholder: "Card Number")
+        cardNumberField.inputType = .Integer
+        cardNumberField.formatter = CardNumberFormatter()
+
+        var cardNumberValidation = Validation()
+        cardNumberValidation.minimumLength = "1234 5678 1234 5678".characters.count
+        cardNumberValidation.maximumLength = "1234 5678 1234 5678".characters.count
+        cardNumberValidation.required = true
+        let characterSet = NSMutableCharacterSet.decimalDigitCharacterSet()
+        characterSet.addCharactersInString(" ")
+        cardNumberValidation.characterSet = characterSet
+        let cardNumberInputValidator = InputValidator(validation: cardNumberValidation)
+        cardNumberField.inputValidator = cardNumberInputValidator
+        items.append(cardNumberField)
+
+        var expirationDateField = Field(type: .Field, title: "Expires", placeholder: "MM/YYYY")
+        expirationDateField.formatter = CardExpirationDateFormatter()
+        expirationDateField.inputType = .Integer
+        var expirationDateValidation = Validation()
+        expirationDateValidation.required = true
+        let expirationDateInputValidator = CardExpirationDateInputValidator(validation: expirationDateValidation)
+        expirationDateField.inputValidator = expirationDateInputValidator
+        items.append(expirationDateField)
+
+        var securityCodeField = Field(type: .Field, title: "CVV", placeholder: "Security Code")
+        securityCodeField.inputType = .Integer
+        var securityCodeValidation = Validation()
+        securityCodeValidation.maximumLength = "CVC".characters.count
+        securityCodeValidation.minimumLength = "CVC".characters.count
+        securityCodeValidation.characterSet = NSCharacterSet.decimalDigitCharacterSet()
+        let securityCodeInputValidator = InputValidator(validation: securityCodeValidation)
+        securityCodeField.inputValidator = securityCodeInputValidator
+        items.append(securityCodeField)
+
+        return items
+    }()
+
+
     override func viewDidLoad() {
         super.viewDidLoad()
         self.view.backgroundColor = UIColor(red: 239/255, green: 239/255, blue: 244/255, alpha: 1)

    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 7
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        if indexPath.row == 0 || indexPath.row == 3 {
            let cell = tableView.dequeueReusableCellWithIdentifier(HeaderCell.Identifier, forIndexPath: indexPath) as! HeaderCell

            switch indexPath.row {
            case 0:
                cell.textLabel?.text = "Cardholder".uppercaseString
                break
            case 3:
                cell.textLabel?.text = "Billing info".uppercaseString
                break
            default: break
            }
            return cell
        } else {
            let cell = tableView.dequeueReusableCellWithIdentifier(FormTextFieldCell.Identifier, forIndexPath: indexPath) as! FormTextFieldCell
            cell.textField.textFieldDelegate = self

            switch indexPath.row {
            case 1:
                cell.textLabel?.text = "First name"
                cell.textField.placeholder = "First name"
                cell.textField.inputType = .Name

                var validation = Validation()
                validation.required = true
                let inputValidator = InputValidator(validation: validation)
                cell.textField.inputValidator = inputValidator

                break
            case 2:
                cell.textLabel?.text = "Last name"
                cell.textField.placeholder = "Last name"
                cell.textField.inputType = .Name

                var validation = Validation()
                validation.required = true
                let inputValidator = InputValidator(validation: validation)
                cell.textField.inputValidator = inputValidator

                break
            case 4:
                cell.textLabel?.text = "Number"
                cell.textField.placeholder = "Card Number"
                cell.textField.inputType = .Integer
                cell.textField.formatter = CardNumberFormatter()

                var validation = Validation()
                validation.minimumLength = "1234 5678 1234 5678".characters.count
                validation.maximumLength = "1234 5678 1234 5678".characters.count
                validation.required = true
                let characterSet = NSMutableCharacterSet.decimalDigitCharacterSet()
                characterSet.addCharactersInString(" ")
                validation.characterSet = characterSet
                let inputValidator = InputValidator(validation: validation)
                cell.textField.inputValidator = inputValidator

                break
            case 5:
                cell.textLabel?.text = "Expires"
                cell.textField.placeholder = "MM/YYYY"
                cell.textField.inputType = .Integer
                cell.textField.formatter = CardExpirationDateFormatter()

                var validation = Validation()
                validation.required = true
                let inputValidator = CardExpirationDateInputValidator(validation: validation)
                cell.textField.inputValidator = inputValidator
                break
            case 6:
                cell.textLabel?.text = "CVV"
                cell.textField.placeholder = "Security Code"
                cell.textField.inputType = .Integer

                var validation = Validation()
                validation.maximumLength = "CVC".characters.count
                validation.minimumLength = "CVC".characters.count
                validation.characterSet = NSCharacterSet.decimalDigitCharacterSet()
                let inputValidator = InputValidator(validation: validation)
                cell.textField.inputValidator = inputValidator
                break
            default: break
            }
            return cell
        }
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if indexPath.row == 0 || indexPath.row == 3 {
            return 60
        } else {
            return 45

    }

    func validate() -> Bool {
        var valid = true
        let rows = self.items.filter({ $0.type == .Field })
        for (index, _) in rows.enumerate() {
            let cell = self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: index, inSection: 0)) as! FormTextFieldCell
            let validField = cell.textField.validate()
            if validField == false {
                valid = validField
