﻿// FieldMasks
var fieldMasks = (function(){
    function _email(value){
        // TODO: A regular expression that checks if entered value is a valid Email address
        var emailPattern = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
        
        if (value.length > 0) {
            if (!emailPattern.test(value)) {
                return false;
            }
        }
        
        return true;
    }
    
    function _password(value){
        // TODO: Not sure what I wanted to do here????
        // ...maybe...password size
        if (value.length < 0) {
            alert('some password validation is supposed to be placed here');
        }
    }
    
    function _phone(value){
    
        // TODO: A regular expression that checks if entered value is a valid Email address
        var phonePattern = /^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,5})|(\(?\d{2,6}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$/;
        
        if (value.length > 0) {
            if (!phonePattern.test(value)) {
                return false;
            }
        }
        
        return true;
    }
    
    return {
        Email: _email,
        Phone: _phone,
        Password: _password
    };
})();

// The DTOMergerFactory uses the DTO (field specs) to move data from the form to the DTO and vice versa.
var DTOMergerFactory = (function(){
    function generateMergeDTO(query, form){
        this.dto = query.dataConnector.dto;
        this.form = form;
        
        function _toFORM(dataBag){
            this.dto.each(function(fieldMap){
                this.form[fieldMap['inputName']] = dataBag[fieldMap['dbName']];
            });
        }
        
        function _toDTO(){
            var dataBag = $H({});
            window.DTOMergerFactory.dto.fieldSet.each(function(fieldMap){
                var element = $F(fieldMap.inputName);
                
                if (element) {
                    // If field found in the form then
                    dataBag.set(fieldMap.dbName, element.getValue());
                }
                else {
                    // Check if the value was passed by parameter
                    command = this.query.dataConnector.command;
                    if (command.parameters) {
                        if (command.parameters[fieldMap.inputName]) {
                            parameterValue = command.parameters[fieldMap.inputName];
                            dataBag.set(fieldMap.dbName, parameterValue);
                        }
                    }
                }
            }, this);
            
            return dataBag;
        }
        
        return {
            dto: this.dto,
            form: this.form,
            toDTO: _toDTO,
            toFrom: _toFORM
        };
    }
    
    return {
        GenerateMergeDTO: generateMergeDTO
    };
})();


// $.data Objects
$.data.Query = Class.create();

Object.extend($.data.Query, $.Events.Methods);

$.data.Query.prototype = {
    initialize: function(command, dto, dataConnector, events) {
        if (!Object.isUndefined(command)) {

            // <-- Configure the DataConnector -->
            dataConnector.command = command;
            dataConnector.dto = dto;
            dataConnector.parentScope = this;

            this.dataConnector = dataConnector;
            this.resultSet = [{}];

        }
        else {
            throw 'No command supplied to Query Object';
        }

        // Register Events
        this['$.query.success'] = $A();
        this['$.query.failure'] = $A();
        this['$.query.exception'] = $A();
        this['$.query.complete'] = $A();

        if (!Object.isUndefined(events)) {
            if (events.onsuccess) this['$.query.success'].push(events.onsuccess);
            if (events.onfailure) this['$.query.failure'].push(events.onfailure);
            if (events.onexception) this['$.query.exception'].push(events.onexception);
            if (events.oncomplete) this['$.query.complete'].push(events.oncomplete);
        }
    },

    _selectSingle: function() {
        return this.dataConnector.SelectSingle();
    },

    _selectMany: function() {
        this.dataConnector.SelectMany(); //.call(this, this.filters);
    },

    _selectManyWithPost: function() {
        this.dataConnector.SelectManyWithPost(); //.call(this, this.filters);
    },

    _selectManyWithGet: function() {
        this.dataConnector.SelectManyWithGet();
    },

    _selectSingleWithGet: function() {
        this.dataConnector.SelectSingleWithGet();
    },

    _storeProcedure: function() {
        this.dataConnector.StoredProcedure();
    },

    _sendMail: function(eMailId) {
        this.dataConnector.SendMail();
    },
    
    bindAsEventListener: function(eventName, eventHandler) {
        if (!Object.isUndefined(this[eventName])) {
            this[eventName].push(eventHandler);
        }
    },

    bindAsDataConnectorEventListener: function(eventName, eventHandler) {
        if (!Object.isUndefined(this.dataConnector)) {
            if (!Object.isUndefined(this.dataConnector[eventName])) {
                this.dataConnector[eventName].push(eventHandler);
            }
        }
    },

    bindQueryParameters: function(parameters) {
        if (Object.isArray(this.dataConnector.command.parameters.QueryString))
            this.dataConnector.command.parameters.QueryString.push(parameters);
        else
            this.dataConnector.command.parameters.QueryString = parameters;
    },

    validateSecurity: function(policy, record) {
        if (!Object.isArray(policy))
            policy = $A().push(policy);

        isPermissionGranted = true;

        policy.each(function(token) {
            //{ environmentVariable: 'MemberID', dbVariable: 'MemberID', expression: 'equal'}

            parameterKeyValue = this.getParamKey(token.environmentVariable);
            dbKeyValue = record[token.dbVariable];

            switch (token.expression) {
                case 'equal':
                    isPermissionGranted = isPermissionGranted && (parameterKeyValue == dbKeyValue);
                    break;
                default:
                    isPermissionGranted = true;
                    break;
            }
        }, this);

        return isPermissionGranted;

    },

    executeSQLtoJSON: function() {
        switch (this.dataConnector.command.type) {
            case 'QueryVerb':
                switch (this.dataConnector.command.queryVerb) {
                    case 'SelectMany':
                        this._selectMany();
                        break;
                    case 'SelectSingle':
                        this._selectSingle();
                    case 'SelectManyWithPost':
                        this._selectManyWithPost();
                        break;
                    case 'DataByFilter':
                        this._SelectDataByFilter();
                        break;
                    case 'SelectSingleWithGet':
                        this._selectSingleWithGet();
                        break;
                    case 'SelectManyWithGet':
                        this._selectManyWithGet();
                        break;
                    default:
                        break;
                }
                break;

            case 'StoreProcedure':
                this._storeProcedure();
                break;

            default:
                break;
        }
    },

    getParamKey: function(keyName) {
        paramValue = this.dataConnector.command.parameters.QueryString[keyName];

        if (Object.isUndefined(paramValue))
            return null;
        else
            return paramValue;
    }
};
