

/*
var $registerFormItems = (function() {
  var $username = new Ox.Input({
    'id': 'registerUsername',
    'autovalidate': autovalidateUsername,
    'label': 'Username:',
    'labelWidth': 90,
    'validate': function(value, callback) {
      callback({
        'message': 'Missing Username',
        'valid': !!value.length
      });
    },
    'width': 256
  });
  var $password = new Ox.Input({
    'id': 'registerPassword',
    autovalidate: /.+/,
    label: 'Password:',
    labelWidth: 90,
    'type': 'password',
    'validate': function(value, callback) {
      callback({
        'message': 'Missing Password',
        'valid': !!value.length
      });
    },
    width: 256    
  });

  var $email = new Ox.Input({
    id: 'registerEmail',
    'type': 'email',
    autovalidate: autovalidateEmail,
    label: 'E-Mail:',
    labelWidth: 90,
    width: 256
  });

  return [$username, $password, $email]
})();
*/
(function() {


//FIXME: creating global for ui. This doesn't sound healthy.


	ui = {
	    accountDialog: function(action) {
	        var that = app.$ui.accountDialog = new Ox.Dialog($.extend({
                    height: 256,
                    id: 'accountDialog',
                    minHeight: 256,
                    minWidth: 384,
                    width: 384
    	        }, ui.accountDialogOptions(action)))
    	        .bindEvent({
    	            resize: function(event, data) {
                        var width = data.width - 32;
                        app.$ui.accountForm.items.forEach(function(item) {
                            item.options({width: width});
                        });
                    }
    	        });
	        return that;
	    },
	    accountDialogOptions: function(action, value) {
	        Ox.print('ACTION', action)
//            app.$ui.accountForm && app.$ui.accountForm.remove();
	        var buttons = {
	                login: ['register', 'reset'],
	                register: ['login'],
	                reset: ['login'],
	                resetAndLogin: []
                },
                buttonTitle = {
                    login: 'Login',
                    register: 'Register',
                    reset: 'Reset Password',
                    resetAndLogin: 'Reset Password and Login'
                },
                dialogText = {
                    login: 'To login to your account, please enter your username and password.',
                    register: 'To create a new account, please choose a username and password, and enter your e-mail address.',
                    reset: 'To reset your password, please enter either your username or your e-mail address.',
                    resetAndLogin: 'To login to your account, please choose a new password, and enter the code that we have just e-mailed to you.'
                },
                dialogTitle = {
                    login: 'Login',
                    register: 'Register',
                    reset: 'Reset Password',
                    resetAndLogin: 'Reset Password'
                };
            function button(type) {
                if (type == 'cancel') {
    	            return new Ox.Button({
                        id: 'cancel' + Ox.toTitleCase(action),
                        title: 'Cancel'
                    }).bindEvent('click', function() {
                        app.$ui.accountDialog.close();
                    });
    	        } else if (type == 'submit') {
    	            return new Ox.Button({
                        disabled: true,
                        id: 'submit' + Ox.toTitleCase(action),
                        title: buttonTitle[action]
                    }).bindEvent('click', function() {
                        app.$ui.accountForm.submit();
                    });
    	        } else {
    	            return new Ox.Button({
    	                id: type,
    	                title: buttonTitle[type] + '...'
    	            }).bindEvent('click', function() {
    	                Ox.print('CLICK EVENT', type)
                        app.$ui.accountDialog.options(ui.accountDialogOptions(type));
                    });
    	        }
            }
            return {
                buttons: [
    	            $.map(buttons[action], function(type) {
                        return button(type);
                    }),
                    [button('cancel'), button('submit')]
                ],
                content: new Ox.Element('div')
                    .append(
                        new Ox.Element('div')
                            .addClass('OxText')
                            .html(dialogText[action] + '<br/><br/>')
                    )
                    .append(
                        app.$ui.accountForm = ui.accountForm(action, value)
                    ),
                keys: {
    	            enter: 'submit' + Ox.toTitleCase(action),
    	            escape: 'cancel' + Ox.toTitleCase(action)
    	        },
                title: dialogTitle[action]
            };
	    },
	    accountForm: function(action, value) {
	        if (app.$ui.accountForm) {
	            app.$ui.accountForm.items.forEach(function(item) {
	                if (item.options('id') == 'usernameOrEmail') {
	                    Ox.print('REMOVING')
	                    //Ox.Event.unbind('usernameOrEmailSelect')
	                    //Ox.Event.unbind('usernameOrEmailSelectMenu')
	                    //Ox.Event.unbind('usernameOrEmailInput')
	                }
	                Ox.print('REMOVING ITEM', item.options('id'));
//	                item.remove();
	            });
	        }
	        var items = {
	                'login': ['usernameOrEmail', 'password'],
	                'register': ['newUsername', 'password', 'email'],
	                'reset': ['usernameOrEmail'],
	                'resetAndLogin': ['oldUsername', 'newPassword', 'code']
	            },
	            $items = $.map(items[action], function(v) {
                    return item(v, value);
                }),
	            that = new Ox.Form({
                    id: 'accountForm' + Ox.toTitleCase(action),
                    items: $items,
                    submit: function(data, callback) {
                        if (action == 'login') {
                            app.api.login(data, function(result) {
                                if (!result.data.errors) {
                                    app.$ui.accountDialog.close();
                                    ITF.login(result.data);
                                } else {
                                    callback([{id: 'password', message: 'Incorrect password'}]);
                                }
                            });
                        } else if (action == 'register') {
                            app.api.register(data, function(result) {
                                if (!result.data.errors) {
                                    app.$ui.accountDialog.close();
                                    ITF.login(result.data);
                                    ui.accountWelcomeDialog().open();
                                } else {
                                    callback([{id: 'password', message: result.data.errors.toString()}]); // fixme
                                }
                            });
                        } else if (action == 'reset') {
                            var usernameOrEmail = data.usernameOrEmail,
                                key = usernameOrEmail[0].id;
                            data = {};
                            data[key] = usernameOrEmail[1];
                            app.api.requestToken(data, function(result) {
                                if (!result.data.errors) {
                                    app.$ui.accountDialog.options(ui.accountDialogOptions('resetAndLogin', result.data.username));
                                } else {
                                    callback([{id: 'usernameOrEmail', message: 'Unknown ' + (key == 'username' ? 'username' : 'e-mail address')}])
                                }
                            });
                        } else if (action == 'resetAndLogin') {
                            app.api.resetPassword(data, function(result) {
                                if (!result.data.errors) {
                                    app.$ui.accountDialog.close();
                                    ITF.login(result.data);
                                } else {
                                    callback([{id: 'code', message: 'Incorrect code'}]);
                                }
                            })
                        }
                    }
                }).bindEvent({
                    submit: function(event, data) {
                
                    },
                    validate: function(event, data) {
                        Ox.print('FORM VALIDATE', data)
                        app.$ui.accountDialog[
                            (data.valid ? 'enable' : 'disable') + 'Button'
                        ]('submit' + Ox.toTitleCase(action));
                    }
                });
            that.items = $items;
            function item(type, value) {
                if (type == 'code') {
                    return new Ox.Input({
                        autovalidate: autovalidateCode,
                        id: 'code',
                        label: 'Code',
                        labelWidth: 120,
                        validate: function(value, callback) {
                            callback({
                                message: 'Missing code',
                                valid: !!value.length
                            });
                        },
                        width: 352
                    });
                } else if (type == 'email') {
                    return new Ox.Input({
                        autovalidate: autovalidateEmail,
                        id: 'email',
                        label: 'E-Mail Address',
                        labelWidth: 90,
                        type: 'email',
                        validate: validateUser('email'),
                        width: 250
                    });
                } else if (type == 'newPassword') {
                    return new Ox.Input({
                        autovalidate: /.+/,
                        id: 'password',
                        label: 'New Password',
                        labelWidth: 90,
                        type: 'password',
                        validate: function(value, callback) {
                            callback({
                                message: 'Missing password',
                                valid: value.length > 0
                            });
                        },
                        width: 250
                    });
                } else if (type == 'newUsername') {
                    return new Ox.Input({
                        autovalidate: autovalidateUsername,
                        id: 'username',
                        label: 'Username',
                        labelWidth: 90,
                        validate: validateUser('username'),
                        width: 250
                    });
                } else if (type == 'oldUsername') {
                    return new Ox.Input({
                        disabled: true,
                        id: 'username',
                        label: 'Username',
                        labelWidth: 90,
                        value: value,
                        width: 250
                    });
                } else if (type == 'password') {
                    return new Ox.Input({
        	            autovalidate: /.+/,
                        id: 'password',
                        label: 'Password',
                        labelWidth: 90,
                        type: 'password',
                        validate: function(value, callback) {
                            callback({
                                message: 'Missing Password',
                                valid: value.length > 0
                            });
                        },
                        width: 250
                    });
                } else if (type == 'username') {
                    return new Ox.Input({
                        autovalidate: autovalidateUsername,
                        id: 'username',
                        label: 'Username',
                        labelWidth: 90,
                        validate: validateUser('username', true),
                        width: 250
                    });    
                } else if (type == 'usernameOrEmail') {
                    return new Ox.FormElementGroup({
                        id: 'usernameOrEmail',
                        elements: [
                            app.$ui.usernameOrEmailSelect = new Ox.Select({
                                    id: 'usernameOrEmailSelect',
                                    items: [
                                        {id: 'username', title: 'Username'},
                                        {id: 'email', title: 'E-Mail Address'},
                                    ],
                                    overlap: 'right',
                                    width: 120
                                })
                                .bindEvent({
                                    change: function(event, data) {
                                        var selected = data.selected[0].id;
                                        app.$ui.usernameOrEmailInput.options({
                                            autovalidate: selected == 'username' ? autovalidateUsername : autovalidateEmail,
                                            validate: validateUser(selected, true),
                                            value: ''
                                        }).focus();
                                    }
                                }),
                            app.$ui.usernameOrEmailInput = new Ox.Input({
                                autovalidate: autovalidateUsername,
                                id: 'usernameOrEmailInput',
                                validate: validateUser('username', true),
                                width: 232
                            })
                        ],
                        separators: [
                            {title: '', width: 0}
                        ]
                    });
                }
            }
            return that;	        
	    },
        accountLogoutDialog: function() {
            var that = new Ox.Dialog({
                    buttons: [
                        new Ox.Button({
                            id: 'cancel',
                            title: 'Cancel'
                        }).bindEvent('click', function() {
                            that.close();
                            app.$ui.mainMenu.getItem('loginlogout').toggleTitle();
                        }),
                        new Ox.Button({
                            id: 'logout',
                            title: 'Logout'
                        }).bindEvent('click', function() {
                            that.close();
                            app.api.logout({}, function(result) {
                                ITF.logout(result.data);
                            });
                        })
                    ],
                    content: new Ox.Element('div').html('Are you sure you want to logout?'),
                    height: 160,
                    keys: {enter: 'logout', escape: 'cancel'},
                    title: 'Logout',
                    width: 300
                });
            return that;
        },
        accountWelcomeDialog: function() {
            var that = new Ox.Dialog({
                    buttons: [
                        [
                            new Ox.Button({
                                id: 'preferences',
                                title: 'Preferences...'
                            }).bindEvent('click', function() {
                                that.close();
                            })
                        ],
                        [
                            new Ox.Button({
                                id: 'close',
                                title: 'Close'
                            }).bindEvent('click', function() {
                                that.close();
                            })
                        ]
                    ],
                    content: new Ox.Element('div').html('Welcome, ' + app.user.username + '!<br/><br/>Your account has been created.'),
                    height: 160,
                    keys: {enter: 'close', escape: 'close'},
                    title: 'Welcome to ' + app.config.site.name,
                    width: 300
                });
            return that;
        }
    }

//FIXME: move these somewhere.
function autovalidateCode(value, blur, callback) {
    value = $.map(value.toUpperCase().split(''), function(v) {
        return /[0-9A-Z]/(v) ? v : null;
    }).join('');
    callback(value);
}

function autovalidateEmail(value, blur, callback) {
    value = $.map(value.toLowerCase().split(''), function(v, i) {
        return /[0-9a-z\.\+\-_@]/(v) ? v : null;
    }).join('');
    callback(value);
}

function autovalidateUsername(value, blur, callback) {
    var length = value.length;
    value = $.map(value.toLowerCase().split(''), function(v, i) {
        if (new RegExp('[0-9a-z' + ((i == 0 || (i == length - 1 && blur)) ? '' : '\-_') + ']')(v)) {
            return v
        } else {
            return null;
        }
    }).join('');
    $.each(['--', '-_', '_-', '__'], function(i, v) {
        while (value.indexOf(v) > -1) {
            value = value.replace(new RegExp(v, 'g'), v[0]);
        }
    })
    callback(value);
}

function validateUser(key, existing) {
    existing = existing || false;
    var string = key == 'username' ? 'username' : 'e-mail address';
    return function(value, callback) {
        var valid = key == 'username' ? !!value.length : Ox.isValidEmail(value);
        valid ? app.api.findUser({
            key: key,
            value: value,
            operator: '='
        }, function(result) {
            var valid = existing == !!result.data.users.length;
            Ox.print(existing, result.data.users)
            callback({
                message: existing ? 
                    'Unknown ' + string :
                    string[0].toUpperCase() + string.substr(1) + ' already exists',
                valid: valid
            });
        }) : callback({
            message: (!value.length ? 'Missing' : 'Invalid') + ' ' + string,
            valid: false
        });
    };
}

})();
