/*********************************************************************
 **
 **   server/appx-client-items.js - Client Item processing
 **
 **   This module contains code to process Appx Item screen elements.
 **
 *********************************************************************/

// what_str =  "@(#)Appx $Header: /src/cvs/appxHtml5/server/appx-client-item.js,v 1.126 2016/06/14 14:03:44 pete Exp $";

//find the smallest container for an item
//@see CharView.lookupDisplay
//TODO: use widget.boxid maybe?
"use strict";
function appxitembox(pos_row, pos_col, size_rows, size_cols) {
    var ret = null, ret2 = null;
    var dim = appx_session.screencols * appx_session.screenrows;
    var boxes = appx_session.current_show.boxes;
    for (var boxIdx = 0; boxIdx < boxes.length; boxIdx++) {
        var box = boxes[boxIdx];
        if (pos_col >= box.begin_column &&
            pos_col <= box.end_column &&
            pos_row >= box.begin_row &&
            pos_row <= box.end_row)
        {
            ret2 = box;//fallback: some widgets can extend past frame size
            if (pos_col + size_cols - 1 <= box.end_column &&
                pos_row + size_rows - 1 <= box.end_row)
            {
                ret = box;
            }
        }
    }
    if (ret == null) ret = ret2;
    if (ret != null && ret.newbox >= 0) ret = boxes[ret.newbox];
    return ret;
}

function appxcreateformatitem(item) {
    var longdata = null;
    var $itemhtml = $("<input type='text'>");
    $itemhtml.addClass("masked");
    if (!longdata) 
	longdata = parseItemLongData(item.rawdata);
    var maskstr = longdata.itemdata[1][0].replace(/\_/g, "~");
    for (var z = 0; z < longdata.itemdata[1][0].length; z++) {
	if (longdata.itemdata[1][0][z] == "X") {
	    maskstr = maskstr.replace(maskstr[z], longdata.itemdata[0][0][z]);
	}
    }

    Inputmask.extendDefinitions({
	"~": {
	    validator: '[A-Za-z0-9 ]',
	    cardinality: 1
	}
    });
    $itemhtml.inputmask(maskstr,{"placeholder": " ", insertMode: false});
    $itemhtml.val(longdata.itemdata[0]);
    
    return $itemhtml;
}

//Items Message Handler
function appxitemshandler(x) {
    var modeFound = false;

    try {
        appx_session.items.length = 0; //clear array
	
        var i = 0;
        var wt = null;
        var longdata = null;
        while (x.data.length > 0) {
            wt = null;
            longdata = null;
	    if (item){
		var lastItem = item;
	    }
            var item = x.data.shift(),
                $itemhtml = $("<div>");
            //console.log("item row=%d, col=%d special=%d wt=%d label=%s",item.pos_row,item.pos_col,item.special,(item.widget == null ? -1 : item.widget.wWidgetType),item.data);
	    item.uline = appxIsUline(item);
            appxSetModifiableCapable(item, false);
	    
            item.maxLen = item.size_rows * item.size_cols;
            switch (item.type) {
                 case ELEM_ALP_CONTIG:
                 case ELEM_ALP_NON_CONTIG:
                 case ELEM_ALP_SUBSTR:
                 case ELEM_ALP_CMPRS:
                     var loInt = item.digits_right;
                     var hiInt = item.digits_left;
                     if (loInt < 0) loInt += 256;
                     if (hiInt < 0) hiInt += 256;
                     item.maxLen = ((hiInt * 256) + loInt);
                     break;
                     //date field fix
                 case ELEM_ALP_JUL_DATE:
                 case ELEM_ALP_GREG_DATE:
                 case ELEM_BIN_JUL_DATE:
                 case ELEM_BIN_GREG_DATE:
                 case ELEM_PD_JUL_DATE:
                 case ELEM_PD_GREG_DATE:
                 case ELEM_UNIVERSAL_DATE:
                     if (!longdata) longdata = parseItemLongData(item.rawdata);
                     item.data = longdata.itemdata[0][0];
                     break;
                 default:
                     break;
            }
	    


            item.widget = new Widget(0, "", item.widget);
            wt = item.widget.wWidgetType;
	    
            if (item.type == ELEM_LOG && wt == null) {
                wt = WIDGET_TYPE_CHECK_BOX;
		item.widget.wWidgetType = WIDGET_TYPE_CHECK_BOX;
            }
	    
            if (appxIsModifiable(item) == false && appxIsModifiableCapable(item) == false && appxIsStatus(item) == false && wt == null) {
                if (item.type == ELEM_LOG && wt != WIDGET_TYPE_CHECK_BOX) {
                    item.data = item.data == "1" ? "Y" : item.data == "0" ? "N" : "";
                }
                var rowtxt = new RowTextStruct();
                rowtxt.type = ROWTEXT_TYPE_ITEM;
		rowtxt.uline = item.uline;
                rowtxt.boxid = -1;
		rowtxt.isTitle = item.widget.wInvert;
                rowtxt.pos_row = item.pos_row;
                rowtxt.pos_col = item.pos_col;
                rowtxt.size_rows = item.size_rows;
                rowtxt.size_cols = item.size_cols;
                rowtxt.string = item.data;
		rowtxt.wordWrap = appxIsWordWrap(item);
                appx_session.rowtext.unshift(rowtxt);
		appx_session.items.push([item, null, (item.pos_row * 256) + item.pos_col]);
		continue;
            }
	    
            //TODO: merge item widget stuff with 'normal' widget code

            // gotta check this before and after
            //TODO: some fields are still added modifiable in inquire mode
            if (appxIsModifiable(item)) {
		item.data = item.data.replace(/\xB6/g, "\r\n").replace(/ *$/gm, "");; //all occurrences of paragraph markers with newline

                // found problem in scan popups with wt == null, set to input if null and modifialble
                if (wt == null && (item.special & 0x02) == 0x02) {
                    wt = WIDGET_TYPE_LISTBOX;
		    item.widget.wWidgetType = WIDGET_TYPE_LISTBOX;
                }
                if (wt == null) {
                    wt = WIDGET_TYPE_RAW_TEXT;
		    item.widget.wWidgetType = WIDGET_TYPE_RAW_TEXT;
                }
            }
            else {
		item.data = item.data.replace(/\xB6/g, "<br/>").replace(/ *$/gm, "");//all occurrences of paragraph markers with newline
		
                // found problem in scan popups with wt == null, set to label if null and not modifialble
                if (wt == null) {
                    wt = WIDGET_TYPE_LABEL;
		    item.widget.wWidgetType = WIDGET_TYPE_LABEL;
                }
		else if(wt == WIDGET_TYPE_FILE_CHOOSER || wt == WIDGET_TYPE_DATE_CHOOSER || wt == WIDGET_TYPE_LISTBOX ) {
		    item.widget.wLabel = null;
		    item.widget.wWidgetType = WIDGET_TYPE_RAW_TEXT;
		    wt = WIDGET_TYPE_RAW_TEXT;
		}
            }
	    
            switch (wt) {
		 case WIDGET_TYPE_BUTTON:
		     $itemhtml = $("<button type='button'>").css({
			 "margin": "0",
			 "padding": "0"
		     });
		     
		     $itemhtml.addClass("button")
			 .data("row", item.widget.wPositionY)
			 .data("col", item.widget.wPositionX);
		     if (item.widget.wLabel == null && item.data != null){
			 item.widget.wLabel = item.data;
		     }
		     
		     if (item.widget.wCommandValueAdjusted != null) {
			 $itemhtml.attr("id", addClientId("widget_sac_" + item.widget.wCommandValueAdjusted,item.widget.wClientId));
			 $itemhtml.click(function () {
			     var opt = parseInt(getClientId(this.id).substring(11));
			     if( opt >= 250 && opt <= 255 ) {
				 var col = $(this).data("col");
				 var row = $(this).data("row");
				 if (col && row) {
				     appxPutCursor(col, row);
				 }
			     }
			     appxwidgetcallback(getClientId(this.id).substring(11));
			 });
		     }
		     if (!item.widget.wBorder){
			 item.widget.wBorder = BORDER_BEVEL_RAISED;
		     }
		     break;
		     
                 case WIDGET_TYPE_SLIDER:
		     $itemhtml = $("<div>");
		     $itemhtml.addClass("noUiSlider");
                     //need some padding for the slider
                     var paddedbox = $("<div>").css({
                         "padding": "10px"
                     });

                     //create the slider
		     var mslider = $("<div>").addClass('slider');
		     
		     /*adding element attributes that are accessed when processing
		     **element in apply styles to actually create slider*/
		     mslider.attr("data-value", parseInt(item.data));
		     mslider.attr("data-min", item.widget.wMinValue);
		     mslider.attr("data-max", item.widget.wMaxValue);
		     mslider.attr("data-tickMajor", item.widget.wTickMajor);
		     mslider.attr("data-tickMinor", item.widget.wTickMinor);
		     mslider.attr("data-tickShow", item.widget.wPaintTicks);
		     mslider.attr("data-tickLabels", item.widget.wPaintTickLabels);
		     mslider.attr("data-tickSnap", item.widget.wSnapToTicks);
		     mslider.attr("data-invert", item.widget.wInvert);
		     mslider.attr("data-modifiable", appxIsModifiable(item));
		     mslider.attr("data-orientation", item.widget.wOrientation);

                     $(paddedbox).append(mslider);
                     $itemhtml.append(paddedbox);
                     break;
		     
                 case WIDGET_TYPE_PROGRESS_BAR:
		     $itemhtml = $("<div>").progressbar({
                         value: parseInt(item.data)
                     });
		     $itemhtml.find(".ui-progressbar-value").height(item.size_rows*appx_session.rowHeightPx);
		     $itemhtml.find(".ui-progressbar-value").css({
			 "background": "none",
			 "background-color": item.widget.wColorFg
		     });
                     break;
		     
                 case WIDGET_TYPE_PASSWORD:
                     $itemhtml = $("<input type='password'>").val(item.data);
                     break;
		     
                 case WIDGET_TYPE_LISTBOX:
                     $itemhtml = $("<select data='" + item.data + "'>").val(item.data).addClass("appx-listbox");
                     break;
		     
                 case WIDGET_TYPE_LABEL:
                     $itemhtml = $("<span>");
                     $itemhtml.text(item.data);
                     break;
		     
                 case WIDGET_TYPE_PICTURE:
                     $itemhtml = $("<div>");
                     break;
		     
                 case WIDGET_TYPE_RAW_TEXT:
		     if (appxIsDate(item) && appxIsModifiable(item)) {
			 $itemhtml = appxcreateformatitem(item);
		     }
		     else {
			 if (item.size_rows > 1){
			     $itemhtml = $("<textarea>").css("padding", "0"); //remove extra width
			     if (!appxIsWordWrap(item)){
				 $itemhtml.addClass("appx-alpha-field");
			     }
			 }else{
			     $itemhtml = $("<input type='text'>");
			 }
			 appxSetModifiableCapable(item, true);
			 if (item.type == ELEM_LOG) {
			     item.data = item.data == "1" ? "Y" : item.data == "0" ? "N" : "";
			 }

			 $itemhtml.val(item.data.replace("\n", " \n"));
		     }
                     break;
		     
                 case WIDGET_TYPE_CHECK_BOX:
                     $itemhtml = $("<input type='checkbox'>");
                     if (item.data == "1") {
                         $itemhtml.prop("checked", true);
                         $itemhtml.data("checked", 2);
                     }
                     else if (item.data == "0") {
                         $itemhtml.prop("checked", false);
                         $itemhtml.data("checked", 0);
                     }
                     else {
                         $itemhtml.prop("indeterminate", true);
                         $itemhtml.data("checked", 1);
                     }
		     
                     $itemhtml.val(item.data);
                     break;
		     
                 case WIDGET_TYPE_FILE_CHOOSER:
                     $itemhtml = $("<input>").css({
                         "background": "#fff url("+appxClientRoot+"/images/folder.png) no-repeat",
                         "overflow": "hidden",
                         "background-position": "99% 50%",
                         "border": "double 1px #555",
                         "padding-right": "5px"
                     });
                     $itemhtml.addClass("appxfilewrapper");
                     $itemhtml.val(item.data);
                     break;
		     
                 case WIDGET_TYPE_COLOR_CHOOSER:
                     $itemhtml = $("<div>");
                     $itemhtml.addClass("appxcolorpickerwrapper");
                     var cp = $("<input type='text' class='appxitem'>");
                     $(cp).addClass("appxcolorpicker");
                     var ic = $("<img src='"+appxClientRoot+"/images/colorpicker.jpg' />").css({
                         "position": "absolute",
                         "right": "0px",
                         "top": "2px",
                         "z-index": 100000
                     });
                     $itemhtml.append(cp);
                     $itemhtml.append(ic);
                     break;
		     
                 case WIDGET_TYPE_HTML_VIEWER:
                     $itemhtml = $("<div>").css("padding", "0"); //remove extra width
                     $itemhtml.html(item.data);
                     $itemhtml.addClass("appx-html-viewer");
                     switch (item.widget.wHtmlViewerType) {
                          case "flash":
                              $itemhtml = $("<object data='" + item.data + "'></object>");
                              break;
                          case "media":
                              $itemhtml = $("<embed src='" + item.data + "'></embed>");
                              break;
                          case "view":
			      if(item.data.indexOf("http") == 0){
				  $itemhtml = $("<iframe src='" + item.data +  "'></iframe>");
			      }else{
				 $itemhtml = $("<iframe src='" + item.data + "' srcdoc='" + item.data + "'></iframe>"); 
			      }
                              break;
                          case "browse":
                              if(item.data.indexOf("http") == 0){
				  $itemhtml = $("<iframe src='" + item.data +  "'></iframe>");
			      }else{
				  $itemhtml = $("<iframe src='" + item.data + "' srcdoc='" + item.data + "'></iframe>");
			      }
                              break;
                          case "edit":
                          case "inline":
                          case "autoedit":
			      $itemhtml = $("<textarea>");
			      $itemhtml.val(item.data);
			      if (item.widget.wEditorConfig){
				  $itemhtml.addClass("ckeditor " + AppxResource.load(item.widget.wEditorConfig));
			      }else{
				  $itemhtml.addClass("ckeditor");
			      }
                              break;
                     }
                     break;
		     
                 case WIDGET_TYPE_HTML_EDITOR:
                     $itemhtml = $("<div>").css({
                         "padding": "0"
                     }); //remove extra width
                     $itemhtml.html(item.data);
		     if (item.widget.wEditorConfig){
			 $itemhtml.addClass("ckeditor " + AppxResource.load(item.widget.wEditorConfig));
		     }else{
			 $itemhtml.addClass("ckeditor");
		     }
                     break;
                 case WIDGET_TYPE_FLASH_PLAYER:
                     $itemhtml = $("<object data='" + item.data + "'></object>");
                     break;
                 case WIDGET_TYPE_TEXT_AREA:
		     //remove extra width
		     $itemhtml = $("<textarea>").css("padding", "0"); 
		     appxSetModifiableCapable(item, true);

		     /*When placing data into element replace html <br> tags
		     **with valid line breaks*/
                     $itemhtml.val(item.data.replace(/\<br \/\>|\<br\>|\<br\/\>/gi, "\r\n"));
                     break;
		     
                 case WIDGET_TYPE_DATE_CHOOSER:
                     $itemhtml = $("<div>").addClass("appxdatefield");
		     
                     if (!longdata) longdata = parseItemLongData(item.rawdata);
                     var i = parseItemDateData(longdata);
                     item.data = i.data;
		     $(i.dv[0]).attr("id", "appxitem_" + item.pos_col + "_" + item.pos_row);
		     $(i.dv[0]).on("focus", function () { //{ val:item.data }
			 var ida = getClientId($(this).attr("id")).split('_');
			 logca("item focus: " + ida[1] + "." + ida[2]);
			 appxPutCursor(ida[1], ida[2]);
		     });
                     $itemhtml.append(i.dv);
                     $itemhtml.append(i.df);
                     break;

                 case WIDGET_TYPE_TABLE:
		     item.widget.wSizeH -= 1;
		     $itemhtml = $("<div>")
		         .addClass("appxtablewidget")
		         .attr("id", addClientId( "appxitem_" + item.widget.wPositionX + "_" + item.widget.wPositionY, item.widget.wClientId))
		         .data("action", {
			     "command": item.widget.wCommand,
			     "command2": item.widget.wCommand2
			 })
		         .data("row", item.widget.wPositionY)
		         .data("col", item.widget.wPositionX);
		     

		     //add jqgrid or extention here
                     break;
		     
                 default:
                     if (item.size_rows > 1) {
			 //remove extra width
                         $itemhtml = $("<textarea>").css("padding", "0"); 
			 /*When placing data into element replace html <br> tags
			 **with valid line breaks*/
                         $itemhtml.val(item.data.replace(/\<br \/\>|\<br\>|\<br\/\>/gi, "\r\n"));
                     }
                     else {
                         $itemhtml = $("<div>");
                         $itemhtml.html(item.data);
                     }
            } //end switch(wt)

            $itemhtml.addClass("item_with_widget");

            // FLD_SPEC_MOD
            // can't we run this after the item's elem is created and set prop disable == true or false?
            if (appxIsModifiable(item)) {
                // all modifiable items need input class
                $itemhtml.addClass("input");
		
                $itemhtml.on("input change", {
                    wx: item.widget
                }, function (e) {
                    $(this).addClass("dirty");
                    appxSetStatusStateText(APPX_STATE_DIRTY);
		    
                    //check if last char is not a space or else it's not saved
                    if (e.data.wx && $(this).val().slice(-1) != ' ') {
                        appx_session.valueTimerStart(e.data.wx.wCommandValueAdjusted);
                    }
                });
		// Firefox is special.  It refuses to fire a change event on a SELECT Listbox until the user 
		// tabs out of the element if they changed the list value using the keyboard.  So we have to 
                //use a key event to trigger it being dirty and to process on change triggers.
		if( $itemhtml.hasClass("appx-listbox") ) {
		    $itemhtml.on("keypress", {
			wx: item.widget
				}, function (e) {
			    $(this).addClass("dirty");
			    appxSetStatusStateText(APPX_STATE_DIRTY);
			    
			    //check if last char is not a space or else it's not saved
			    if (e.data.wx && $(this).val().slice(-1) != ' ') {
				appx_session.valueTimerStart(e.data.wx.wCommandValueAdjusted);
			    }
			});
		}
		
		if( appxIsMasked(item) ) {
		    $itemhtml.on("input keyup", {
			wx: item.widget
		    }, function (e) {
			$(this).addClass("dirty");
			appxSetStatusStateText(APPX_STATE_DIRTY);
			
			//check if last char is not a space or else it's not saved
			if (e.data.wx && $(this).val().slice(-1) != ' ') {
			    appx_session.valueTimerStart(e.data.wx.wCommandValueAdjusted);
			}
		    });
		}
		
                $itemhtml.addClass("appx-modifiable");
		
                if (appxIsToken(item)) {
                    if (wt == WIDGET_TYPE_RAW_TEXT) {
                        $itemhtml.attr('maxlength', item.size_cols);
                    }
                }
                else {
                    if (item.maxLen) $itemhtml.attr('maxlength', item.maxLen);
                }

            }
            else { //ELSE !FLD_SPEC_MOD
		
		if (wt == WIDGET_TYPE_NONE || wt == WIDGET_TYPE_RAW_TEXT ||
		    wt == WIDGET_TYPE_LABEL){
                    $itemhtml = $("<div>").addClass("appx-raw-text");
		    
                    if (item.pos_row <= appx_session.screenrows - 3) {
                        if (item.size_rows > 1 || wt != WIDGET_TYPE_LABEL) { //dont mangle fonts by pre tag
                            var $pre = $("<div>"); //.css({"margin": "0","padding": "0"});
                            if (item.size_rows > 1) 
				$pre.css("white-space", "pre-wrap"); //20140325 chrisa: added wordwrap
                            else 
				$pre.css("white-space", "nowrap");
                            $pre.html(item.data).appendTo($itemhtml);
                        }
                        else {
                            $itemhtml.html(item.data);
                        }
                    }
                }
		
                if (appxIsModifiableCapable(item)) {
                    $itemhtml.addClass("appx-not-modifiable");
                }
		
            } //END FLD_SPEC_MOD
	    
            if (appxIsUppercase(item))
                $itemhtml.css("text-transform", "uppercase");
	    
            if (appxIsModifiable(item) || wt == WIDGET_TYPE_BUTTON)
                $itemhtml.prop("disabled", false);
            else
                $itemhtml.prop("disabled", true);

            if (appxIsNullOk(item)) {
                $itemhtml.addClass("appx-nullok");
            }
            else {
                if (!longdata) longdata = parseItemLongData(item.rawdata);
                if (longdata && longdata.itemdata[0][0] == "")
                    $itemhtml.addClass("appx-nullok");
            }
	    
            if (appxIsMasked(item)) {
                $itemhtml.addClass("masked");
                if (!longdata) longdata = parseItemLongData(item.rawdata);
                var maskstr = longdata.itemdata[1][0].replace(/\_/g, "*");
                for (var z = 0; z < longdata.itemdata[1][0].length; z++) {
                    if (longdata.itemdata[1][0][z] == "X") {
                        maskstr = maskstr.replace(maskstr[z], longdata.itemdata[0][0][z]);
                    }
                }
		
		$itemhtml.inputmask(maskstr,{"placeholder": " ", insertMode:false});
		$itemhtml.val(longdata.itemdata[0]);
            }
	    
            if (wt == WIDGET_TYPE_LABEL)
                $itemhtml.addClass("label").addClass("notranslate");
            else
                $itemhtml.addClass("appxitem").addClass("notranslate").addClass("appxfield").data("row", item.pos_row).data("col", item.pos_col);

	    if (wt != WIDGET_TYPE_BUTTON){
		$itemhtml.attr("id", addClientId("appxitem_" + item.pos_col + "_" + item.pos_row,item.widget ? item.widget.wClientId : null)); //TODO: use data()
	    }

	    $itemhtml.on("focus", function () { //{ val:item.data }
		appx_session.valueTimerStop();
		var ida = getClientId($(this).attr("id")).split('_');
                logca("item focus: " + ida[1] + "." + ida[2]);
		appxPutCursor(ida[1], ida[2]);

		if (appx_session.lastOption && appx_session.lastOption === "333"){
		    this.selectionStart = this.selectionEnd = this.value.length;
		}else{
		    if (appx_session.getProp("autoSelect")) {
			$(this).select();
		    }
		}
	    });
	    
	    
            appxwidgetdimensions(item, $itemhtml);
            appxwidgetshandlerprops(item, $itemhtml);
	    
            // TODO:  Move this up to tests for widget types ~ line 60 - CS 03/12/2014
            //get token field data
            if (appxIsToken(item)) {
		if (appxIsModifiable(item) && (wt == WIDGET_TYPE_LISTBOX || wt == null)) {
                    appx_session.token_groups[item.token_group] = appx_session.server.replace(/\./g, "_") + "_" + appx_session.port + "_" + item.token_cacheid + "_" + item.token_app + "_" + item.token_ap_ver;
		    
                    var cacheid = appx_session.server.replace(/\./g, "_") + "_" + appx_session.port + "_" + item.token_cacheid + "_" + item.token_app + "_" + item.token_ap_ver;
                    if (!appx_session.token_cache[cacheid]) {
                        appx_session.token_cache.length++;
                        appx_session.token_cache.keys.push(cacheid);
                        appx_session.token_cache[cacheid] = {
                            "cacheid": cacheid,
                            "data": ""
                        };
                        if (!appxtokengetitem(cacheid)) {
                            sendappxtoken(item.token_group);
                        }
                    }
                    $itemhtml.addClass(cacheid);    
                }
            }
	    
            if (item.size_rows > 1)
                $itemhtml.css({
                    "overflow": "auto"
                });
            else if (item.widget == null || item.widget.wWidgetType != WIDGET_TYPE_SLIDER)
		if (item.size_rows > 1) {
		    $itemhtml.css({
			"overflow": "hidden",
			"white-space": "pre-wrap"
		    });
		}
	    else {
		$itemhtml.css({
		    "overflow": "hidden",
		    "white-space": "pre"
		});
	    }

	    if( item.uline ) {
		if( $itemhtml ) {
		    $itemhtml.addClass("appx-uline");
		}
	    }

	    if( item.pos_row <= appx_session.screenrows - 3 ) 
		appx_session.items.push([item, $itemhtml, (item.pos_row * 256) + item.pos_col]);
	    
            if (appxIsStatus(item)) {
                if (appxIsStatusDb(item)) appxSetStatusDbText(item.data);
                if (appxIsStatusAp(item)) appxSetStatusApText(item.data);
                if (appxIsStatusVer(item)) appxSetStatusVerText(item.data);
                if (appxIsStatusUser(item)) appxSetStatusUserText(item.data);
                if (appxIsStatusDate(item)) appxSetStatusDateText(item.data);
                if (appxIsStatusKeymap(item)) appxSetStatusKeymapText(item.data);
                if (appxIsStatusMode(item)) appxSetStatusModeText(item.data);
                if (appxIsStatusEmbld(item)) appxSetStatusEmbldText(item.data);
                if (appxIsStatusProgress(item)) appxSetStatusProgressText(item.data);
		
                if (appxIsStatusMode(item)) modeFound = true;
            }
	    
            i++;
	    
        } //end appxNullOk();
	
    }
    catch (ex) {
        console.log("appxitemshandler: " + ex);
	console.log(ex.stack);
    } //end try
    
    if (modeFound == false) appxSetStatusModeText("");
} // end function appxitemhandler()

function appxIsMasked(item) {
    return ((item.options & FLD_OPT_MASK) != 0);
}

function appxIsUline(item) {
    return ((item.special & FLD_SPEC_ULINE) != 0);
}

function appxIsModifiable(item) {
    return ((item.special & FLD_SPEC_MOD) == FLD_SPEC_MOD);
}

function appxIsModifiableCapable(item) {
    return ((item.special & FLD_SPEC_MOD_ABLE) == FLD_SPEC_MOD_ABLE);
}

function appxSetModifiableCapable(item, val) {
    if (val == true)
        item.special |= FLD_SPEC_MOD_ABLE;
    else
        item.special &= ~FLD_SPEC_MOD_ABLE;
}

function appxIsDLUonTabOut(item){
    return (appxIsModifiable(item) && appxIsScannable(item) && ((item.special & FLD_SPEC_DLU_TABOUT) != 0));
}
function appxIsScannable(item) {
    return (appxIsModifiable(item) && ((item.options & FLD_OPT_SCAN) != 0));
}

function appxIsStatus(item) {
    return ((item.options & FLD_OPT_STAT_BITS) != 0);
}

function appxIsStatusDb(item) {
    return ((item.options & FLD_OPT_STAT_BITS) == FLD_OPT_STAT_DB);
}

function appxIsStatusAp(item) {
    return ((item.options & FLD_OPT_STAT_BITS) == FLD_OPT_STAT_AP);
}

function appxIsStatusVer(item) {
    return ((item.options & FLD_OPT_STAT_BITS) == FLD_OPT_STAT_VER);
}

function appxIsStatusUser(item) {
    return ((item.options & FLD_OPT_STAT_BITS) == FLD_OPT_STAT_USER);
}

function appxIsStatusDate(item) {
    return ((item.options & FLD_OPT_STAT_BITS) == FLD_OPT_STAT_DATE);
}

function appxIsStatusKeymap(item) {
    return ((item.options & FLD_OPT_STAT_BITS) == FLD_OPT_STAT_KEYMAP);
}

function appxIsStatusMsg(item) {
    return ((item.options & FLD_OPT_STAT_BITS) == FLD_OPT_STAT_MSG);
}

function appxIsStatusMode(item) {
    return ((item.options & FLD_OPT_STAT_BITS) == FLD_OPT_STAT_MODE);
}

function appxIsStatusEmbld(item) {
    return ((item.options & FLD_OPT_STAT_BITS) == FLD_OPT_STAT_EMBLD);
}

function appxIsStatusProgress(item) {
    return ((item.options & FLD_OPT_STAT_BITS) == FLD_OPT_STAT_PROGRESS);
}

function appxIsDate(item) {
    return (item.type == ELEM_ALP_JUL_DATE || 
	    item.type == ELEM_ALP_GREG_DATE ||
	    item.type == ELEM_BIN_JUL_DATE ||
	    item.type == ELEM_BIN_GREG_DATE ||
	    item.type == ELEM_PD_JUL_DATE ||
	    item.type == ELEM_PD_GREG_DATE ||
	    item.type == ELEM_UNIVERSAL_DATE);
}

function appxIsToken(item) {
    return ((item.special & FLD_SPEC_TOKEN) == FLD_SPEC_TOKEN);
}

function appxIsWordWrap(item) {
    return ((item.special & FLD_SPEC_WORD_WRAP) == FLD_SPEC_WORD_WRAP);
}

function appxIsUppercase(item) {
    return ((item.options & FLD_OPT_UCASE) != 0);
}

function appxIsNullOk(item) {
    return ((item.options & FLD_OPT_NULLOK) != 0);
}

function parseItemDateData(i) {
    var maskstr = i.itemdata[1][0].replace(/\_/g, "*");

    for (var z = 0; z < i.itemdata[1][0].length; z++) {
        if (i.itemdata[1][0][z] == "X") {
            maskstr = maskstr.replace(maskstr[z], i.itemdata[0][0][z]);
        }
    }

    var pickstr = "";
    var datemsk = "";
    var timemsk = "";
    var part = "";
    var hasDate = true;

    for (var z = 0;
         (z * 2) < i.itemdata[2][0].length; z++) {
        part = i.itemdata[2][0].substring(z * 2, (z * 2) + 2);

        if (part != "--") {
            switch (z) {
                 case 0: // Century
                     pickstr += part;
                     datemsk += "yy";
                     break;
                 case 1: // Year
                     pickstr += part;
                     if (datemsk.length == 0) // If there is no century then we add the mask for year only
                         datemsk += "y";
                     break;
                 case 2: // Month
                     pickstr += part;
                     datemsk += "mm";
                     break;
                 case 3: // Day
                     pickstr += part;
                     datemsk += "dd";
                     break;
                 case 4: // Hour
                     if (datemsk.length > 0) // If there is a date part then we add a space separator to the string
                         pickstr += " ";
                     pickstr += part;
                     timemsk += "HH";
                     break;
                 case 5: // Minute
                     if (timemsk.length > 0) { // If there are hours we add the colon separator
                         pickstr += ":";
                         timemsk += ":";
                     }
                     pickstr += part;
                     timemsk += "mm";
                     break;
                 case 6: // Second
                     if (timemsk.length > 0) { // If the are minutes we add the colon separator
                         pickstr += ":";
                         timemsk += ":";
                     }
                     pickstr += part;
                     timemsk += "ss";
                     break;
                 case 7: // Thousands
                     if (timemsk.length > 0) { // If there are seconds we add the period separator
                         pickstr += ".";
                         timemsk += ".";
                     }
                     pickstr += part + "0"; // Appx does thousands, not milliseconds so we add the third digit
                     timemsk += "l";
                     break;
            }
        }
    }
    if (datemsk == ""){
	hasDate = false;
    }
    var pickval = '{"value":"' + pickstr + '","datemsk":"' + datemsk + '","timemsk":"' + timemsk + '"}';
    var dv = $("<input class='appxdatevalue appxitem' type='text' style='width: 100%; height: 100%'>");
    var df = $("<input class='appxdatepicker' type='hidden'>").val(pickval);

    dv.inputmask(maskstr, {insertMode: false});
    dv.val(i.itemdata[0]);

    
    return {
        "data": i.itemdata[0][0],
	"hasDate": hasDate,
        "df": df,
        "dv": dv
    };
}

function parseItemLongData(itemdata) {
    // Convert buffer to string
    var newarray = [];
    try {
        newarray.push(91); // [
        newarray.push(34); // "
        for (var i = 0; i < itemdata.length; i++) {
            if (itemdata[i] == 0x02 || itemdata[i] == 0x01) {
                if (itemdata[i] == 0x02) {
                    newarray.push(34); // "
                    newarray.push(44); // ,
                    newarray.push(34); // "
                }
                if (itemdata[i] == 0x01) {
                    newarray.push(34); // "
                    newarray.push(93); // ]
                    newarray.push(44); // ,
                    newarray.push(91); // [
                    newarray.push(34); // "
                }
            }
            else {
                newarray.push(itemdata[i]);
            }
        }
        newarray.push(34); // "
        newarray.push(93); // ]
        return JSON.parse('{"itemdata": [' + (ab2str(newarray)).replace(/\n/g, "\\\\n").replace(/\r/g,"\\\\r") + ']}');
    }
    catch (ex) {
        console.log("parseItemLongData: " + ex);
        console.log("parseItemLongData: data=" + newarray);
	console.log(ex.stack);
        newarray = [91, 34, 34, 93];
        return JSON.parse('{"itemdata": [' + ab2str(newarray) + ']}');
    }

}

var FLD_OPT_NULLOK = 0x01;
var FLD_OPT_UCASE = 0x02;
var FLD_OPT_MASK = 0x04;
var FLD_OPT_SCAN = 0x08;

var FLD_OPT_STAT_BITS = 0xF0;
var FLD_OPT_STAT_DB = 0x10;
var FLD_OPT_STAT_AP = 0x20;
var FLD_OPT_STAT_VER = 0x30;
var FLD_OPT_STAT_USER = 0x40;
var FLD_OPT_STAT_DATE = 0x50;
var FLD_OPT_STAT_KEYMAP = 0x60;
var FLD_OPT_STAT_MSG = 0x70;
var FLD_OPT_STAT_MODE = 0x80;
var FLD_OPT_STAT_EMBLD = 0x90;
var FLD_OPT_STAT_PROGRESS = 0xA0;

//MFld
//var FLD_SPEC_NONE       = 0x00;
//var FLD_SPEC_PICTURE    = 0x01;
var FLD_SPEC_TOKEN = 0x02;
var FLD_SPEC_WORD_WRAP    = 0x04;
var FLD_SPEC_MOD_ABLE = 0x08;
var FLD_SPEC_ULINE = 0x08;
//var FLD_SPEC_ENCODING   = 0x30;
var FLD_SPEC_DLU_TABOUT = 0x40;
var FLD_SPEC_MOD = 0x80;

var ELEM_NONE = 0;
var ELEM_ALP_CONTIG = 1;
var ELEM_ALP_NON_CONTIG = 2;
var ELEM_ALP_JUL_DATE = 3;
var ELEM_ALP_GREG_DATE = 4;
var ELEM_BIN = 5;
var ELEM_BIN_JUL_DATE = 6;
var ELEM_BIN_GREG_DATE = 7;
var ELEM_PD_FIX = 8;
var ELEM_PD_JUL_DATE = 9;
var ELEM_PD_GREG_DATE = 10;
var ELEM_LOG = 11;
var ELEM_PD_VAR = 12;
var ELEM_ALP_SUBSTR = 13;
var ELEM_ALP_CMPRS = 14;
var ELEM_UNIVERSAL_DATE = 15;
