var __DK_CurrentCallBack = null;

function __DK_DoCallBack(eventTarget, eventArgument, updateTarget, validation, validationGroup, updateState, preCallback, postCallback, errorCallback)
{
    if (validation)
    {
        if (typeof(Page_ClientValidate) == 'function')
        {
            if (!Page_ClientValidate(validationGroup))
                return false;
        }
    }
    __DK_CallBack_Execute(eventTarget, eventArgument, updateTarget, null, updateState, preCallback, postCallback, errorCallback);
}

function __DK_CallBack_Execute(eventTarget, eventArgument, updateTarget, context, updateState, preCallback, postCallback, errorCallback)
{
    var e;
    try
    {
        if (__DK_CurrentCallBack != null)
        {
            return false;
        }
        else
        {
            __DK_CurrentCallBack = new Object();
        }
        __DK_CurrentCallBack.preCallback = preCallback;
        __DK_CurrentCallBack.postCallback = postCallback;
        __DK_CurrentCallBack.errorCallback = errorCallback;
        __DK_CurrentCallBack.context = context;
        var postData = __DK_CallBack_GetPostData(eventTarget, eventArgument, updateTarget, updateState);
        var xmlRequest = __DK_CallBack_GetXMLRequest();
        __DK_CurrentCallBack.xmlRequest = xmlRequest;
        xmlRequest.onreadystatechange = __DK_CallBack_Complete;
        xmlRequest.open("POST", theForm.action, true);
        xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        if ((typeof(__DK_CurrentCallBack.preCallback) == "function") && (__DK_CurrentCallBack.preCallback != null))
        {
            __DK_CurrentCallBack.preCallback();
        }
        xmlRequest.send(postData);
    }
    catch(e)
    {
        __DK_CallBack_Error(e.message);
    }
}

function __DK_CallBack_Error(description)
{
    var errorCallbackFunction;
    if (__DK_CurrentCallBack && __DK_CurrentCallBack.errorCallback)
    {
        errorCallbackFunction = __DK_CurrentCallBack.errorCallback;
    }
    __DK_CurrentCallBack = null;
    if ((typeof(errorCallbackFunction) == "function") && (errorCallbackFunction != null))
    {
        errorCallbackFunction(description);
        return;
    }
    var error = "Call back operation failed.";
    if (description && (description != ""))
    {
        error += "\n" + description;
    }
    alert(error);
}

function __DK_CallBack_Complete()
{
    var e;
    try
    {
        if (__DK_CurrentCallBack && __DK_CurrentCallBack.xmlRequest && (__DK_CurrentCallBack.xmlRequest.readyState == 4))
        {
            var result = __DK_CallBack_ParseResult(__DK_CurrentCallBack.xmlRequest.responseText);
            if (result.status == "error")
            {
                __DK_CallBack_Error(result.errorDescription);
                return;
            }
            if (theForm.__VIEWSTATE && (result.viewState != "")) theForm.__VIEWSTATE.value = result.viewState;
            if (theForm.__VIEWSTATEENCRYPTED && (result.viewStateEncrypted != "")) theForm.__VIEWSTATEENCRYPTED.value = result.viewStateEncrypted;
            if (theForm.__EVENTVALIDATION && (result.eventValidation != "")) theForm.__EVENTVALIDATION.value = result.eventValidation;
            for (var controlID in result.controls)
            {
                if (document.getElementById(controlID))
                {
                    document.getElementById(controlID).innerHTML = result.controls[controlID];
                }
            }
            if ((typeof(__DK_CurrentCallBack.postCallback) == "function") && (__DK_CurrentCallBack.postCallback != null))
            {
                __DK_CurrentCallBack.postCallback(result, __DK_CurrentCallBack.context);
            }
            __DK_CurrentCallBack = null;
        }
    }
    catch (e)
    {
        __DK_CallBack_Error(e.message);
    }
}

function __DK_CallBack_ParseResult(resultText)
{
    var result = new Object();
    resultText = resultText.split("|");
    if (resultText[0] == "s")
    {
        result.status = "success";
        result.viewState = __DK_CallBack_Decode(resultText[1]);
        result.viewStateEncrypted = __DK_CallBack_Decode(resultText[2]);
        result.eventValidation = __DK_CallBack_Decode(resultText[3]);
        result.controls = new Object();
        for (var i = 4; i < resultText.length; i++)
        {
            if (i % 2 == 0)
            {
                result.controls[__DK_CallBack_Decode(resultText[i])] = __DK_CallBack_Decode(resultText[i + 1]);
            }
        }
    }
    else
    {
        result.status = "error";
        result.errorDescription = "";
        if (resultText.length > 1)
        {
            result.errorDescription = __DK_CallBack_Decode(resultText[1]);
        }
    }
    return result;
}

function __DK_CallBack_GetXMLRequest()
{
    var xmlRequest, e;
    try
    {
        xmlRequest = new XMLHttpRequest();
    }
    catch(e)
    {
        try
        {
            xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(e)
        {
            xmlRequest = null;
        }
    }
    return xmlRequest;
}

function __DK_CallBack_GetPostData(eventTarget, eventArgument, updateTarget, updateState)
{
    theForm.__EVENTTARGET.value = eventTarget;
    theForm.__EVENTARGUMENT.value = eventArgument;
    var postData = "";
    var element;
    var count = theForm.elements.length;
    for (var i = 0; i < count; i++)
    {
        element = theForm.elements[i];
        var tagName = element.tagName.toLowerCase();
        if (tagName == "input")
        {
            var type = element.type;
            if ((type == "text" || type == "hidden" || type == "password" ||
                ((type == "checkbox" || type == "radio") && element.checked)))
            {
                postData += __DK_CallBack_GetPostDataField(element.name, element.value);
            }
        }
        else if (tagName == "select")
        {
            var selectCount = element.options.length;
            for (var j = 0; j < selectCount; j++)
            {
                var selectChild = element.options[j];
                if (selectChild.selected == true)
                {
                    postData += __DK_CallBack_GetPostDataField(element.name, element.value);
                }
            }
        }
        else if (tagName == "textarea")
        {
            postData += __DK_CallBack_GetPostDataField(element.name, element.value);
        }
    }
    theForm.__EVENTTARGET.value = "";
    theForm.__EVENTARGUMENT.value = "";
    postData += "__DIGIKNOWCALLBACK=1";
    postData += "&__DIGIKNOWCALLBACK_UPDATETARGET=" + updateTarget;
    if (updateState)
    {
        postData += "&__DIGIKNOWCALLBACK_UPDATESTATE=1";
    }
    return postData;
}

function __DK_CallBack_GetPostDataField(name, value)
{
    return (name + "=" + __DK_CallBack_Encode(value) + "&");
}

function __DK_CallBack_Encode(parameter)
{
    if (window.encodeURIComponent)
    {
        return window.encodeURIComponent(parameter);
    }
    else
    {
        return __DK_CallBack_encodeURIComponent(parameter);
    }
}

function __DK_CallBack_Decode(parameter)
{
    if (window.decodeURIComponent)
    {
        return window.decodeURIComponent(parameter);
    }
    else
    {
        return __DK_CallBack_decodeURIComponent(parameter);
    }
}

function __DK_CallBack_encodeURIComponent(s)
{
    var hexchars = "0123456789ABCDEF";
    var okURIchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
    var c;
    var enc = "";
    s = __DK_CallBack_UTF8(s);
    for (var i= 0; i<s.length; i++)
    {
        if (okURIchars.indexOf(s.charAt(i)) == -1)
        {
            c = s.charCodeAt(i);
            c = hexchars.charAt(c >> 4) + hexchars.charAt(c & 0xF);
            enc += "%" + c;
        }
        else
        {
            enc += s.charAt(i);
        }
    }
    return enc;
}

function __DK_CallBack_decodeURIComponent(s)
{
    var sbuf = "";
    var l  = s.length;
    var ch = -1 ;
    var b, sumb = 0;
    for (var i = 0, more = -1 ; i < l ; i++) {
        switch (ch = s.charAt(i))
        {
            case "%":
                ch = s.charAt (++i);
                ch += s.charAt (++i);
                b = parseInt(ch, 16);
                break ;
            case "+":
                b = " ";
                break ;
            default:
                b = ch.charCodeAt(0);
        }
        if ((b & 0xc0) == 0x80)
        {
            sumb = (sumb << 6) | (b & 0x3f);
            if (--more == 0) sbuf += String.fromCharCode(sumb);
        }
        else if ((b & 0x80) == 0x00)
        {
	        sbuf += String.fromCharCode(b);
        }
        else if ((b & 0xe0) == 0xc0)
        {
	        sumb = b & 0x1f;
	        more = 1;
        }
        else if ((b & 0xf0) == 0xe0)
        {
	        sumb = b & 0x0f;
	        more = 2;
        }
        else if ((b & 0xf8) == 0xf0)
        {
	        sumb = b & 0x07;
	        more = 3;
        }
        else if ((b & 0xfc) == 0xf8)
        {
	        sumb = b & 0x03;
	        more = 4;
        } 
        else
        {
	        sumb = b & 0x01;
	        more = 5;
        }
    }
    return sbuf;
}

function __DK_CallBack_UTF8(wide)
{
    var c, s;
    var enc = "";
    var i = 0;
    while (i < wide.length)
    {
        c = wide.charCodeAt(i++);
        if (c >= 0xDC00 && c < 0xE000) continue;
        if (c >= 0xD800 && c < 0xDC00)
        {
            if (i >= wide.length) continue;
            s = wide.charCodeAt(i++);
            if (s<0xDC00 || c>=0xDE00) continue;
            c = ((c-0xD800)<<10)+(s-0xDC00)+0x10000;
        }
        if (c<0x80) enc += String.fromCharCode(c);
        else if (c<0x800) enc += String.fromCharCode(0xC0+(c>>6),0x80+(c&0x3F));
        else if (c<0x10000) enc += String.fromCharCode(0xE0+(c>>12),0x80+(c>>6&0x3F),0x80+(c&0x3F));
        else enc += String.fromCharCode(0xF0+(c>>18),0x80+(c>>12&0x3F),0x80+(c>>6&0x3F),0x80+(c&0x3F));
    }
    return enc;
}