var MoAutoComplete = {
	ViewList: function(autoCompleteId) {
		var autoComplete = $find(autoCompleteId);

		// To show the popup by JavaScript, following code is necessary.
		// [NOTE] This trick is weak if the AutoCompleteExtender is updated.
		autoComplete._cache = {};
		autoComplete._currentPrefix = null;
		autoComplete._textBoxHasFocus = true;

		// save the old minimum prefix length, and set the value 0
		var oldMinimumPrefixLength = autoComplete.get_minimumPrefixLength();
		autoComplete.set_minimumPrefixLength(0);

		// send the event to show the popup
		autoComplete._onTimerTick(null, null);

		// restore the old minimum prefix length
		autoComplete.set_minimumPrefixLength(oldMinimumPrefixLength);
	},
	SetValue: function(autoCompleteId) {
		var autoComplete = $find(autoCompleteId);
		if (autoComplete) {
			var element = autoComplete.get_element();
			if (element) {
				if (element.value == "") {
					//todo set selected value and auto calculate Scroll Index
					var selectedIndex = 18;
					autoComplete._handleScroll(autoComplete._completionListElement.childNodes[selectedIndex], selectedIndex + 15);
					autoComplete._highlightItem(autoComplete._completionListElement.childNodes[selectedIndex]);
					autoComplete._selectIndex = selectedIndex;
				}
				else {
					var children = autoComplete._completionListElement.childNodes;
					if (children) {
						for (var i = 0; i < children.length; ++i) {
							if (element.value === children[i].innerText) {
								var item = children[i];
								autoComplete._handleScroll(item, selectedIndex);
								autoComplete._highlightItem(item);
								autoComplete._selectIndex = i;
								break;
							}
						}
					}
				}
			}
		}
	}
};

var timeZone = {
	getTimeZoneOffset: function ()
	{
		var current_date = new Date( );
		var gmt_offset = current_date.getTimezoneOffset( );
		return gmt_offset;
	}
}

var defaultButtons = {
	registerButton: function(cId, bId) {
		var oC = document.getElementById(cId);
		var oB = document.getElementById(bId);
		if (typeof (oC) !== 'undefined' && typeof (oB) !== 'undefined') {
			if (typeof (oC.addEventListener) !== 'undefined') {
				oC.addEventListener('keypress', function(e) {
					defaultButtons.fireDefaultButton(e, oB);
				}, false);
			} else if (typeof (oC.attachEvent) !== 'undefined') {
				oC.attachEvent('onkeypress', function(e) {
					defaultButtons.fireDefaultButton(e, oB);
				});
			}
		}
	},
	fireDefaultButton: function(e, lbtn) {
		if (!e.which && !e.keyCode) {
			return;
		} else {
			var k = (e.which || e.keyCode);
			try {
				if (k === 13) {
					lbtn.focus();
					eval(lbtn.href);
					return true;
				}
			}
			catch (err) {
				return false;
			}
		}
	}
};

function MaxLength(textElement, value) {

	if (textElement) {
		if (textElement.value.length > value - 1) {
			textElement.value = textElement.value.substring(0, value - 1);
			return false;
		}
	}
}

function addEvent(obj, event_name, fnc, assigment_only) {
	var rtrn = true;
	if (typeof obj == "undefined") { return false; }

	if (!assigment_only && obj.attachEvent) {
		obj.attachEvent("on" + event_name, fnc);
	}
	else if (!assigment_only && obj.addEventListener) {
		obj.addEventListener(event_name, fnc, false);
	}
	else {
		rtrn = _bindEvent(obj, event_name, fnc);
	}
	return rtrn;
} //eof addEvent


function removeEvent(obj, eventName, fnc, assigment_only) {
	var rtrn = true;
	if (typeof obj == "undefined") { return false; }

	if (!assigment_only && obj.detachEvent) {
		obj.detachEvent("on" + eventName, fnc);
	}
	else if (!assigment_only && obj.removeEventListener) {
		obj.removeEventListener(eventName, fnc, false);
	}
	else {
		rtrn = _unbindEvent(obj, eventName, fnc);
	}
	return rtrn;
} //eof removeEvent


function _bindEvent(obj, event_name, fnc) {
	var str = '', handlers = '';

	/* Extract current handlers */
	if (obj["on" + event_name] != null) {
		str = obj["on" + event_name].toString();     //current event handler wrapper fx
		handlers = _removeWrapper(str, event_name);  //current handlers from without wrapper
	}

	var newListener = fnc.toString();                //new function to string
	var newArray = new Array();
	var rtrnArray = new Array();
	var addReturn = null;

	/* Check if new function has a return statement */
	if (/return \w+;/.test(newListener)) addReturn = true;

	/* Create function call string to be placed in handler wrapper
	* 1. Create string of passed (new) function declaration line
	*    converting to function call, with optional return:
	*     e.g. function x() {etc.} becomes x(); or return x();
	* 2. append to string of existing event handlers putting
	*    any with return value at end of list.
	*/
	newListener = (addReturn ? 'return ' : '') + newListener.match(/function ([\w$]*\s*\([\w]*\))\s*\{?/)[1];
	handlers += '\n' + newListener + ';';

	/* Put function calls into 1 of 2 arrays
	* based on whether the function returns a value
	*/
	var handlerArray = handlers.match(/[^;]+;\s*/g); //returns array from string separated at /[^;]+;\s*/

	for (var i = 0; i < handlerArray.length; i++) {
		if (!/return /.test(handlerArray[i])) {
			newArray[newArray.length] = handlerArray[i].replace(/^\s*|\s*$/g, '');
		}
		else {
			rtrnArray[rtrnArray.length] = handlerArray[i].replace(/^\s*|\s*$/g, '');
		}
	}

	/* Combine the function calls into a string
	* with those returning a value last
	*/
	handlers = newArray.join('\n');
	if (rtrnArray.length > 0) handlers += '\n' + rtrnArray.join('\n');

	/* Bind handlers back to object's event*/
	obj["on" + event_name] = new Function("evt", handlers);
	return true;
} //eof _bindEvent

function _unbindEvent(obj, eventName, fnc) {
	if (obj["on" + eventName] != null)
		var eventHandler = obj["on" + eventName].toString();
	else
		return false;

	var eventListeners = _removeWrapper(eventHandler, eventName);

	/* Get call line for fx being removed */
	fnc = fnc.toString();

	var fx_name = fnc.match(/function ([\w$])*\s*\([\w]*\)\s*\{?/)[1];
	var re = new RegExp(fx_name);

	/* split event listeners into array & create array for kept listeners */
	var fxArray = eventListeners.match(/[^;]+;\s*/g);
	var newArray = new Array();

	/* Copy listeners being retained to newArray skipping one being deleted*/
	var looking = true;   //so only one entry is removed
	fxArray.reverse();    //take last entry first
	for (var i = 0; i < fxArray.length; i++) {
		if (looking && re.test(fxArray[i]))
			looking = false;
		else
			newArray[newArray.length] = fxArray[i].replace(/^\s*|\s*$/g, '');
	}

	/* Bind kept event listeners to event */
	if (!looking) {
		if (newArray.length > 0) {
			newArray.reverse(); //Back to original order
			eventListeners = newArray.join('\n');
			obj["on" + eventName] = new Function("evt", eventListeners);
		}
		else {
			obj["on" + eventName] = null;
		}
	}
	return !looking;
} //eof _unbindEvent

function _removeWrapper(eventHdlrStr, eName) {
	/* Remove handler wrapper for function calls using RegExp*/
	var re1 = /^\s*function anonymous\([\w]*\)\s*\{\s*/;
	var re2 = new RegExp("function on" + eName + "\\(\\w*\\)\\s*\\{");
	var re3 = /^\s*function\s+\(\w*\)\s*\{\s*/;

	/* Remove handlerr wrapper */
	if (re1.test(eventHdlrStr))
		eventHdlrStr = eventHdlrStr.replace(re1, "");        //remove anonymous fx declaration IE and this
	else if (re2.test(eventHdlrStr))
		eventHdlrStr = eventHdlrStr.replace(re2, "");        //remove onevent fx declaration Mozilla
	else if (re3.test(eventHdlrStr))
		eventHdlrStr = eventHdlrStr.replace(re3, "");        //remove KHTML anonymous (no name);
	else {
		var addReturn = /return \w+/.test(eventHdlrStr);
		eventHdlrStr.match(/function ([\w$]*\s*\([\w]*\))\s*\{?/);
		eventHdlrStr = ((addReturn) ? "return " : "") + RegExp.$1 + ';';
	}

	eventHdlrStr = eventHdlrStr.replace(/\s*\}\s*$/, '');    //remove closing brace

	/* Cleanup remaining function calls */
	eventHdlrStr = eventHdlrStr.replace(/^\s*|\s*$/g, '');     //all trim
	eventHdlrStr = eventHdlrStr.replace(/\s+/g, ' ');          //Replace multiple white spaces with one space
	eventHdlrStr = eventHdlrStr.replace(/\bevent\b/g, 'evt');  //replace key word event with local evt
	if (!/;$/.test(eventHdlrStr)) { eventHdlrStr += ";"; }      //add closing semicolon

	/* create array of function calls based on semicolon */
	var handlerArray = eventHdlrStr.match(/[^;]+;\s*/g);

	/* trim each function call */
	if (handlerArray) {
		for (var i = 0; handlerArray && i < handlerArray.length; i++) {
			handlerArray[i] = handlerArray[i].replace(/^\s*|\s*$/g, '');
		}
		return handlerArray.join('\n');
	}
	else {
		return '';
	}
} //eof _removeWrapper


// enable the datepicker controls when the combobox value is enableitem, 
// otherwise disable controls
function TaskRangeComboBoxInit(comboboxId, enableItem,
text1, button1, text2, button2) {
    var combobox = document.getElementById(comboboxId);
    if (!combobox) return false;
    
    document.getElementById(text1).disabled =
    document.getElementById(text2).disabled =
    document.getElementById(button1).disabled =
    document.getElementById(button2).disabled =
    (combobox.value != enableItem);

    // set period

    if (combobox.value != enableItem) {

        var Today = new Date().getDateOnly();
        var From = Today;
              
        document.getElementById(text2).value = Today.format("dd.MM.yyyy");
   
        if (combobox.value == "last_month") {
            From.setMonth(From.getMonth() - 1);
        }

        if (combobox.value == "last_half_year") {
            From.setMonth(From.getMonth() - 6);
        }

        if (combobox.value == "last_year") {
            From.setMonth(From.getMonth() - 12);
        }
        
        document.getElementById(text1).value = From.format("dd.MM.yyyy");
    }

    return false;
}

function ValidateTaskExportRange(startTextId, startRequeredValidatorId, startExpressionValidatorId,
                                 endTextId, endRequeredValidatorId, endExpressionValidatorId,
                                 orderDateTextValidatorId) {
    var valid = true;
    re = /^(((((0[1-9])|(1\d)|(2[0-8])).((0[1-9])|(1[0-2])))|((31.((0[13578])|(1[02])))|((29|30).((0[1,3-9])|(1[0-2]))))).((20[0-9][0-9]))|((((0[1-9])|(1\d)|(2[0-8])).((0[1-9])|(1[0-2])))|((31.((0[13578])|(1[02])))|((29|30).((0[1,3-9])|(1[0-2]))))).((19[0-9][0-9]))|(29.02.20(([02468][048])|([13579][26])))|(29.02.19(([02468][048])|([13579][26]))))$/;

    //validate start date
    startText = document.getElementById(startTextId);
    startRequeredValidator = document.getElementById(startRequeredValidatorId);
    startExpressionValidator = document.getElementById(startExpressionValidatorId);

    startRequeredValidator.style["display"] = "none";
    startExpressionValidator.style["display"] = "none";

    if (startText.value == null || startText.value == "") {
        startRequeredValidator.style["display"] = "inline";
        valid = false;
    } else if (!re.test(startText.value)) {
        startExpressionValidator.style["display"] = "inline";
        valid = false;
    }

    //validate end date

    endText = document.getElementById(endTextId);
    endRequeredValidator = document.getElementById(endRequeredValidatorId);
    endExpressionValidator = document.getElementById(endExpressionValidatorId);
    orderDateTextValidator = document.getElementById(orderDateTextValidatorId);

    endRequeredValidator.style["display"] = "none";
    endExpressionValidator.style["display"] = "none";
    orderDateTextValidator.style["display"] = "none";

    if (endText.value == null || endText.value == "") {
        endRequeredValidator.style["display"] = "inline";
        valid = false;
    } else if (!re.test(endText.value)) {
        endExpressionValidator.style["display"] = "inline";
        valid = false;
    }

    // validate date order
    if (valid) {
        var startDate = new Date(startText.value.replace(/^([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{2,4})$/, "$2/$1/$3"));
        var endDate = new Date(endText.value.replace(/^([0-9]{1,2}).([0-9]{1,2}).([0-9]{2,4})$/, "$2/$1/$3"));
        if (startDate > endDate) {
            orderDateTextValidator.style["display"] = "inline";
            valid = false;
        }
    }

    if (!valid) return false;
}

/* Autocompliting in Sale inline form ***********/

// Following functions autocomplite fields in Sale inline form
// on Sum changing Discounted Sum and Paid Sum will be updated if they have empty or autocompleted values
// on Discounted Sum changing Paid Sum will be updated if it has empty or autocompleted value

function SaleSum_onchange(sender, discountedId, paidId) {
    var discounted = document.getElementById(discountedId);
    if (ParseDecimalOrCurrency(false, discounted.value) == 0 || discounted.autocomplited) {
        discounted.value = DecimalToCurrency(sender.value, 2, false);
        discounted.autocomplited = true;
        if (!discounted.className.match(/autocompleted/)) {
            discounted.className += " autocompleted";
        }
    
        var paid = document.getElementById(paidId);
        if (ParseDecimalOrCurrency(false,paid.value) == 0 || paid.autocomplited) {
            paid.value = DecimalToCurrency(sender.value);
            paid.autocomplited = true;
            if (!paid.className.match(/autocompleted/)) {
                paid.className += " autocompleted";
            }
        }
    }
}

function SaleDiscount_onchange(sender, paidId) {
    var paid = document.getElementById(paidId);
    if (ParseDecimalOrCurrency(false, paid.value) == 0 || paid.autocomplited) {
        paid.value = DecimalToCurrency(sender.value);
        paid.autocomplited = true;
        if (!paid.className.match(/autocompleted/)) {
            paid.className += " autocompleted";
        }
    }

    sender.autocomplited = false;
    sender.className = sender.className.replace(/ autocompleted/, "");
}

function SalePaid_onchange(sender) {
    sender.autocomplited = false;
    sender.className = sender.className.replace(/ autocompleted/, "");
}

/* End Autocompliting in Sale inline form ********/

/* Make Order *****************/

function MakeOrderSum_onchange(focuced, paidId, section1Id, section2Id, discountId, deliveryPaymentId) {
    var paid = document.getElementById(paidId);
    var section1 = document.getElementById(section1Id);
    var section2 = document.getElementById(section2Id);
    var discount = document.getElementById(discountId);
    var deliveryPayment = document.getElementById(deliveryPaymentId);
    if (paid && section1 && section2 && discount && deliveryPayment) {
        var discountValue = discount.value.replace(/[%]/g, '');
        paid.value = 0 +
            ParseDecimalOrCurrency((focuced.id == section1Id), section1.value) * (1 -
            (parseFloat(discountValue) && parseFloat(discountValue)<=100 ? parseFloat(discountValue) : 0) / 100) +
            ParseDecimalOrCurrency((focuced.id == section2Id), section2.value) +
            ParseDecimalOrCurrency((focuced.id == deliveryPaymentId), deliveryPayment.value);
        paid.value = DecimalToCurrency(Math.round(paid.value * 100) / 100,2, false);
    }
}

function MakeOrderSum_onchangeDiscount(paidId, section1Id, section2Id, discountId, deliveryPaymentId, validatorId) {
    MakeOrderSum_onchange(discountId, paidId, section1Id, section2Id, discountId, deliveryPaymentId);
    if (document.getElementById(validatorId) && document.getElementById(validatorId).isvalid)
        FormatePercentValue(discountId);
}


function ParseDecimalOrCurrency(isFocuced, value) {
    var valueDecimal;
    
    if (isFocuced) { valueDecimal = value; }
    else { valueDecimal = CurrencyToDecimal(value); }
    
    return parseFloat(DecimalToAppLocale(valueDecimal)) ? parseFloat(DecimalToAppLocale(valueDecimal)) : 0;
}

/* end Make Order ************/

function FormatePercentValue(controlId) {
    var control = document.getElementById(controlId);
    var discountValue = control.value.replace(/[%]/g, '');
    if (control) {
        control.value = ((discountValue == '') ? '0' : discountValue) + '%';
    }
}

function Trim(str){return (str.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""))}

function EndWith(str, endstr) { return (str.match(endstr + "$") == endstr) }


function TaskClientDdlOnChange(sender, panelId, text, validators) {
    if (sender.selectedIndex && sender[sender.selectedIndex].value == text) {
        MO.ShowPanel(panelId);
        sender.panelOpened = true; 
    }
    else if (sender.panelOpened) {
        MO.HidePanel(panelId);
        sender.panelOpened = false;
    }

    if (validators == null) return;

    for (var i = 0; i < validators.length; i++) {
        var validator = validators[i] ? document.getElementById(validators[i]) : null;
        if (validator != null) {
            if (sender.panelOpened)
                validator.enabled = true;
            else 
                ValidatorEnable(validator, false);
        }
    }
}

function FinOperationExpandClick(sender, panelId, expandImgUrl, collapseImgUrl) {
    if (!sender.panelOpened) {
        MO.ShowPanel(panelId);
        sender.panelOpened = true;
        sender.src = collapseImgUrl;
    }
    else if (sender.panelOpened) {
        MO.HidePanel(panelId);
        sender.panelOpened = false;
        sender.src = expandImgUrl;
    }
}


var availible = true;
function EnsureNumeric(e) {

    var k;
    var evt = (e) ? e : window.event;       //IE reports window.event not arg

    if (evt.type == "keydown") {
        k = evt.keyCode;
        if (k < 16 ||                 // non printables
            (k > 32 && k < 41) ||     // navigation keys
            (k > 47 && k < 58 && !evt.shiftKey) ||         //numbers
            (k > 95 && k < 106) ||      // numpad numbers
            k == 46 || k == 8)
            availible = true;
        else
            availible = false;
    } else {                                // This is keypress
        if (availible) return;              //Number or special key
        k = (evt.charCode) ?
                   evt.charCode : evt.keyCode;
        if (!isKeyAvailible(k)) {
            if (evt.preventDefault)
            { evt.preventDefault(); }
            else
            { window.event.returnValue = false; }
        }

    }
}

function EnsurePercent(e) {

    var k;
    var evt = (e) ? e : window.event;       //IE reports window.event not arg

    if (evt.type == "keydown") {
        k = evt.keyCode;
        if (k < 16 ||                 // non printables
            (k > 32 && k < 41) ||     // navigation keys
            (k > 47 && k < 58 && !evt.shiftKey) ||         //numbers
            (k == 53 && evt.shiftKey) || //%
            (k > 95 && k < 106) ||      // numpad numbers
            k == 46 || k == 8)
            availible = true;
        else
            availible = false;
    } else {                              // This is keypress
        if (availible) return;              //Number or special key
        k = (evt.charCode) ?
                   evt.charCode : evt.keyCode;
        if (!availible) {
            if (evt.preventDefault)
            { evt.preventDefault(); }
            else
            { window.event.returnValue = false; }
        }

    }
}

function Select(control) {
    if (control) {
        control.select();
    }
}



