﻿/** @class TNRIS.NfipXmlShapeLayer
*/

TNRIS.NfipXmlShapeLayer = function(config) {
    Ext.applyIf(this, {
        id: Ext.id(),
        shapeLineColor: new VEColor(100,0,0,0.6),
        shapeFillColor: new VEColor(100,0,0,0.6),
        shapeIcon: '<div class="globePushpin"><img src="images/pushPins/greenGlobePin.png" /></div>'
    });
    TNRIS.NfipXmlShapeLayer.superclass.constructor.call(this, config);
};

Ext.extend(TNRIS.NfipXmlShapeLayer, TNRIS.XmlShapeLayer, {
    hasRestrictedEdit: function() {
        return true;
    },

    getShapeEditor: function() {
        var editor = Ext.getCmp('NfipShapeEditorWindow');
        if (null == editor) {
            editor = new TNRIS.NFipXmlLayerUserDataWindow({id: 'NfipShapeEditorWindow', layer: this});
        }
        return editor;
    },

    gridColumnSpecs: function() {
        var gridStore = this.getGridStore();
        if (null == gridStore || null == gridStore.fields) {
            return [];
        }
        
        var fields = [];
        Ext.each(this.getColumnConfigs(), function(config) {
            fields.push( { header: config.guiName, dataIndex: config.dbName});
        }, this);
    
        return fields;
    },
    
    getLayerExportWindow: function() {
        var winTitle = 'Exporting ' + this.name();
        var exportWin = new TNRIS.NFIPExportWindow({title: winTitle, layer: this});
        exportWin.load();
        return exportWin;
    }
    
});

/** @class Dialog box for exporting NFIP layer features to the database
@constructor
@param {object} config
*/
TNRIS.NFIPExportWindow = function(config) {
    Ext.apply(this,config);
   
    this.form = new Ext.form.FormPanel({
        layout: 'fit',
        labelAlign:'top',
        items: [
            { id: 'nfipFeatureCount', cls: 'nfipFeatureCount', xtype: 'label' },
            { id: 'nfipSelectedCount', cls: 'nfipSelectedCount', xtype: 'label' },
            { id: 'nfipExportCount', cls: 'nfipExportCount', xtype: 'label' },
            { id: 'nfipFailedCount', cls: 'nfipFailedCount', xtype: 'label' }
        ]
    });
    
    this.nhdStore = this.layer.getGridStore();
    this.sm = new Ext.grid.CheckboxSelectionModel({singleSelect:false,sortable:true});
    this.layer.on({
        'loadGrid': {
            scope: this,
            fn: function(s, r, o) {
                this.featureCount = this.nhdStore.getCount();
                var columns = this.layer.gridColumnSpecs();
                columns = [this.sm].concat(columns);
                columns = columns.concat([{header:'Record Status',renderer: this.validateNhdRecord.bind(this)}]);

                this.exportGrid = new Ext.grid.GridPanel({
                    store: this.nhdStore,
                    columns: columns,
                    stateful: false,
                    autoShow: true,
                    sm: this.sm
                });
                
                this.form.add(this.exportGrid);
                this.form.doLayout();
            },
            single: true
        }
    });
    
    TNRIS.NFIPExportWindow.superclass.constructor.call(this, {
        id: 'nfipExportWindow',
        cls: 'nfipExportWindow',
        layout: 'form',
        width: 500,
        height: 400,
        modal: true,
        resizable: false,
        stateful: false,
        closeAction: 'close',
        items: [this.form],
        buttonAlign: 'center',
        buttons: [
            {
                text: 'Export',
                scope: this,
                handler: this.onExportClick
            },
            {
                text: 'Cancel',
                scope: this,
                handler: function() {
                    this.close();
                }   
            }
        ]
    });
};

Ext.extend(TNRIS.NFIPExportWindow, Ext.Window,{
    load:function() {
        this.layer.loadGridData();
    },
    
    onExportClick: function(){
        this.selectedFeatures = this.sm.getSelections();
        this.selected = this.selectedFeatures.length;
        this.total = this.nhdStore.getCount();
        this.exported = 0;
        this.failed = 0;
        
        var featuresToExport = [];
        Ext.each(this.selectedFeatures,function(record) {
            var featureData = this.getFeatureDateFromRecord(record);
            if (this.checkFeatureValidity(featureData)){
                featuresToExport.push(featureData);
            }else {
                this.failed++;
            }
        },this);
        
        this.getEl().mask('Exporting selected records to server... Please Wait!!');
        PageMethods.submitNfipFeature(featuresToExport,function(exportedResult){
            this.getEl().unmask();
            var successList = exportedResult.successItems;
            var failList = exportedResult.failureItems;
            
            Ext.each(successList, function(itemId) {
                this.exported++;
                this.layer.deletedRecords.push(itemId);
            },this);
            
            Ext.each(failList, function(itemId) {
                this.failed++;
            },this);
            
            this.updateStatus();
            this.layer.commitShapeData(
                function() { 
                    this.layer.reload();
                    this.updateStatus();
                    Ext.Msg.alert("Export Completed"," The export is compeleted and all successfully exported features were deleted from your NFIP layer."); 
                }.bind(this));
        }.bind(this));

    },
    
    updateStatus: function() {
        Ext.getCmp('nfipExportCount').getEl().update('<br/>Exported: '+ this.exported + ' Records ');
        Ext.getCmp('nfipFailedCount').getEl().update('<br/>Failed: '+ this.failed + ' Records ');
        Ext.getCmp('nfipFeatureCount').getEl().update('Total: '+ this.total + ' Records ');
        Ext.getCmp('nfipSelectedCount').getEl().update('<br/>Selected: '+ this.selected + ' Records ');
    },
    
    validateNhdRecord: function(value,metadata,record,rIndex,colIndex,store){
        var result = "";
        var featureData = this.getFeatureDateFromRecord(record);
        if (this.checkFeatureValidity(featureData)){
            result = '<font color ="green">Ready to export</font> ';
        }else {
            result= '<font color ="red">Insufficient Data</font> ';
        }
        return result;
    },
    
    getFeatureDateFromRecord: function(record) {
        var featureData = {
            "id" : record.id ,
            "Name" : record.get('1'),
            "Email" : record.get('2'),
            "Phone" : record.get('3'),
            "AlternatePhone" : record.get('4'),
            "Position" : record.get('5'),
            "LengthOfStudy" : record.get('6'),
            "MappingType" : record.get('7'),
            "ExistingStudyAvailable" : record.get('8'),
            "ReasonOfStudy" : record.get('9'),
            "InformationAvailable" : record.get('10'),
            "Funding" : record.get('11'),
            "ShapePoints" : record.get('shapePoints'),
            "ShapeType" : record.get('shapeType')
        };
        return featureData;
    },
    
    checkFeatureValidity: function(feature){
        var result = true;
        fieldsToValidate = ["ExistingStudyAvailable", "InformationAvailable", "LengthOfStudy", "MappingType", "Position", "ReasonOfStudy"];

        Ext.each(fieldsToValidate,function(field) {
            var fVar = "feature." + field;
            var value = eval(fVar);
            if ((null == value) || ("" == value)){
                result = false;
                return false;
            }
        },this);

        return result;
    }
    
});


TNRIS.NFipXmlLayerUserDataWindow = function(config) {
    Ext.apply(this, config);

    //syntax must be similar to XmlLayerUserDataWindow
    this.fieldRecordConstructor = Ext.data.Record.create(['dbName', 'guiName', 'order', 'dbType', 'isId', 'isName', 'isHidden', 'isGeometry', 'value']);
    
    this.fieldStore = new Ext.data.Store({
        reader: new Ext.data.JsonReader({}, this.fieldRecordConstructor)
    });
    
    this.sm = new Ext.grid.CheckboxSelectionModel({singleSelect:false,sortable:true});
    
    this.reasonStore = new Ext.data.Store({
        reader: new Ext.data.ArrayReader({}, ['Reason'])
    });
    
    this.reasonGrid = new Ext.grid.GridPanel({
        id: 'reasonGrid',
        store: this.reasonStore,
        autoExpandColumn: 'reason',
        border: true,
        stateful: false,
        anchor: '96%',
        height: 110,
        cls: 'reasonGrid',
        columns: [this.sm, {id: 'reason',header: 'List Of Reasons', dataIndex: 'Reason'} ],
        sm: this.sm
    });

    this.form = new Ext.FormPanel({
        bodyStyle: 'padding:5px; background-color: transparent',
        defaultType: 'textfield',
        layout: 'form',
        autoScroll: true,
        defaults: { maxLength: 100 },
        items: [
            {   
                id: 'Name', 
                fieldLabel: 'Name', 
                width: 200, 
                disabled: true 
            },
            {   
                id: 'Email', 
                fieldLabel: 'Email', 
                width: 200, 
                disabled: true
            },
            {   
                id: 'Phone', 
                fieldLabel: 'Phone', 
                width: 200, 
                disabled: true
            },
            {   
                id: 'AlternatePhone', 
                fieldLabel: 'Alternate phone', 
                width: 200,
                emptyText: '[Like... 512-463-8337]',
                regex: new RegExp(/^[01]?[- .]?(\([2-9]\d{2}\)|[2-9]\d{2})[- .]?\d{3}[- .]?\d{4}$/),
                regexText:'Please enter the phone number in correct format.'
            },
            {   
                id: 'Position', 
                fieldLabel: 'Position', 
                xtype: 'combo', 
                allowBlank: false,
                blankText: 'Please select your position.',
                width: 200, 
                editable: false, 
                forceSelection: false, 
                mode: 'local', 
                selectOnFocus: true, 
                triggerAction: 'all', 
                emptyText:'-- Select position --',
                store: [    "Floodplain Administrator for Area",
                            "City/County Official",
                            "City/County Engineer",
                            "COE or other Federal Engineer",
                            "Regional/Authority MUD/staff", 
                            "Concerned Citizen"
                ]
            },
            { 
                id: 'LengthOfStudy', 
                fieldLabel: 'Study distance', 
                width: 200,
                allowBlank: false,
                blankText: 'Study length can not be empty. Either allow the system calculated length or enter the length manually in miles.',
                cls: 'txtLengthOfStudy', 
                fieldClass: 'fldLengthOfStudy' 
            },
            {
                id: 'MappingType', 
                fieldLabel: 'Mapping type', 
                xtype: 'combo',
                allowBlank: false, 
                blankText: 'Please select a mapping type',
                width: 200, 
                editable: false, 
                forceSelection: true, 
                mode: 'local', 
                selectOnFocus: true, 
                triggerAction: 'all', 
                emptyText:'-- Select mapping type --',
                store: [    ["Approximate A","Approximate A"],
                            ["Approximate A with profile","Approximate A with profile"],
                            ["Limited detail","Limited detail"],
                            ["Detailed study - 100 year only","Detailed study - 100 year only"],
                            ["Detailed study - 10,50,100,500 year profiles","Detailed study - 10,50,100,500 <br/> year profiles"], 
                            ["Detailed study - 10,50,100,500 year profiles with floodway","Detailed study - 10,50,100,500 <br/> year profiles with floodway"],
                            ["Coastal Zone V","Coastal Zone V"], 
                            ["Coastal Zone VE","Coastal Zone VE"], 
                            ["Zone AO(Alluvial Fan)","Zone AO(Alluvial Fan)"]
                ]
            },
            {
                id: 'ExistingStudyAvailable', 
                fieldLabel: 'Is there an existing study', 
                labelSeparator: '?',
                xtype: 'combo',
                allowBlank: false,
                blankText: 'Please specify if there is an existing study available.',
                width: 100, 
                editable: false, 
                forceSelection: true, 
                emptyText:'-- Select --',
                mode: 'local', 
                selectOnFocus: true, 
                triggerAction: 'all',
                store: [    "Yes" , "No" ]
            },
            { 
                xtype: 'label', 
                cls:'x-form-item', 
                text: 'Reason for study:'
            },
            this.reasonGrid,
            { 
                xtype: 'label', 
                cls:'lblInformation x-form-item' , 
                text: 'Any additional information available?'
            },
            {
                xtype: 'fieldset',
                cls: 'nfipInformationRadio',
                autoHeight: true,
                anchor: '95%',
                border: false,
                items: [
                    {   
                        xtype: 'checkbox', id: 'chkHistoricalHighWater', hideLabel: true ,
                        boxLabel: "Historical Highwater Marks", name: 'chk-hhw', value: 'Historical Highwater Marks'
                    },
                    {   
                        xtype: 'checkbox', id: 'chkSurveyData', hideLabel: true ,
                        boxLabel: "Survey Data", name: 'chk-sd', value: 'Survey Data'  
                    },
                    {   
                        xtype : 'textfield', id: 'informationOthers', fieldLabel: 'Other Information', 
                        width: 200, emptyText:'[Optional]'
                    } 
                ]
            },
            {
                xtype: 'textfield', 
                id: 'Funding', 
                fieldLabel: 'Funding amount for this effort',
                cls: 'fundingAmount', 
                emptyText: '[Leave blank if none]',
                regex: new RegExp(/^\d+(\.\d\d)?$/),
                regexText:'Please specify a valid number with or without decimal value.'
            }
            ]
    });


    TNRIS.NFipXmlLayerUserDataWindow.superclass.constructor.call(this, {
        title: 'NFIP Map Needs Properties',
        height: 610,
        width: 400,
        anchor: '90%',
        layout: 'fit',
        closable: false, 
        resizable: false,
        closeAction: 'close',
        buttonAlign: 'center',
        stateful: false,
        modal: true,
        items: this.form,
        buttons: [
            {
                id: 'okButton',
                text: 'Ok',
                scope: this,
                handler: this.onOK
            }, {
                id: 'cancelButton',
                text: 'Cancel',
                scope: this,
                handler: function() {this.onClose(); }
            }
        ],
        listeners: {
            'show': {
                scope: this,
                fn: this.onShow
            }
        }
    });
    this.form.doLayout();
};

Ext.extend(TNRIS.NFipXmlLayerUserDataWindow, Ext.Window,
/** @scope TNRIS.NFipXmlLayerUserDataWindow */
    {
    load: function(shapeId, array) {
        this.shapeId = shapeId;
        this.fieldStore.loadData(array);
        this.fieldArray = array;
        this.reasonStore.loadData([["No map exist"], ["No map exists due to development in the area"], ["Map is out of date due to terrain data"], ["Map is out of date due to development in the area"], ["Map is out of date due to hydrologic data"]]);
    },
    
    onShow: function() {
        if (this.fieldArray.length > 0 ) {
            Ext.each(this.fieldArray, function(field) {
                switch (field.guiName) {
                    case 'ReasonOfStudy':
                        this.setReasonOfStudyValue(field.value);
                        break;
                    case 'InformationAvailable':
                        this.setInformationAvailableValue(field.value);
                        break;
                    case 'LengthOfStudy':
                        if ((null == field.value)||("" == field.value)) {
                            this.setApproxLength();
                        } else {
                            var fieldCmpLen = this.form.findById(field.guiName);
                            if (null != fieldCmpLen) { fieldCmpLen.setValue(field.value); }
                        }
                        break;
                    default: 
                        var fieldCmp = this.form.findById(field.guiName);
                        if (null != fieldCmp) { fieldCmp.setValue(field.value); }
                        break;
                }
            }, this);
            this.setUserDetails();
        }
    },

    setUserDetails: function() {
        PageMethods.getUserDetail(function(userInfo) {
            this.form.findById('Name').setValue(userInfo.name);
            this.form.findById('Phone').setValue(userInfo.phone);
            this.form.findById('Email').setValue(userInfo.email);
        } .bind(this));
    },

    setApproxLength: function() {
        var shapes = [];
        var shape = this.layer.getShapeByRecordId(this.shapeId);
        shapes.push(shape);
        var geoCalculator = new TNRIS.GeoCodeCalc();
        geoCalculator.calcPersistedShapeAttributes(shapes, "", function(result) {
            this.form.findById('LengthOfStudy').setValue(result.length.toFixed(4) + " Miles");
        } .bind(this));
    },

    onOK: function() {
        //TODO: check for form validity
        if (!this.validateFormFields()) {
            return;
        }

        this.fieldStore.each(function(record) {
            var fieldName = record.get('guiName');
            var recordValue;
            switch (fieldName) {
                case 'ReasonOfStudy':
                    recordValue = this.getReasonOfStudyValue();
                    break;
                case 'InformationAvailable':
                    recordValue = this.getInformationAvailableValue();
                    break;
                default:
                    var field = this.form.findById(fieldName);
                    recordValue = field.getValue();
                    break;
            }
            record.set('value', recordValue);
        }, this);

        var fields = this.fieldStore.getRange();
        this.layer.updateShapeData(this.shapeId, fields);
        this.onClose();
    },

    getReasonOfStudyValue: function() {
        if(this.sm.getCount() == 0 ) {
            return "";        
        }

        var selections = this.sm.getSelections();
        var resultXml = "<Xml>{0}</Xml>";
        
        var xmlSelections = "";
        Ext.each(selections,function(record) {
            var selValue = record.get('Reason');
            xmlSelections += ("<SelectedReasons><Selected>"+ selValue + "; </Selected></SelectedReasons>");
        },this);
        
        resultXml =String.format(resultXml,xmlSelections );
        return resultXml;
    },
    
    setReasonOfStudyValue: function(value) {
        if (null == value) { 
            return;
        }
        
        var reasonRec = Ext.data.Record.create([
           {name: 'Selected'}  
        ]);

        var myReader = new Ext.data.XmlReader({
            record: 'SelectedReasons'
        }, reasonRec);

        var store = new Ext.data.Store({
            reader: myReader
        });

        store.loadData(value,false);
        var selectons= [];
        store.each(function(record){
            var sValue = record.get('Selected');
            
            sValue= sValue.substring(0,(sValue.length-2));
            
            this.reasonStore.each(function(reasonRec){
                if (reasonRec.get('Reason') == sValue) {
                    selectons.push(reasonRec);
                }
            },this);
        },this);
        
        this.sm.clearSelections();
        this.sm.selectRecords(selectons);
    },

    getInformationAvailableValue: function() {
        var result = "";
        var chkHistWater = this.form.findById('chkHistoricalHighWater').getValue() ? 'Historical HighWater Marks; ' : '';
        var chkSurData = this.form.findById('chkSurveyData').getValue() ? 'Survey Data; ' : '';
        var infOthers = this.form.findById('informationOthers').getValue();
        
        if ((chkHistWater == '') && (chkSurData == '') && ((null == infOthers)||("" == infOthers))) {
            result="";
        }   
        else {
            result = ["<Xml><InformationAvailable>",
                                "<Historical>{0}</Historical>",
                                "<SurveyData>{1}</SurveyData>",
                                "<Others>{2}</Others>",
                        "</InformationAvailable></Xml>"].join("");

            result = String.format(result, chkHistWater, chkSurData, infOthers);
        }
        return result;
    },
    
    setInformationAvailableValue: function(value) {
        if ((null == value) || (""== value)) {
            return;
        }
        
        var infoRecord = Ext.data.Record.create([
           {name: 'Historical'},{name: 'SurveyData'},{name: 'Others'}   
        ]);

        var myReader = new Ext.data.XmlReader({
            record: 'InformationAvailable'
        }, infoRecord);

        var store = new Ext.data.Store({
            reader: myReader
        });

        store.loadData(value);
        
        if (store.getCount() > 0 ) {
            var details = store.getAt(0);
        }
        
        var hist = details.get('Historical');
        var surv = details.get('SurveyData');
        var other = details.get('Others');
    
        if (hist == 'Historical HighWater Marks; ') {this.form.findById('chkHistoricalHighWater').setValue(true); }
        if (surv == 'Survey Data; ') {this.form.findById('chkSurveyData').setValue(true); }
        if ((null != other)&&("" != other)) {this.form.findById('informationOthers').setValue(other); }

    },

    validateFormFields: function() {
        var fieldsToValidate = [
            ["Position", "Please select your job position"],
            ["LengthOfStudy",  "Please specify the length of study"],
            ["MappingType", "Pleas select the type of mapping need to be done"],
            ["ExistingStudyAvailable", "Please select whether there is any existing study available in this area"],
            ["ReasonOfStudy", "Please select atleast one reason, why you need a study"],
            ["InformationAvailable","Please specify the information that you could provide"]
        ];
        
        var validationStatus = true;

        Ext.each(fieldsToValidate, function(field) {
            var result = this.validateField(field[0]);
            if (!result) {
                var message ="";
                Ext.Msg.alert("Validation Failed", field[1]);
                validationStatus = false;
                return false;
            }
        }, this);
        
        return validationStatus;

    },
    
    validateField: function(fieldName) {
        var result = false;
        var value;
        switch(fieldName) {
            case "ReasonOfStudy":
                value = this.getReasonOfStudyValue();
                break;
            case "InformationAvailable":
                value = this.getInformationAvailableValue();
                break;
            default:
                var cmp = this.form.findById(fieldName);
                value = cmp.getValue();
                break;
        }
        
        if ((null != value) && (value != "")) {
            result = true;
        }
        return result;
    },

    onClose: function() {
        this.close();
    }
});

if (typeof(Sys) !== "undefined") { Sys.Application.notifyScriptLoaded(); }
