'use strict';

jQuery(function() {
    init_ewz_layouts();
});
jQuery(window).on("load",function() {
    do_layout_setup();
});

var ewzG, ewzG1;
var popupN;
var nNew, newFnum;
var ajaxurl;
var layouts_done = new Object();
var g_changesMade, g_doingSubmit;


/** ewzG represents what is on the server. Should be changed after save or delete only **/
/************************** The OnLoad Function  ****************************************/
/* called on load                                   */
/* generates the whole page from the ewzG structure */
function init_ewz_layouts() {
    fixConsole();
    var i, restr;
    g_changesMade = false;
    g_doingSubmit = false;
    popupN = 0;
    nNew = 0;
    newFnum = 0;

    // ewzG is null if not logged in
    if (null !== ewzG1) {
        ewzG = ewzG1.gvar;
        if( ewzG.do_warn ){
            window.addEventListener("beforeunload", function (e) {
                if( g_changesMade && !g_doingSubmit ){
                    // dummy -- in newer browsers the message cannot be overwritten
                    var confirmationMessage = "Really leave this page? Changes you made may not be saved.";
                    (e || window.event).returnValue = confirmationMessage; //Gecko + IE
                    return confirmationMessage;                            //Webkit, Safari, Chrome
                }
           });
        }

        // console.log("INIT ewzG", ewzG);
        for (i = 0; i < ewzG.layouts.length; ++i) {
            // error message, page titles, fields
            var lid = ewzG.layouts[i].layout_id;
            jQuery('#ewz_layouts').append(layout_str( lid, ewzG.layouts[i] ));

            // restrictions (one blank for each existing - will fill out later
            for (restr = 0; restr < ewzG.layouts[i].restrictions.length; ++restr) {
                jQuery('#restricts_f' + lid  + '_').append(new_restriction_str(lid, jQuery('#add_restr_f' + lid + '_').get()));
            }
        }
        if (ewzG.message) {
            ewz_alert('L001','<pre>' + ewzG.message + '</pre>', ++popupN);
        }

        for (var lnum = 0; lnum < ewzG.layouts.length; ++lnum) {
            var lid = ewzG.layouts[lnum].layout_id;
            // disable required fields for radio buttons or labels
            disable_required_for_radio_lab(lnum);
            layouts_done[lid] = false;
        }

        // add expand_all, close_all
        add_expander();
    }
}

function do_layout_setup(){
    // make the layout postboxes sortable
    // ( "clone" option needed for firefox to stop opening on drag-drop )
    jQuery('#ewz_layouts').sortable({
        containment: 'parent',
        handle: ".ewz_hndle",
        items: "> div",
        distance: 5,
        helper: "clone"
    });
}

/************************ Functions Returning an HTML String ****************************************/

/* Returns the html string for a postbox containing a single layout */
function layout_str( lnum, fObj) {

    var i, key, str, kvalue, khead, korigin;
    /*********** Postbox *************/
    str = '<div id="ewz_admin_layouts_f' + lnum + '_" class="metabox-holder">';

    str += '    <div id="ewz_postbox-layout_f' + lnum + '_" class="ewz_box closed" style="display: block;" >';

    str += '       <h3 id="tpg_header_f' + lnum + '_"  class="ewz_hndle"  title="Click to toggle" onClick="toggle_layout_box(this )">';
    str += '           <span class="ewz_indicator"></span>' + fObj.layout_name + '</h3>';

    /*********** General *************/
    str += '       <div class="inside">';
    str += '          <form method="POST" action="" id="cfg_form_f' + lnum + '_" ';
    str += '                onSubmit="return ewz_check_layout_input(this, ' + ewzG.jsvalid + ')">';
    str += '          <div class="ewzform ewz_scrollx">';
    str += '             <input type="hidden" name="ewzmode" value="layout">';
    str += '             <input type="hidden" name="layout_id" id="layout_id' + lnum + '_"value="' + fObj.layout_id + '">';
    str += '             <div class="ewz_data ewz_scrollx ewz_95">';
    if (fObj.n_webforms > 0) {
        str += '      <div class="ewz_warn">Warning: This layout is in use by ' + fObj.n_webforms + ' webforms.<br /> ';
        if (fObj.n_items > 0) {
            str += fObj.n_items + ' items have already been uploaded. <br />';
            str += 'Making changes now could cause serious problems.';
        } else {
            str += 'Changes made now will affect them, <br />but no items have yet  been uploaded.';
        }
        str += '      </div>';
    }
    str += '                <p class="ewz_sect_title"><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'layout\')">';
    str += '                   &nbsp;General Information';
    str += '                </p>';
    str += '                <table>';
    str += '                    <tr><td><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'name\')">&nbsp;Name for this layout</td>';
    str += '                        <td>' + textinput_str('f' + lnum + '_layout_name_', 'layout_name', 60, fObj.layout_name) + '</td>';
    str += '                    </tr>';
    str += '                    <tr><td><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'maxnum\')">&nbsp;Maximum number of items &nbsp;</td>';
    str += '                        <td>' + numinput_str('f' + lnum + '_max_num_items_', 'max_num_items', '', 1, ewzG.maxNumitems, Number(fObj.max_num_items));
    str += '                        &nbsp; &nbsp; Overrideable by webforms: &nbsp; ' + checkboxinput_str('f' + lnum + '_override_', 'override', fObj.override ) + '</td>';
    str += '                    </tr>';
    str += '                    <tr><td><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'notes\')">&nbsp;Notes</td>';
    str += '                        <td>';
    str += '                            <textarea rows="1" cols="40" maxlength="500" id="' + 'f' + lnum + '_layout_notes' + '" name="notes" >';
    str +=                             fObj.notes + '</textarea>';
    str += '                        </td>';
    str += '                    </tr>';
    str += '                </table>';
    str += '             </div>';


    str += duplicate_buttons( lnum, '1', fObj );

    /*********** Fields *************/
    str += '             <div class="ewz_data ewz_95">';
    str += '                <span class="ewz_sect_title"><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'field\')">';
    str += '                   Fields to be entered/uploaded for each item</span> &nbsp; &nbsp; &nbsp; ';
    str += '                      ( <i>Items affected by restrictions are outlined in red and may not be edited</i>';
    str += '                        <img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'restr\')"> &nbsp;)';
    str += '                <div class="ewz_95">';
    str += '                   <div  id="ewz_sortable_f' + lnum + '_" >';
    // <br> needed at top and bottom to drag a field to the top or bottom
    str += '<br />';
    for (i = 0; i < fObj.forder.length; ++i) {
        str += field_str(lnum, fObj.forder[i], fObj.fields[fObj.forder[i]]);
    }
    // removed so "next" works when checking append in do_all_checks
    //   str += '<br />';
    str += '                   </div>';
    str += '                   <p>';
    str += '                      <img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'ftype\')">&nbsp;Add another field: &nbsp; ';
    str += '                      <button type="button" class="button-secondary" id="addTextBtn_f' + lnum + '_" onClick="add_field( this, ' + "'str'" + ')">';
    str += '                          A Text Entry</button>';
    str += '                      <button type="button" class="button-secondary" id="addImgBtn_f' + lnum + '_" onClick="add_field( this, ' + "'img'" + ')">';
    str += '                          An Image File</button>';
    str += '                      <button type="button" class="button-secondary" id="addOptBtn_f' + lnum + '_" onClick="add_field( this, ' + "'opt'" + ')">';
    str += '                          A Drop-down Selection</button>';
    str += '                      <button type="button" class="button-secondary" id="addRadBtn_f' + lnum + '_" onClick="add_field( this, ' + "'rad'" + ')">';
    str += '                          A Radio Button</button>';
    str += '                      <button type="button" class="button-secondary" id="addChkBtn_f' + lnum + '_" onClick="add_field( this, ' + "'chk'" + ')">';
    str += '                          A Check Box</button>';
    str += '                      <button type="button" class="button-secondary" id="addLabBtn_f' + lnum + '_" onClick="add_field( this, ' + "'lab'" + ')">';
    str += '                          A Fixed-Text Label</button>';
    str += '                   </p>';
    str += '                </div>';
    str += '             </div>';

    str += duplicate_buttons( lnum, '2', fObj );

    /*********** Restrictions *************/
    str += '             <div class="ewz_data ewz_95">';
    str += '                <p class="ewz_sect_title"><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'restr\')">';
    str += '                    Optional Restrictions On Allowed Field Values';
    str += '                </p>';
    str += '                <div class="ewz_95">';
    str += '                   <div id="restricts_f' + lnum + '_">';
    str += '                   </div>';
    str += '                   <button type="button" id="add_restr_f' + lnum + '_" class="button-secondary" onClick="add_restriction(this)">';
    str += '                         Add A New Restriction</button>';
    str += '                </div>';
    str += '             </div>';

    str += duplicate_buttons( lnum, '3', fObj );

    /*********** Spreadsheet *************/
    str += '             <div class="ewz_data ewz_95">';
    str += '                <p class="ewz_sect_title"><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'xtra\')">';
    str += '                    Extra Data To Show In Spreadsheet';
    str += '                </p>';
    str += '                <div class="ewz_95">';
    str += '                   <div id="spread_f' + lnum + '_" class="ewz_box closed">';
    str += '                      <h3 id="hspread_f' + lnum + '_" class="ewz_hndle"  title="Click to toggle" onClick="toggle_ewz_box(this)">';
    str += '                          <span class="ewz_indicator"></span>Select Items</h3>';
    str += '                      <div class="inside">';
    str += '                         <table class="ewz_field">';


    for (key in ewzG.display) {
        if (ewzG.display.hasOwnProperty(key)) {
            kvalue = fObj.extra_cols[key];
            khead = ewzG.display[key].header;
            korigin = ewzG.display[key].origin;
            str +=                             '<tr><td>' + khead + ' ( <i> ' + korigin + ' data )</i></td><td>';
            str += colinput_str('f' + lnum + '_extra_cols_' + key + '_', 'extra_cols[' + key + ']', kvalue, 'ssc' + lnum);
            str +=                             '</td></tr>';
        }
    }

    str +=                          '</table>';
    str +=                       '</div>';
    str +=                    '</div>';
    str +=                 '</div>';
    str +=              '</div>';

    /*********** Save/Delete *************/
  /*  str +=              '<div class="ewz_numc">' + ewzG.nonce_string + '</div>';*/
    str +=                  '<table class="ewz_buttonrow">';
    str +=                     '<tr>';
    str +=                        '<td><button type="submit" id="lsub_f' + lnum + '_" class="button-primary">Save Changes to <i>' + fObj.layout_name + '</i>';
    str +=                            '</button>';
    str +=                        '</td>';

    str +=                       '<td><button type="button" id="lspr_col_f' + lnum + '_" class="button-secondary" ';
    str +=                            'onClick="show_spread_columns(' + lnum + ",'" + fObj.layout_name + "')" + '">Show Summary of Assigned Spreadsheet Columns';
    str +=                           '</button>';
    str +=                        '</td>';
    str +=                       '<td class="ewz_waitmessage"></td>';
    if (ewzG.can_do) {
        str +=                    '<td class="ewz_right">';
        str +=                        '<button type="button" id="ldel_f' + lnum + '_" class="button-secondary" ';
        str +=                            'onClick="delete_layout(this, ' + fObj.n_webforms + ', ' + fObj.n_items + ' )">Delete <i>' + fObj.layout_name + '</i>';
        str +=                        '</button>';
        str +=                    '</td>';
    }
    str +=                     '</tr>';
    str +=                 '</table>';
    str +=            '</div>';
    str +=           '</form>';
    str +=        '</div>';
    str +=     '</div>';
             // add a div for the spreadsheet columns popup
    str +=     '<div id="spread_cols_display' + lnum + '" class="wp-dialog" ></div>';
    str += '</div>';


    return str;
}

/* return the html for the extra "Save" and "Show Summary" buttons */
function duplicate_buttons( lnum, bnum, fObj ){

    var str = '<table class="ewz_buttonrow">';
    str +=      '<tr>';
    str +=         '<td><button type="submit" id="lsub_f' + lnum + '_' + bnum + '" class="button-primary">Save Changes to <i>' + fObj.layout_name + '</i>';
    str +=             '</button>';
    str +=         '</td>';
    str +=         '<td><button type="button" id="lspr_col_f' + lnum + '_' + bnum + '" class="button-secondary" ';
    str +=                     'onClick="show_spread_columns(' + lnum + ",'" + fObj.layout_name + "')" + '">Show Summary of Assigned Spreadsheet Columns';
    str +=            '</button>';
    str +=         '</td>';
    str +=         '<td class="ewz_waitmessage"></td>';
    str +=      '</tr>';
    str +=   '</table>';
    return str;
}



/* return the html for a new blank restriction */
function new_restriction_str(lnum, button) {

    var restrs = jQuery(button).parent().find('button[id^="x' + jQuery(button).attr("id") + '"]'),
        rnum = 0,
        txt, rid, jcurr_form,
        msgnm = '';

    if (restrs.length) {
        rnum = restrs.last().attr("id").replace(/^.*R/, '').replace(/_$/, '');
        rnum = parseInt(rnum, 10 ) + 1;
    }
    txt = '<div id="restr_title_f' + lnum + '_r' + rnum + '_" class="ewz_subpost ewz_box closed">';
    txt += '   <h3 id="new_restr_f' + lnum + '_r' + rnum + '_" class="ewz_hndle"  title="Click to toggle" onClick="toggle_ewz_box(this)">';
    txt += '       <span class="ewz_indicator"></span>--- New Restriction ---</h3>';
    txt += '   <div class="inside">';

    rid = jQuery(button).attr("id") + "R" + rnum + '_';
    txt += '       <div class="ewz_add_restr" id="' + rid + '">';
    txt += '          <table class="ewz_field"><tr><td colspan="2">Forbidden combination:</td></tr>';
    jcurr_form = jQuery(button).closest('form[id^="cfg_form_f"]');

    jcurr_form.find('select[id$="_field_type_"]').each( function() {
        var inside, field_id, nmstr, fieldname, isreq, fieldtype, option_list;

        inside = jQuery(this).closest('div[class="inside"]');
        field_id = inside.find('input[name^="fields"]').filter(":hidden").val();
        if( inside.find( 'input[id$="_field_ident_"]').val() != 'followupQ' ){
            nmstr = 'restrictions[' + rnum + '][' + field_id + ']';
            fieldname = inside.find('input[id$="field_header_"]').val();
            isreq = inside.find('input[id$="_required_"]').filter(":checked").length;
            fieldtype = jQuery("option:selected", this).val();

            txt += '      <tr><td class="ewz_leftpad">' + ewz_esc(fieldname) + ":</td>";
            txt += '          <td>';

            // do this in javascript instead of getting from db so it will reflect current changes
            if ('opt' === fieldtype) {
                option_list = '';
                inside.find('table[id^="data_fields_"]').find('tr[id$="_row_"]').each( function() {
                    var label, val;
                    label = jQuery(this).find('input[id$="_label_"]').val();
                    val = jQuery(this).find('input[id$="_value_"]').val();

                    option_list += '         <option value="' + val + '">' + label + '</option>';
                });
            }

            txt += field_values(fieldtype, isreq, nmstr, 'f' + lnum + '_restrictions_' + rnum + '__' + field_id + '_', option_list);
        }
    });

    txt += '                 </td>';
    txt += '             </tr>';
    txt += '             <tr><td ><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'rmsg\')">&nbsp;Message: ';
    msgnm = 'restrictions[' + rnum + '][msg]';
    txt += '                 </td><td><input type="text" maxlength="200" name="' + msgnm + '" id="f' + lnum + '_restrictions_' + rnum + '__msg_">';
    txt += '                 </td>';
    txt += '             </tr>';
    txt += '           </table>';
    txt += '       </div>';
    txt += '       <p style="text-align:right">';
    txt += '          <button type="button" class="button-secondary" id="x' + rid + '" onClick="delete_restr(this)">Remove Restriction</button>';
    txt += '       </p>';
    txt += '    </div>';
    txt += '</div>';

    return txt;
}

function field_values(fieldtype, isreq, select_name, select_id, options) {
   var txt = '';
   switch (fieldtype) {
      case 'str':
      case 'img':
         if (isreq === 0) {
            txt += '      <select name="' + select_name + '" id="' + select_id + '">';
            txt += '         <option value="~*~">Any </option>';
            txt += '         <option value="~-~">Blank </option>';
            txt += '         <option value="~+~">Not Blank </option>';
            txt += '      </select>';
         } else {
            txt += ' --- <input type="hidden" name="' + select_name + '" id="' + select_id + '" value="~*~">';
         }
         break;
      case 'opt':
         txt += '          <select name="' + select_name + '" id="' + select_id + '">';
         txt += '             <option value="~*~">Any </option>';
         if (isreq === 0) {
            txt += '         <option value="~-~">Blank </option>';
            txt += '         <option value="~+~">Not Blank </option>';
         }
         txt += options;
         txt += '          </select>';
         break;
       case 'rad':
            txt += '      <select name="' + select_name + '" id="' + select_id + '">';
            txt += '         <option value="~*~">Any </option>';
            txt += '         <option value="~+~">Checked </option>';
            txt += '         <option value="~-~">Not Checked </option>';
            txt += '      </select>';
         break;
       case 'chk':
            txt += '      <select name="' + select_name + '" id="' + select_id + '">';
            txt += '         <option value="~*~">Any </option>';
            txt += '         <option value="~+~">Checked </option>';
            txt += '         <option value="~-~">Not Checked </option>';
            txt += '      </select>';
         break;
       case 'lab':
      case undefined:
         break;
   }
   return txt;
}



/* return the html for a "field" div */
function field_str(lnum, i, fObj) {
    var fld, f_ident, str;

    fld = 'fields[' + i + ']';
    f_ident = "f" + lnum + '_fields' + i + '_';
    str = '<div id="' + f_ident + 'field_mbox_" class="ewz_box closed">';

    str += '  <h3 class="ewz_hndle" onClick="toggle_ewz_box(this)" title="Click to toggle" id="field_title_' + f_ident + '">';
    str += '      <span class="ewz_indicator"></span>' + fObj.field_header + '</h3>';
    str += '  <div class="inside">';
    str += '     <input type="hidden" name="' + fld + '[field_id]' + '" value="' + fObj.field_id + '">';
    str += '     <input type="hidden" name="forder[]" value="forder_f' + lnum + '_c' + i + '_">';
    str += '     <table  class="ewz_field">';
    str += '       <tr><td><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'fhead\')">&nbsp;Column Header For Web Page: </td>';
    str += '           <td>' + textinput_str(f_ident + 'field_header_', fld + '[field_header]', 50, fObj.field_header, 'onChange="update_title(this)"') + '</td>';
    str += '           <td rowspan="5"  id="special_' + f_ident + '" > ' + type_data_field_str(lnum, f_ident, fld, fObj.field_type, fObj.fdata) + '</td>';
    str += '       </tr>';
    str += '       <tr><td><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'ftype\')">&nbsp;Data Type: </td>';
    str += '           <td class="ewz_shaded">' + type_opt_str(lnum, f_ident, fld, fObj.field_type) + '</td>';
    str += '       </tr>';
    str += '       <tr><td><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'sshead\')">&nbsp;Field Identifier: </td>';
    str += '           <td>' + textinput_str(f_ident + 'field_ident_', fld + '[field_ident]', 15, fObj.field_ident) + '</td>';
    str += '       </tr>';
    str += '       <tr><td><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'sscol\')">&nbsp;Spreadsheet Column: </td>';
    str += '           <td>' + colinput_str(f_ident + 'ss_column_', fld + '[ss_column]', fObj.ss_column, 'ssc' + lnum) + '</td>';
    str += '       </tr>';
    var rq = fObj.required;
    if( fObj.field_type == 'rad' || fObj.field_type == 'lab' ){
       rq = 'disabled';
    }
    str += '       <tr><td><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'req\')">&nbsp;Required: </td>';
    str += '           <td>' + checkboxinput_str(f_ident + 'required_', fld + '[required]', fObj.required, rq) + '</td>';
    str += '       </tr>';

    str += '       <tr><td><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'append\')">&nbsp;Append to Previous Column in Webform: </td>';
    str += '           <td>' + checkboxinput_str(f_ident + 'append_', fld + '[append]', fObj.append ) + '</td>';
    str += '       </tr>';

    str += '       <tr><td><img  class="ewz_ihelp" src="' + ewzG.helpIcon + '" onClick="ewz_help(\'all_items\')">&nbsp;Applies To All Items: </td>';
    str += '           <td>' + checkboxinput_str(f_ident + 'all_items_', fld + '[all_items]', fObj.all_items ) + '</td>';
    str += '       </tr>';

    str += '     </table>';
    str += '     <div style="text-align:right; padding:10px;"> ';
    str += '        <button type="button" class="button-secondary" id="del_' + f_ident + '" onClick="delete_field(this)">Delete Field</button>';
    str += '     </div>';
    str += '  </div>';
    str += '</div>';
    return str;
}


/************************ Functions That Actually Do Something  ****************************************/

function toggle_layout_box( handle ){
    var lid = get_layout_ident( handle );
    jQuery(handle).closest('.ewz_box').children(".inside").toggle();
    if( !layouts_done[lid] ){
        var lnum = js_find_by_key(ewzG.layouts, 'layout_id', lid);
        setup_layout(lid, ewzG.layouts[lnum] );
        layouts_done[lid] = true;

        // note when changes made -- do it here, after setup_layout has made any required changes to selection boxes
        jQuery('#ewz_layouts').find(':input:not(:button)').on( "change", function(){
            g_changesMade = true;
        });
    }
    jQuery(handle).toggleClass('ewz_hndle');
    jQuery(handle).children('span.ewz_indicator').first().toggleClass('ewz_open');
}



function save_layout_order(){
    var l_nonce = jQuery('#ewznonce').val();
    var data = {
        action: 'ewz_save_layout_order',
        ewznonce:   l_nonce,
        ewzmode:  'lset',
        lorder: new Object()
    };

    if( jQuery('input[id^="layout_id"][value=""]').length > 0 ){
        ewz_alert('L002',"Please save your unsaved Layout before trying to rearrange them", ++popupN);
        return;
    }

    jQuery('input[id^="layout_id"]').each(function(index){
        data['lorder'][jQuery(this).val()] = index;
    });
    data['action'] = 'ewz_save_layout_order';
    data['ewznonce'] = l_nonce;
    // ajaxurl variable is available in admin
    var jqxhr = jQuery.post( ajaxurl,
                             data,
                             function (response) {
                                 jQuery("#temp_del").remove();
                                 set_ewzG_layout_order(data['lorder']);
                                 ewz_alert('L003', response.replace(/$/mg, '<br>'), ++popupN);
                             }
                           ).fail( function( jqXHr, textStatus, errorThrown ){ewz_alert( 'L035', 'Sorry, there was a server error: ' + jqXHr.responseText, ++popupN );} );
}

function set_ewzG_layout_order(lorder){
   for( var layout_id in lorder ){
       if ( lorder.hasOwnProperty(layout_id) ){
           var ind = ewzG.layouts.findIndex( function(l){ return l.layout_id == layout_id; } );
           ewzG.layouts[ind].layout_order = lorder[layout_id];
        }
   }
}

/* disable editing of fields appearing in restrictions */
function disable_restricted_fields(lnum) {
    jQuery("#restricts_f" + lnum + '_').find('option:selected').each(function() {
        if (jQuery(this).val() !== '~*~') {
            var field_id, optval, jTxt;

            field_id = jQuery(this).parent().attr('id').replace(/^.*__/, '').replace('_', '');
            disable_and_flag(jQuery('#f' + lnum + '_fields' + field_id + '_field_type_'));
            disable_and_flag(jQuery('#del_f' + lnum + '_fields' + field_id + '_'));
            optval = jQuery(this).val();
            switch (optval) {
                case "~+~":
                case "~-~":
                    disable_and_flag(jQuery('#f' + lnum + '_fields' + field_id + '_required_'));
                    break;

                default:
                    jTxt = jQuery("input[id^='f" + lnum + "_fields" + field_id + "_fdata_'][id$='_value_'][value='" + optval + "']");
                    disable_and_flag(jTxt.parent().siblings().last().find("button"));
                    disable_and_flag(jTxt);
                    break;
            }
        }
    });
}

/* disable "required" checkbox if the field type is label or radio  */
function disable_required_for_radio_lab(lnum){
    var jfield = jQuery("#cfg_form_f" + lnum + "_").find('input[id$="_field_ident_"]').filter(function() {
        return (this.value != 'followupQ' );}).closest('table[class="ewz_field"]');

    var type = jfield.find( 'select[id$="_field_type_"]').val();
    if( type == 'lab' || type == 'rad' ){
        jfield.find('input[id$="_required_"]').prop("disabled", true);
    }
}

function enable_restricted_fields(lnum) {
    var content;
    jQuery("#cfg_form_f" + lnum + "_").find(".ewz_disabled").each(function() {
        jQuery(this).find('input,button').prop("disabled", false);
        content = jQuery(this).html();
        jQuery(this).replaceWith(content);
    });
}


/* Set up some onChange functions for a layout */
function setup_layout(for_lid,  layout ) {
    if( undefined !== layout ){
        set_restr_selections(for_lid, layout );
    }

    var jLayout = jQuery('#ewz_admin_layouts_f' + for_lid + '_');

    // set postbox header from title
    jQuery('#f' + for_lid + '_layout_name_').on("keyup", function() {
        update_layout_name(this);
    });
    jQuery('#f' + for_lid + '_layout_name_').on("change",function() {
        update_layout_name(this);
    });

    // make sure individual option max nums are less than overall max
    jQuery('#f' + for_lid + '_max_num_items_').on("change", function() {
        disable_max_vals(jLayout);
    });
    jLayout.find('select[id$="_maxnum_"]').on("change", function() {
        disable_max_vals(jLayout);
    });
    disable_ss_options('.ssc' + for_lid);
    jQuery("#f" + for_lid + "_max_num_items_").trigger("change");

    // make the field postboxes sortable
    // ( "clone" option needed for firefox to stop opening on drag-drop )
    jQuery('#ewz_sortable_f' + for_lid + '_').sortable({
        containment: 'parent',
        tolerance: "pointer",
        handle:  ".ewz_hndle",
        items: "> div",
        distance: 5,
        helper: "clone"
    });

    // disable fields appearing in restrictions
    disable_restricted_fields(for_lid);

    // disable required fields for checkboxes and radio buttons
    disable_required_for_radio_lab(for_lid);

    // "formatted text" only available for single-line text inputs
    initcaps_for_1line('ewz_admin_layouts_f' + for_lid + '_');
}

/* For the maxnum dropdown box in an option field OR A CHECKBOX FIELD, disable any maxnum >= the overall max num items */
/*    ( unless the field has identifier 'followupQ' )
/* Also disable numbers less than this in the max_num_items drop-down */
function disable_max_vals(jLayout) {
    var jMaxNum, opt_max_limit, mni_min;
    jMaxNum = jLayout.find('select[name="max_num_items"]');
    opt_max_limit = jMaxNum.val();
    mni_min = 0;

    jLayout.find("select[id$='_maxnum_'],select[id$='_chkmax_']").each(function() {
        var jselect, optval;
        jselect = jQuery(this);
        if( !(jselect.closest('table[class="ewz_field"]').find('input[id$="_field_ident_"]').val() == 'followupQ') ){
            optval = jselect.val();
            if (optval > mni_min) {
                mni_min = optval;
            }
            jselect.find('option').prop("disabled", false);
            jselect.find('option').filter(function(){
                return  parseInt(jQuery(this).val(), 10) > opt_max_limit; } ).prop("disabled", true);
        }
    });
    jMaxNum.find('option').prop("disabled", false);
    jMaxNum.find('option').filter(function(){
        return  parseInt(jQuery(this).val(), 10) < mni_min; }).prop("disabled", true);
}

/* Restrictions are initially created blank. This fills in the details */
function set_restr_selections(lnum, layout) {
    var restrict, field, field_id, jmsg, junescaped, jpbox;
    if( undefined !== layout.restrictions  ){
        for (restrict in layout.restrictions) {
            if (layout.restrictions.hasOwnProperty(restrict)) {
                for (field in layout.fields) {
                    if (layout.fields.hasOwnProperty(field)) {
                        field_id = layout.fields[field].field_id;
                        var optval = layout.restrictions[restrict][field_id];
                        jQuery('#f' + lnum + '_restrictions_' + restrict + '__' + field_id + '_ > option[value="' + optval + '"]').attr('selected', 'selected');
                    }
                }
                jmsg = jQuery('#f' + lnum + '_restrictions_' + restrict + '__msg_');
                junescaped = jQuery(document.createElement('div')).html(layout.restrictions[restrict].msg);
                jmsg.val(junescaped.text());
                jpbox = jmsg.closest('div[id^="restr_title"]');
                jpbox.find('h3[id^="new_restr"]').html('<span class="ewz_indicator"></span>' + layout.restrictions[restrict].msg);
            }
        }
    }
}

function add_restriction(button) {
    var jRestrictDiv = jQuery(button).parent().find('div[id^="restricts_f"]'),
        lnum = get_layout_ident(button);

    jRestrictDiv.append(new_restriction_str(lnum, button));
    jRestrictDiv.find(':input:not(:button)').on("change",function(){
        if(!g_changesMade){g_changesMade=true;}
    });
}

function delete_restr(button) {
    var lnum = get_layout_ident(button);
    // delete the restriction
    jQuery(button).closest('.ewz_box').remove();
    enable_restricted_fields(lnum);
    // there may be other restrictions, enable clears everything
    disable_restricted_fields(lnum);
}

/* Called on change of layout name, to change the postbox title */
function update_layout_name(textfield) {
    var jtext, jlayout;

    jtext = jQuery(textfield);
    jlayout = jtext.closest(jQuery('div[id^="ewz_postbox-layout_f"]'));
    jlayout.find('h3[id^="tpg_header_f"]').text(jtext.val());
    jlayout.find('button[id^="lsub_f"] i').text(jtext.val());
    jlayout.find('button[id^="ldel_f"] i').text(jtext.val());
}


/* Adds a new field to the current layout, of type defined by field_type */
function add_field(add_field_btn, field_type) {
    var form, cnum, newid, lnum, fdata, data;
    ++newFnum;

    form = jQuery(add_field_btn).closest('form[id^="cfg_form"]');
    newid = form.attr("id").replace('cfg_form_', '') + 'fieldsX' + newFnum + '_';
    lnum = form.attr("id").replace('cfg_form_f', '').replace('_', '');
    fdata = {};

    data = {};
    fdata = get_empty_field_str( field_type );

    data.fdata = fdata;
    data.field_ident = '';
    data.field_header = '';
    data.field_id = '';
    data.field_type = field_type;
    data.required = 0;
    data.ss_column = '-1';
    form.find('div[id^="ewz_sortable"]').append(jQuery(field_str(lnum, 'X' + newFnum, data)));
    jQuery('h3[id="field_title_' + newid + '"]').html("--- New Field ---");

    var jNewBox = jQuery('#' + newid + 'field_mbox_');
    // fire a change event on the spreadsheet column select boxes to disable used columns
    jNewBox.find('select[onchange^="disable_ss_options"]').trigger("change");

    var jLayout = jQuery(add_field_btn).closest('div[id^=ewz_admin_layouts_f]');
    jNewBox.find('select[id$="_maxnum_"],select[id$="_chkmax_"]').on("change",function() {
        disable_max_vals(jLayout);
    });
    disable_max_vals(jLayout);
    if( field_type == 'str' ){
        initcaps_for_1line('ewz_admin_layouts_f' + lnum + '_');
    }
    jNewBox.find(':input:not(:button)').on("change", function(){
        if(!g_changesMade){g_changesMade=true;}
    });
}

/* Creates a new layout as a copy of the one selected */
function add_layout_copy() {
    var fromid, fromnum, layouts, to_num, fromstringid, tostringid, jQnew, sscstr, newhtml;
    ++nNew;

    fromid = jQuery('#ewz_addlayout').val();
    fromnum = jQuery('#ewz_addlayout').prop("selectedIndex");
    layouts = jQuery('div[id^="ewz_admin_layouts_f"]');
    to_num = 'X' + nNew;

    fromstringid = 'ewz_admin_layouts_f' + fromid + '_';
    tostringid = 'ewz_admin_layouts_f' + to_num + '_';
    jQnew = jQuery('#' + fromstringid).clone();
    sscstr = new RegExp('ssc' + fromid, "g");
    newhtml = jQnew.html().replace(sscstr, 'ssc' + to_num);

    jQnew.html(newhtml);
    jQnew.attr("id", tostringid);
    jQnew.find('[id]').each(function() {
        jQuery(this).attr("id", jQuery(this).attr("id").replace('f' + fromid + '_', 'f' + to_num + '_'));
    });

    // remove restrictions  -- will be copied after save, on the server
    jQnew.find('#restricts_f' + to_num + '_').empty();

    jQnew.find('input[name="layout_id"]').attr("value", "");
    jQnew.find('input[name$="[field_id]"]').attr("value", "");
    jQnew.find('select:disabled,input:disabled,button:disabled').prop("disabled", false);

    jQnew.find('input[name="forder[]"]').each(function() {
        jQuery(this).attr("value", jQuery(this).attr("value").replace('_f' + fromid + '_', '_f' + to_num + '_'));
    });
    jQnew.find('div[class="ewz_warn"]').html('');
    // make sure the new layout_name is within the limit of 60 chars
    var oldname = jQuery('#' + fromstringid).find('input[id$="layout_name_"]').val();
    jQnew.find('[id$="layout_name_"]').first().attr("value", "--- Copy of " + oldname.substr(0, 45) + ' --');

    jQnew.insertBefore(layouts.first());

    do_submit( jQnew.find('form[id^="cfg_form"]'), to_num, fromid );
}


/* Deletes the layout on the current page, does not change what is stored on the server */
function delete_js_layout(id, thediv, lname) {
    var re = new RegExp('<option value="' + id + '">' + lname + '<\\/option>');
    thediv.remove();
    // NB: order of layouts_options is that originally loaded, may not be current order
    var old = jQuery('#ewz_addlayout').html();

    jQuery('#ewz_addlayout').html( old.replace(re, ''));
}

/* Deletes the layout from ewzG */
function delete_layout_ewzG(id, lname){
    var re = new RegExp('<option value="' + id + '">' + lname + '<\\/option>');
    var index = js_find_by_key(ewzG.layouts, 'layout_id', id);
    // NB: order of layouts_options is that originally loaded, may not be current order
    ewzG.layouts_options = ewzG.layouts_options.replace(re, '');
    ewzG.layouts.splice(index, 1);
}


/* Just deletes the field on the current page, does not change what is stored on the server */
function delete_js_field(layout_id, field_id, jfield_div) {
    jfield_div.find('select[id$="_maxnum_"],select[id$="_chkmax_"]').prop("selectedIndex", 0);
    jfield_div.find('select[id$="_maxnum_"],select[id$="_chkmax_"]').trigger("change");
    jfield_div.find('select[onchange^="disable_ss_options"]').prop("selectedIndex", 0);
    jfield_div.find('select[onchange^="disable_ss_options"]').trigger("change");
    jfield_div.remove();
    jQuery('select[id*="restrictions"][id$="__' + field_id + '_"]').remove();
}

/* delete the field from ewzG */
function delete_field_ewzG(layout_id, field_id){
    var index = js_find_by_key(ewzG.layouts, 'layout_id', layout_id);
    delete ewzG.layouts[index].fields[field_id];
}


/* First checks for attached webforms or items */
/* Actually deletes the layout on the server via ajax. If successful, calls delete_js_layout to delete it on the current page. */
function delete_layout(button, nwebforms, nitems) {
    var jbutton, lname, confirmstring, thediv, id, del_nonce, jqxhr;

    jbutton = jQuery(button);
    lname = jbutton.closest('div[id^="ewz_postbox-layout_f"]').find('h3[id^="tpg_header_f"]').text().trim();
    lname = lname.replace(/To make it permanent.*$/, '');

    thediv = jbutton.closest('div[id^="ewz_admin_layouts_f"]');
    id = thediv.find('input[name="layout_id"]').first().attr("value");

    if (jQuery('div[id^="ewz_postbox-layout_f"]').length < 2) {
        ewz_alert('L006',ewzG.errmsg.onlylayout, ++popupN);
        return;
    }
    if (nitems > 0) {
        ewz_alert('L007',ewzG.errmsg.deletehasitems, ++popupN);
        return;
    }
    if (id === undefined || '' == id ) {
        delete_js_layout(id, thediv, lname);
    } else {

        confirmstring = '';
        if (nwebforms > 0) {
            confirmstring = ewzG.errmsg.deletehaswebforms + "<br><br>";
        }
        confirmstring = confirmstring + ewzG.errmsg.deleteconfirm + "'" + lname + "'?";

        ewz_confirm( confirmstring,
            function(){
                del_nonce = jQuery('#ewznonce').val();
                jbutton.after('<span id="temp_load" style="text-align:left"> &nbsp; <img  src="' + ewzG.load_gif + '"/></span>');
                jqxhr = jQuery.post(ajaxurl,
                        {
                            action: 'ewz_del_layout',
                            layout_id: id,
                            ewznonce: del_nonce
                        },
                function(response) {
                    jQuery("#temp_load").remove();
                    if ('1' == response) {
                        delete_js_layout(id, thediv, lname);
                        delete_layout_ewzG(id, lname);
                    } else {
                        ewz_alert('L008',response.replace(/$/mg, '<br>'), ++popupN);
                    }
                }
                ).fail( function( jqXHr, textStatus, errorThrown ){ewz_alert( 'L036', 'Sorry, there was a server error: ' + jqXHr.responseText, ++popupN );} );
            },
            null,
            ++popupN
       );
    }
}


/* Actually deletes the field on the server via ajax. If successful, deletes it on the current page. */
function delete_field(del_field_btn) {
    var jbutton, fname, jfield_div, jform_div, field_id, layout_id, del_nonce, jqxhr;

    jbutton = jQuery(del_field_btn);
    jfield_div = jbutton.closest('div[id$="field_mbox_"]');
    field_id = jfield_div.find('input[name^="fields"]').filter(":hidden").val();
    if (field_id === undefined || '' == field_id ) {
        delete_js_field(layout_id, field_id, jfield_div);
    } else {
        fname = jbutton.closest('div[id$="field_mbox_"]').find('h3[id^="field_title"]').text();
        ewz_confirm("Really delete the '" + fname + "' field?",
                    function(){
                       jform_div = jbutton.closest('form[id^="cfg_form_f"]');
                       layout_id = jform_div.find('input[name="layout_id"]').first().attr("value");

                        del_nonce = jQuery('#ewznonce').val();
                       jbutton.after('<span id="temp_load" style="text-align:left"> &nbsp; <img  src="' + ewzG.load_gif + '"/></span>');
                       jqxhr = jQuery.post(ajaxurl,
                            {
                                action: 'ewz_del_field',
                                field_id: field_id,
                                layout_id: layout_id,
                                ewznonce: del_nonce
                            },
                            function(response) {
                               jQuery("#temp_load").remove();
                               if ('1' == response) {
                                  delete_js_field(layout_id, field_id, jfield_div);
                                  delete_field_ewzG(layout_id, field_id);
                               } else {
                                   ewz_alert('L009',response.replace(/$/mg, '<br>'), ++popupN);
                               }
                            }
                       ).fail( function( jqXHr, textStatus, errorThrown ){ewz_alert( 'L037', 'Sorry, there was a server error: ' + jqXHr.responseText, ++popupN );} );
                   },
                   null,
                   ++popupN
        );
    }
}

function ewz_esc(instring) {
    return instring.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}


var g_errors_done;
/***********************************************************************
 * Called on submit.
 * Disables the submit buttons, then checks for errors.
 * If it finds any, pops up a warning and re-enables the submit button
 * If it doesn't, submits via ajax.
 * Always returns false unless there is an exception.
 * Changes globals g_doingSubmit, g_errors_done, g_changesMade
 **********************************************************************/
function ewz_check_layout_input(form, do_check) {
    var ok, jform, lnum, except1, warning;

    // stop the "do you really want to leave" message that would otherwise show when the "save changes" button is clicked
    g_doingSubmit = true;

    g_errors_done = [];
    ok = true;
    warning = '';

    jform = jQuery(form);
    lnum = jform.attr("id").replace('cfg_form_f', '').replace('_', '');

    // disable the submit buttons until this function is finished
    jform.find('button[id^="lsub_f"]').prop("disabled", true);

    try {
        if(do_check) {
            // remove leading and trailing spaces from all inputs
            // NB: need index arg so value is correctly assigned
            jform.find('input').val(function(index, value) {
                return value.replace(/ +$/, '').replace(/^ +/, '');
            });
            // do_all_checks pops up notices asynchronously
            ok = ok && do_all_checks(jform, lnum);
            if( ok ){
                // get_all_confirms does not pop up confirmation dialogs, just returns a message
                warning = get_all_confirms(jform);
                ok = ok && ( warning.length == 0 );
            }
            if( warning.length > 0 ){
                // now show the asynchronous confirmation dialog, and submit if confirmed
                // the do_submit call may be executed after ewz_check_layout_input has finished
                ewz_confirm( warning,
                             function(){
                                 do_submit(jform, lnum);
                             },
                             null,
                             ++popupN );

            } else if( ok ){
                do_submit(jform, lnum);
            }
        } else {
            do_submit(jform, lnum);
        }
    } catch (except1) {
        ewz_alert('L031',"Sorry, there was an unexpected error: " + except1.message, ++popupN);
    }
    jform.find('button[id^="lsub_f"]').prop("disabled", false );
    g_doingSubmit = false;
    return false;   // submit is done via ajax, dont do it again
}

function do_submit(jform, lnum, copy_restr_from ){
    copy_restr_from = ( typeof copy_restr_from !== 'undefined') ? copy_restr_from : -1;
    jform.find('td[class="ewz_waitmessage"]').html('Processing, please wait ... <img alt="Please Wait" src="' + ewzG.load_gif + '"/>');
    // enable all the disabled stuff so right data gets sent
    jform.find('select:disabled,input:disabled,button:disabled').prop("disabled", false);
    jform.find('input[id$="optrow_"]').prop("disabled", true);  // we DO want this disabled

    jform.append('<input type="hidden" name="action" value="ewz_save_layout" />');
    jform.append('<input type="hidden" name="ewznonce" value="' + jQuery('#ewznonce').val() + '">');
    if(copy_restr_from >= 0 ){
        jform.append('<input type="hidden" name="copy_restr_from", value="' + copy_restr_from + '">');
    }

    // ajaxurl variable is available in admin
    jQuery.post(
        ajaxurl,
        jform.serialize(),
        function(response) {
            if (response) {
                if( response.success ){
                    var oldname = '';
                    var lid = response.data.layout_id;
                    var newL = '<option value="' + lid + '">' + response.data.layout_name + '</option>';
                    var index = js_find_by_key(ewzG.layouts, 'layout_id', lid);
                    if( index >= 0 ){
                        oldname = ewzG.layouts[index].layout_name;
                        if( oldname != response.data.layout_name ){
                            jQuery('#ewz_addlayout > option[value="' + lid + '"]').replaceWith(newL);
                        }
                        ewzG.layouts[index] = response.data;
                    } else {
                        ewzG.layouts.push(response.data);
                        jQuery('#ewz_addlayout').append(newL);
                        // NB: order of layouts_options is that originally loaded, may not be current order
                        ewzG.layouts_options += newL;
                    }

                    jQuery('#ewz_admin_layouts_f' + lnum + '_').replaceWith( layout_str( lid, response.data ) );
                    for (var restr = 0; restr < response.data.restrictions.length; ++restr) {
                        jQuery('#restricts_f' + lid  + '_').append(new_restriction_str(lid, jQuery('#add_restr_f' + lid + '_').get()));
                    }
                    setup_layout(lid, response.data);
                    var loc = jQuery('#ewz_admin_layouts_f' + lid + '_').position().top - 50;
                    jQuery('html, body').scrollTop( loc );
                    jform.find('td[class="ewz_waitmessage"]').html('');
                    ewz_alert('L046', 'Saved Layout "' + response.data.layout_name + '"', ++popupN );

                } else {
                    ewz_alert('L045', response.data, ++popupN );
                    disable_ss_options('.ssc' + lnum);
                    disable_restricted_fields(lnum);
                    jform.find('td[class="ewz_waitmessage"]').html('');
                }
                g_changesMade = false;
            } else {
                disable_ss_options('.ssc' + lnum);
                disable_restricted_fields(lnum);
                ewz_alert('L030','EWZ: Sorry, there was an unknown error while saving the layout. If this happens again, please contact your webmaster.', ++popupN);
                jform.find('td[class="ewz_waitmessage"]').html('');
            }
        },
        'json'
    ).fail( function( jqXHr, textStatus, errorThrown ){
        jform.find('td[class="ewz_waitmessage"]').html('');
        ewz_alert( 'L038', 'Sorry, there was a server error: ' + jqXHr.responseText, ++popupN );
    } ) ;

}


function do_all_checks(jform, lnum){
    var  maxnumitems, maxs, except1, except2;
    var ok = true;
    // no layout name
    if (!jform.find('input[id$="_layout_name_"]').val()) {
        err_alert('L010', lnum, ewzG.errmsg.layoutname);
        ok = false;
    }
    // no max num items
    maxnumitems = jform.find('select[id$="_max_num_items_"]').val();
    if (!maxnumitems) {
        err_alert('L011', lnum, ewzG.errmsg.maxnumitems);
        ok = false;
    }
    // no fields
    if (!jform.find('div[id^="field_mbox_"]')) {
        err_alert( 'L012',lnum, ewzG.errmsg.nofields);
        ok = false;
    }
    /* cant return from function from inside filter, so use 'ok' flag */
    // missing column header
    jform.find('input[id$="_field_header_"]').filter(function() {
        return  ('' == jQuery(this).val().replace(/^\s+|\s+$/g, ''));
    }).each(function() {
        err_alert('L013', lnum, ewzG.errmsg.colhead);
        ok = false;
    });
    // missing identifier
    jform.find('input[id$="field_ident_"]').filter(function() {
        return !jQuery(this).val().replace(/^\s+|\s+$/g, '').match(/^[a-z][a-z0-9_\-]+$/i);
    }).each(function() {
        err_alert('L014', lnum, ewzG.errmsg.ident);
        ok = false;
    });
    // followup cannot be image type
    jform.find('input[id$="field_ident_"]').filter(function() {
        return( 'followupQ' == jQuery(this).val() );
    }).filter(function() {
        return ( 'img' == jQuery(this).closest('tbody').find('select[id$="_field_type_"]').val());
    }).each(function() {
        err_alert( 'L015',lnum,  ewzG.errmsg.followimg);
        ok = false;
    });
    // invalid max_img_w
    jform.find('input[id$="_max_img_w_"]').each(function() {
        if (!jQuery(this).val().match(/^[1-9][0-9]*$/)) {
            err_alert('L016', lnum, ewzG.errmsg.maximgw);
            ok = false;
        }
    });
    // invalid max_img_h
    jform.find('input[id$="_max_img_h_"]').each(function() {
        if (!jQuery(this).val().match(/^[1-9][0-9]*$/)) {
            err_alert( 'L017',lnum, ewzG.errmsg.maximgh);
            ok = false;
        }
    });
    // invalid min_longest_dim
    jform.find('input[id$="min_longest_dim_"]').each(function() {
        if( jQuery(this).val().match(/^ *$/)) {
            jQuery(this).val(0);
        } else if (!jQuery(this).val().match(/^[0-9][0-9]*$/)) {
            err_alert( 'L018',lnum, ewzG.errmsg.minlongestdim);
            ok = false;
        }
    });
    // invalid text, checkbox or radio label
    jform.find('input[id$="chklabel_"]').each(function() {
        if( jQuery(this).val().match(/[^A-Za-z0-9_\.\-\ ]/)) {
            err_alert( 'L033',lnum, ewzG.errmsg.label);
            ok = false;
        }
    });
    jform.find('input[id$="radlabel_"]').each(function() {
        if( jQuery(this).val().match(/[^A-Za-z0-9_\.\-\ ]/)) {
            err_alert( 'L034',lnum, ewzG.errmsg.label);
            ok = false;
        }
    });
    jform.find('input[id$="textlabel_"]').each(function() {
        if( jQuery(this).val().match(/[^A-Za-z0-9_\.\-\ ]/)) {
            err_alert( 'L039',lnum, ewzG.errmsg.label);
            ok = false;
        }
    });
    // missing option label or value
    jform.find('input[id$="_label_"]').each(function() {
        var lab = jQuery(this).val();
        if (!lab) {
            err_alert( 'L022',lnum, ewzG.errmsg.optlabel);
            ok = false;
        }
        if (lab.match(/[^A-Za-z0-9_\.\- ]/)) {
            err_alert( 'L023',lnum, ewzG.errmsg.option);
            ok = false;
        }
    });
    // option list must contain a valid option
    jform.find('select[id$="_field_type_"]').each(function(){
        if( jQuery(this).val() === 'opt'){
            var jfield_table = jQuery(this).closest('table[class="ewz_field"]');
            var header = jfield_table.find('input[id$="_field_header_"]').val();
            if(jfield_table.find('table[id^="data_fields_"]').find('tr[id$="_row_"]').length < 1 ){
                err_alert( 'L024',lnum,  header + ': ' +  ewzG.errmsg.optioncount );
                ok = false;
            }
        }
    });
    // option must have a valid value
    jform.find('input[id$="_value_"]').each(function() {
        var oval = jQuery(this).val();
        if (!oval) {
            err_alert( 'L025',lnum, ewzG.errmsg.optvalue);
            ok = false;
        }
        if (oval.match(/[^A-Za-z0-9_\.\-]/)) {
            err_alert( 'L026',lnum, ewzG.errmsg.option);
            ok = false;
        }
    });
    // restriction must have a message
    jform.find('input[id$="__msg_"]').each(function() {
        if (!jQuery(this).val()) {
            err_alert( 'L027',lnum, ewzG.errmsg.restrmsg);
            ok = false;
        }
    });
    // text input must have maxchars
    jform.find('select[id$="_maxstringchars_"]').each(function() {
        if (!jQuery(this).val().replace(/^\s+|\s+$/g, '')) {
            err_alert( 'L028',lnum, ewzG.errmsg.maxnumchar);
            ok = false;
        }
    });
    // img must have set of allowed types
    jform.find('select[id$="_allowed_image_types_"]').each(function() {
        if (!jQuery(this).val()) {
            err_alert( 'L029',lnum, ewzG.errmsg.imgtypes);
            ok = false;
        }
    });
    // invalid or missing max_img_size, maxUploadMb
    jform.find('input[id$="_max_img_size_"]').each(function() {
        jQuery(this).val(jQuery(this).val().replace(/[Mm]$/, ''));
        maxs = jQuery(this).val();
        if (!maxs) {
            err_alert('L019', lnum, ewzG.errmsg.nomaximgsz);
            ok = false;
        } else {
            if (!maxs.match(/^[0-9]?[0-9]?\.?[0-9]+$/)) {
                err_alert( 'L020',lnum, ewzG.errmsg.maximgsz);
                ok = false;
            }
            if (parseFloat(maxs) > parseFloat(ewzG.maxUploadMb)) {
                err_alert( 'L021',lnum, ewzG.errmsg.sysmaxsz);
                ok = false;
            }
        }
    });
     // required checkbox cannot have chkmax
   jform.find('select[id$="_field_type_"]').each(function(){
        if( jQuery(this).val() === 'chk'){
            var jfield_table = jQuery(this).closest('table[class="ewz_field"]');
            if( jfield_table.find('[id$="_required_"]:checked').length > 0 &&
                jfield_table.find('[id$="_fdata_chkmax_"]').val() > 0
              ){
            err_alert( 'L042',lnum, ewzG.errmsg.chkboxchkmax);
            ok = false;
            };
        }
    });

    // Text for blank selection must be valid
    jform.find('input[id$="[selecttext]"]').each(function(){
        if( jQuery(this).val().match(/[^A-Za-z0-9_\.\-\ ]/)) {
            err_alert('L043', lnum, ewzG.errmsg.selecttext);
            ok = false;
        }
    });

    // All-Items fields cant be  image fields
    jform.find('input[id$="_all_items_"]:checked').closest('table.ewz_field').find('select[id$="_field_type_"]').find(":selected").each(function(){
        var type_for_all_items = jQuery(this).val();
        if(type_for_all_items == 'img') {
            err_alert('L044', lnum, ewzG.errmsg.no_img_all_items );
            ok = false;
        };
    });
    // All-Items fields cant append or be appended to
    jform.find('input[id$="_all_items_"]:checked' ).closest('table.ewz_field').find('input[id$="_append_"]').each(function(){
        if( jQuery(this).prop( "checked" ) ){
            err_alert('L040', lnum, ewzG.errmsg.no_append_all_items );
            ok = false;
        }
    });

    jform.find('input[id$="_all_items_"]:checked' ).closest('div[id$="field_mbox_"]').next().find('input[id$="_append_"]').each(function()
    {
        if( jQuery(this).prop( "checked" ) ){
            err_alert('L041', lnum, ewzG.errmsg.no_append_all_items );
            ok = false;
        }
    });

    return ok;
}

function get_all_confirms(jform){
    var warning = '';
    var maxnumitems = jform.find('select[id$="_max_num_items_"]').val();
    // Warn about potential problems but allow if user okays
    jform.find('input[id$="_max_img_size_"]').each(function() {
        jQuery(this).val(jQuery(this).val().replace(/[Mm]$/, ''));
        var maxs = jQuery(this).val();
        if (parseFloat(maxs) * maxnumitems >= parseFloat(ewzG.maxTotalMb)) {
            warning = warning +  ewzG.errmsg.sysmaxup;
        }
    });
    // warnings re ineffective restrictions
    jform.find('div[id^="add_restr_f"]').each(function() {
        var any = jQuery(this).find('select[name^="restrictions"]').find('option:eq(0)').not(":selected");
        if (any.length < 1) {
            warning = warning + ewzG.errmsg.all_any;
        } else  if (any.length < 2) {
            warning = warning + ewzG.errmsg.one_any;
        }
    });
    // warn re label not shown or in spreadsheet
    jform.find('input[id$="fdata_showlabel_"]').each(function() {
        if( !this.checked ){
            var spr_col_id = jQuery(this).attr('id').replace('fdata_showlabel_', 'ss_column_');
            var colval = jQuery('#' + spr_col_id).val();
            if( colval === undefined || colval == -1 ){
                warning = warning + ewzG.errmsg.useless_label;
            }
        }
    });
    return warning;
}

function get_layout_ident(element) {
    var id = jQuery(element).closest('div[id^="ewz_admin_layouts"]').attr('id');
    return id.replace('ewz_admin_layouts_f','').replace('_','');
}

function err_alert( alertid, layoutnum, msg )
{
    if( !g_errors_done[msg] )
    {
        ewz_alert(alertid, '(layout #' + layoutnum + ') ' + msg, ++popupN);
        g_errors_done[msg] = true;
    }
}

function layouts_compress_lines(checkbox){
    if(jQuery(checkbox).is(':checked')){
        jQuery('div[id^="ewz_admin_layouts_f"]').each(function(){
            jQuery(this).css( "padding", "1px" );
        });
        jQuery('div[id^="ewz_postbox-layout_f"]').each(function(){
            jQuery(this).css( "margin-bottom", "0px" );
        });
        jQuery('h3[id^="tpg_header_f"]').each(function(){
            jQuery(this).css( "padding", "1px" );
        });
    }  else {
        jQuery('div[id^="ewz_admin_layouts_f"]').each(function(){
            jQuery(this).css( "padding", "" );
        });
        jQuery('div[id^="ewz_postbox-layout_f"]').each(function(){
            jQuery(this).css( "margin-bottom", "" );
        });
        jQuery('h3[id^="tpg_header_f"]').each(function(){
            jQuery(this).css( "padding", "" );
        });
    }
}
function sort_layouts_alpha(){
    var mylist = jQuery('#ewz_layouts');
    var listitems = mylist.children('div[id^="ewz_admin_layouts_"]').get();
    listitems.sort(function(a, b) {
        var ja = jQuery(a);
        var jb = jQuery(b);
        var ta = jQuery('#' + ja.attr('id').replace('ewz_postbox-layout', 'tpg_header') ).text();
        var tb = jQuery('#' + jb.attr('id').replace('ewz_postbox-layout', 'tpg_header') ).text();
        return (ta < tb) ? -1 : (ta > tb) ? 1 : 0;
    });
    jQuery.each(listitems, function(idx, itm) {
        mylist.append(itm);
    });
}
