/*
 * EntryPoint.java
 *
 * Created on April 6, 2010, 6:51 PM
 */
package com.dhaval.web.vaadin.simple;

import com.dhaval.web.vaadin.simple.forms.UserWindow;
import com.dhaval.web.vaadin.simple.validators.IntegerValidator;
import com.vaadin.Application;
import com.vaadin.data.Item;
import com.vaadin.data.validator.DoubleValidator;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;

/** 
 *
 * @author dhaval
 * @version 
 */
public class EntryPoint extends Application {

    public EntryPoint() {
    }

    @Override
    public void init() {
        Window mainWindow = new Window("Vaadin Demo Application");
        mainWindow.center();

        GenericForm loginForm = new GenericForm(new LoginDetail(), "Sign in", new GenericFieldFactory(), new GenericFormEventHandler() {

            public void formCommitted(Object formBean) {
                LoginDetail loginDetail = (LoginDetail) formBean;
                if (!loginDetail.getUserId().equalsIgnoreCase("guest") || !loginDetail.getPassword().equalsIgnoreCase("guest")) {
                    Window.Notification not = new Window.Notification("", "Invalid Username or Password. Please try again.", Window.Notification.TYPE_ERROR_MESSAGE);
                    getMainWindow().showNotification(not);
                } else {
                    UserWindow userWindow = new UserWindow(EntryPoint.this);
                    EntryPoint.this.removeWindow(getMainWindow());
                    EntryPoint.this.setMainWindow(userWindow);
                }

            }
        });

        VerticalLayout hPanel = new VerticalLayout();
        hPanel.setWidth("650px");
        hPanel.setSpacing(true);
        
        Panel panel = new Panel();
        Label lbl = new Label("This is a demostration application built using modern Java Web Framework - Vaadin. " +
                "For more information on Vaadin visit the product site <a href='http://vaadin.com'>Vaadin</a>. " +
                "Use <i>guest/guest</i> as Username/Password for temporary login." +
                "<br><br>For login information please contact the Site Administrator <a href='http://twitter.com/dhavaln'>dhavaln</a>",
                Label.CONTENT_XHTML);
        panel.addComponent(lbl);

        hPanel.addComponent(panel);
        hPanel.setComponentAlignment(panel, Alignment.MIDDLE_CENTER);

        hPanel.addComponent(loginForm);
        hPanel.setComponentAlignment(loginForm, Alignment.MIDDLE_RIGHT);

        Button newUser = new Button("New User?", new Button.ClickListener() {

            public void buttonClick(ClickEvent event) {
                GenericForm registrationForm = new GenericForm(new UserRegistration(), "New User", new GenericFieldFactory(), new GenericFormEventHandler() {

                    public void formCommitted(Object formBean) {
                        Window.Notification n = new Window.Notification("User Registration", Window.Notification.TYPE_TRAY_NOTIFICATION);
                        n.setPosition(Window.Notification.POSITION_CENTERED);
                        n.setDescription("<p>The functionality is not yet open for all.<p>Please contact the Site Administrator for login information.");
                        getMainWindow().showNotification(n);
                    }
                });
                openInWindow("User Detail", registrationForm);
            }
        });
        newUser.setStyleName(Button.STYLE_LINK);

        hPanel.addComponent(new Label("<hr>", Label.CONTENT_XHTML));
        hPanel.addComponent(newUser);
        
        mainWindow.addComponent(hPanel);

        setMainWindow(mainWindow);
    }

    public void openInWindow(String header, GenericForm form) {
        Window formWindow = new Window(header);
        formWindow.setModal(true);
        formWindow.setClosable(true);
        formWindow.setWidth("40%");

        formWindow.addComponent(form);
        getMainWindow().addWindow(formWindow);
    }

    public static class UserRegistration implements Serializable{
        private String userId;
        private String firstName;
        private String lastName;
        private String password;
        private String eMailAddress;

        public String getFirstName() {
            return firstName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public void seteMailAddress(String eMailAddress) {
            this.eMailAddress = eMailAddress;
        }

        public String geteMailAddress() {
            return eMailAddress;
        }


    }

    public static class LoginDetail implements Serializable{

        private String userId;
        private String password;
        private boolean rememberMe;

        public void setPassword(String password) {
            this.password = password;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public String getPassword() {
            return password;
        }

        public String getUserId() {
            return userId;
        }

        public void setRememberMe(boolean rememberMe) {
            this.rememberMe = rememberMe;
        }

        public boolean isRememberMe() {
            return rememberMe;
        }
    }

    public static class GenericFieldFactory extends DefaultFieldFactory implements Serializable{

        private Map<String, String> fieldType;
        private List<String> listFields;

        public GenericFieldFactory() {
        }

        public GenericFieldFactory(Map<String, String> fieldType) {
            this.fieldType = fieldType;
        }

        public GenericFieldFactory(List<String> listFields){
            this.listFields = listFields;
        }
        
        @Override
        public Field createField(Item item, Object propertyId, Component uiContext) {
            Class type = item.getItemProperty(propertyId).getType();
            Field field = null;
            if(fieldType != null && !fieldType.isEmpty()){
                String strType = fieldType.get(propertyId.toString());
                if(strType.equalsIgnoreCase("string")){
                    type = String.class;
                }else if(strType.equalsIgnoreCase("number")){
                    type = Double.class;
                    item.getItemProperty(propertyId).setValue(0.0);
                }
            }

            if (listFields != null && listFields.contains(propertyId.toString())) {
                ComboBox cb = new ComboBox(propertyId.toString());
                cb.addItem("String");
                cb.addItem("Number");
                cb.addItem("Date");
                cb.setNewItemsAllowed(false);

                field = cb;
                field.setPropertyDataSource(item.getItemProperty(propertyId));
            }

            if (item.getItemProperty(propertyId).getValue() == null
                    && (type == String.class
                    || type == Object.class) ) {
                item.getItemProperty(propertyId).setValue("");
            }

            if(field == null){
                field = super.createField(item, propertyId, uiContext);
            }
            field.setRequired(true);

            if (type == StringBuffer.class) {
                TextField tf = (TextField) field;
                tf.setWordwrap(true);
                tf.setRows(5);
                tf.setColumns(25);
            }

            if(field instanceof TextField){
                TextField tf = (TextField) field;
                if(propertyId.toString().toLowerCase().indexOf("password") >= 0){
                    tf.setSecret(true);
                }
            }

            if (type == Integer.class) {
                field.addValidator(new IntegerValidator("value must be a number"));
            } else if (type == Double.class) {
                field.addValidator(new DoubleValidator("value must be a number"));
            } else if (type == Date.class){
                DateField df = (DateField) field;
                df.setResolution(DateField.RESOLUTION_MIN);
            }

            return field;
        }
    }
}
