package com.github.dkharrat.nexusdialog.sample;

import android.text.InputType;
import android.view.*;

import com.github.dkharrat.nexusdialog.FormController;
import com.github.dkharrat.nexusdialog.FormWithAppCompatActivity;
import com.github.dkharrat.nexusdialog.controllers.*;
import com.github.dkharrat.nexusdialog.controllers.SearchableSelectionController.SelectionDataSource;
import com.github.dkharrat.nexusdialog.utils.MessageUtil;
import com.github.dkharrat.nexusdialog.validations.InputValidator;
import com.github.dkharrat.nexusdialog.validations.RequiredFieldValidator;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.*;

/**
 * Demonstrates the following functionality:
 * <ul>
 *  <li>SearchableSelectionController</li>
 *  <li>Event handling</li>
 *  <li>Using a Custom Element</li>
 *  <li>Basic Validations</li>
 *  <li>Property change notifications</li>
 * </ul>
 */
public class ComplexForm extends FormWithAppCompatActivity {

    private final static String FIRST_NAME = "firstName";
    private final static String LAST_NAME = "lastName";
    private final static String FULL_NAME = "fullName";
    private final static String GENDER = "gender";
    private final static String FAVORITE_COLOR = "favColor";
    private final static String CUSTOM_ELEM = "customElem";
    private final static String EVEN_NUMBER = "evenNumber";

    private final Stack<String> addedElements = new Stack<String>();

    @Override
    public void initForm(FormController formController) {
        setTitle("Complex Form");

        final FormSectionController section = new FormSectionController(this, "Personal Info");
        section.addElement(new EditTextController(this, FIRST_NAME, "First name", "Change me", true));
        section.addElement(new EditTextController(this, LAST_NAME, "Last name"));
        section.addElement(new ValueController(this, FULL_NAME, "Full name"));
        section.addElement(new SelectionController(this, GENDER, "Gender", true, "Select", Arrays.asList("Male", "Female"), true));
        section.addElement(new SearchableSelectionController(this, FAVORITE_COLOR, "Favorite Color", false, "Blue", dataSource));

        CustomElement customElem = new CustomElement(this, CUSTOM_ELEM, "Custom Element");
        customElem.getAddButton().setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                String name = "elem_" + addedElements.size();
                addedElements.add(name);
                section.addElement(new ValueController(ComplexForm.this, name, name));
                recreateViews();
            }
        });
        customElem.getRemoveButton().setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                if (!addedElements.isEmpty()) {
                    section.removeElement(addedElements.pop());
                    recreateViews();
                }
            }
        });
        section.addElement(customElem);

        final FormSectionController validationSection = new FormSectionController(this, "Some checked input");

        HashSet<InputValidator> inputValidators = new HashSet<InputValidator>();
        inputValidators.add(new CustomValidation());
        inputValidators.add(new RequiredFieldValidator());
        validationSection.addElement(new EditTextController(
            this, EVEN_NUMBER, "enter an even number", "Put a number here",
            inputValidators, InputType.TYPE_CLASS_NUMBER
        ));

        getFormController().addSection(section);
        getFormController().addSection(validationSection);

        PropertyChangeListener nameFieldListener = new PropertyChangeListener() {
            @Override public void propertyChange(PropertyChangeEvent event) {
                Object firstName = getModel().getValue(FIRST_NAME);
                Object lastName = getModel().getValue(LAST_NAME);

                // setting a field value will automatically refresh the form element
                getModel().setValue(FULL_NAME, firstName + " " + lastName);
            }
        };

        // add a listener to get notifications for any field changes
        getModel().addPropertyChangeListener(FIRST_NAME, nameFieldListener);
        getModel().addPropertyChangeListener(LAST_NAME, nameFieldListener);

        // initialize field with a value
        getModel().setValue(LAST_NAME, "Smith");
    }

    private final SelectionDataSource dataSource = new SelectionDataSource() {
        @Override public List<String> getItems() {
            return Arrays.asList(
                    "Red",
                    "Blue",
                    "Green",
                    "Purple",
                    "Pink"
            );
        }
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.form_actionbar, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)  {
        super.onOptionsItemSelected(item);

        getFormController().resetValidationErrors();
        if (getFormController().isValidInput()) {
            Object firstName = getModel().getValue(FIRST_NAME);
            Object lastName = getModel().getValue(LAST_NAME);
            Object gender = getModel().getValue(GENDER);
            Object favColor = getModel().getValue(FAVORITE_COLOR);
            Object number= getModel().getValue(EVEN_NUMBER);

            String msg = "First name: " + firstName + "\n"
                    + "Last name: " + lastName + "\n"
                    + "Gender: " + gender + "\n"
                    + "Favorite Color: " + favColor + "\n"
                    + "Even number: " + number + "\n";
            MessageUtil.showAlertMessage("Field Values", msg, this);
        } else {
            getFormController().showValidationErrors();
        }
        return true;
    }
}

@@ -1502,16 +1502,22 @@
 nitForm(
+final 
 FormCont
@@ -3556,36 +3556,33 @@
    ));%0A%0A        
-getF
+f
 ormController().
@@ -3570,34 +3570,32 @@
   formController
-()
 .addSection(sect
@@ -3600,36 +3600,33 @@
 ction);%0A        
-getF
+f
 ormController().
@@ -3622,18 +3622,16 @@
 ntroller
-()
 .addSect
@@ -3842,32 +3842,47 @@
 ect firstName = 
+formController.
 getModel().getVa
@@ -3924,32 +3924,47 @@
 ject lastName = 
+formController.
 getModel().getVa
@@ -4073,32 +4073,47 @@
                 
+formController.
 getModel().setVa
@@ -4251,32 +4251,47 @@
 changes%0A        
+formController.
 getModel().addPr
@@ -4343,32 +4343,47 @@
 tener);%0A        
+formController.
 getModel().addPr
@@ -4484,16 +4484,31 @@
         
+formController.
 getModel

fix crash in ComplexForm sample (#35)