﻿/// <reference path="jquery.js" />
/// <reference path="jquery-plugins.js" />


CalendarViewType =
{
    Unknown: 0,
    Event: 1 << 1,
    ToDo: 1 << 2,
    Journal: 1 << 3,
    Invoice: 1 << 4,
    Project: 1 << 5,
    Support_Case: 1 << 6,
    Disbursement: 1 << 7,
    Notation: 1 << 8,
    Message: 1 << 9,
    Subscription: 1 << 10,
    Product: 1 << 11,
    Document: 1 << 12
};

EntryFlags =
{
    None: 0, // WSDL support
    Billable: 1 << 0,
    Invoiced: 1 << 1,
    Journal: 1 << 2,
    Canceled: 1 << 3,
    Project: 1 << 4,
    Calendar_Item: 1 << 5,
    Event: 1 << 6,
    ToDo: 1 << 7,
    Support_Case: 1 << 8,
    Product: 1 << 9,
    Subscription: 1 << 10,
    Notifications_Sent: 1 << 11,
    Disbursement: 1 << 12,
    Client_Access: 1 << 13,
    QuoteOnly: 1 << 14,
    Track_Supplier_Payments: 1 << 15,
    All_Employees: 1 << 16,
    Project_Milestone: 1 << 17,
    Never_Invoice: 1 << 18,
    Inactive: 1 << 19,
    IsTemplate: 1 << 20,
    Pending: 1 << 21
};

EntityFlags =
{
    /// <summary>
    /// Denotes that the entity should be included in the Sales Pipeline
    /// </summary>
    Sales_Lead: 1 << 1,
    /// <summary>
    /// Denotes that this entity can be billed as a customer
    /// </summary>
    Customer: 1 << 2,
    /// <summary>
    /// Denotes that this entity acts as a supplier
    /// </summary>
    Supplier: 1 << 3,
    /// <summary>
    /// Denotes that this entity subscribes to Mailing Lists
    /// </summary>
    Subscriber: 1 << 4,
    /// <summary>
    /// Denotes that this entity type is a Company or Business
    /// </summary>
    Company: 1 << 5,
    /// <summary>
    /// Denotes that this entity is of type a Person
    /// </summary>
    Person: 1 << 6,
    /// <summary>
    /// Denotes that this entity is an Employee
    /// </summary>
    Employee: 1 << 7,
    /// <summary>
    /// Denotes that this entity belongs to an Employee Next Of Kin
    /// </summary>
    //NextOfKin: 1 << 8,
    /// <summary>
    /// Denotes that the entity should be excluded from Veetro entity selection listings
    /// </summary>
    Inactive: 1 << 9,
    /// <summary>
    /// When present, the person will receive e-mail notifications each time a Entry is modified.
    /// </summary>
    Enable_Entry_Alerts: 1 << 10,
    /// <summary>
    /// When present, the Person cannot log in
    /// </summary>
    Disable_Login: 1 << 11
};


// Url watch works like this:
// /whateverpath#Key1/Val1/Key2/Val2/CellSize/20
var UrlWatch = {
    _ChangeDelegates: [],
    _ChangeDelegateContexts: [],
    _LastUrlHash: null,
    _FirstParse: true,

    // Subscribe to a #anchor url change
    OnChanged: function (code, context) {
        this._ChangeDelegates.push(code);
        this._ChangeDelegateContexts.push(context);
    },
    // Extract a value from the anchor
    GetValueOrDefault: function (key, def) {
        var r = this.Get(key);
        return r ? r : def;
    },
    // modifies the anchor by changing the desired key
    Set: function (key, value) 
    {
        var args = (document.location.hash.startsWith('#') ? document.location.hash.substring(1) : document.location.hash).split('/');
        var s = new StringBuilder();
        s.Append('#');

        var exists = false;
        for (var i = 0; i < args.length; i += 2) {
            if (i + 1 >= args.length)
                break;
            if (args[i].toLowerCase() == key.toLowerCase()) {
                args[i + 1] = value;
                exists = true;
            }
            if (s.Buffer.length > 1)
                s.Append('/');
            s.Append(args[i]);
            s.Append('/');
            s.Append(args[i + 1]);
        }
        if (!exists) {
            if (s.Buffer.length > 1)
                s.Append('/');
            s.Append(key);
            s.Append('/');
            s.Append(value);
        }
        document.location.hash = s.ToString();
    },
    Get: function (key, value) // get/set anchor hash
    {
        
        var args = (document.location.hash.startsWith('#') ? document.location.hash.substring(1) : document.location.hash).split('/');
        for (var i = 0; i < args.length; i += 2)
            if (args[i].toLowerCase() == key.toLowerCase()
                    && i + 1 < args.length)
                return args[i + 1];
        return null;

    }
};

setInterval(function () {
    if (UrlWatch._LastUrlHash != window.location.hash) {
        if (!UrlWatch._FirstParse) { // dont fire on initialisation
            for (var i = 0; i < UrlWatch._ChangeDelegates.length; i++)
                UrlWatch._ChangeDelegates[i].call(UrlWatch._ChangeDelegateContexts[i]);
        }
        UrlWatch._LastUrlHash = window.location.hash;
        UrlWatch._FirstParse = false;
    }
}, 200);


function $() {
    var elements = new Array();
    for (var i = 0; i < arguments.length; i++) {
        var element = arguments[i];
        if (typeof element == 'string')
            element = document.getElementById(element);

        if (arguments.length == 1)
            return element;

        elements.push(element);
    }
}

//
// Helper so I dont have to translate C#
//
function StringBuilder() {
    this.Buffer = [];
    this.Append = function (s) { this.Buffer.push(s); };
    this.ToString = function () { return this.Buffer.join(""); };
    this.toString = function () { return this.Buffer.join(""); };
}

DateTime = {
    MinValue: new Date(-62135582400000),
    MaxValue: new Date(253402300799999),
    IsEmpty: function (date) {
        return !date
        || date == this.MinValue
        || date == this.MaxValue
        || date.getFullYear() < 1990
        || date.getFullYear() > 3000;
    }
}

var ns4 = document.layers;
var op5 = (navigator.userAgent.indexOf("Opera 5") != -1)
|| (navigator.userAgent.indexOf("Opera/5") != -1);
var op6 = (navigator.userAgent.indexOf("Opera 6") != -1)
|| (navigator.userAgent.indexOf("Opera/6") != -1);
var agt = navigator.userAgent.toLowerCase();
var mac = (agt.indexOf("mac") != -1);
var ie = (agt.indexOf("msie") != -1);
var ie6 = ie && (agt.indexOf("6.") > -1 || agt.indexOf("5.") > -1);
var mac_ie = mac && ie;
var mouseX, mouseY;
var indexes = 100;
var UserInfo;
var LastBalloonPosX, LastBalloonPosY;
var JS_PLEASE_WAIT = "Please wait ... ";
var IsNavigatingAway;
var TO_SECS = 1000;
var TO_MINS = 60 * TO_SECS;
var TO_HOURS = 60 * TO_MINS;
var TO_DAYS = 24 * TO_HOURS;
var VeetroColorPallete =
{
    Top: "FFFFFF,000000,F6EAD2,1A3E72,527AAE,B84540,96B655,7F66A0,4AACC5,F59D56".split(','),
    Mid: ("D2D2D2,BABABA,9A9A9A,828282,727272," // grays
        + "727272,6A6A6A,4E4E4E,363636,1E1E1E,"
        + "B6ADA6,9A968D,726F6A,4E4A47,363231,"
        + "C2CEDA,869AB5,4E6B97,122E53,0C1E32,"
        + "D2DEF4,A6BAD5,7A9AC1,3C557E,26364F,"
        + "EECECF,DA9E9E,CA726E,86332F,55221E,"
        + "E1EED2,CADAAB,AFC67E,6B823E,425126,"
        + "DFD9E7,BFB2CE,9F8DB7,5F4C79,403351,"
        + "D3EAF2,A5D5E3,78C1D4,388096,255664,"
        + "FCE7D6,FACEAB,F7B680,B77640,7A4E2B").split(','),
    Bottom: "B20D11,E9161D,FFB90B,FFFF00,96D642,19AA41,02B2EE,0072BB,2D3799,6F3098".split(','),
    Open: function (onselect) {
        var s = new StringBuilder();
        s.Append('<div class="ColorPallette" style="border: 1px solid #D3D3D3;background-color:#FBFBFB;width:174px;position:absolute;z-index:10000;">');
        {
            // top row
            s.Append('<div style="margin:1px">');
            for (var i = 0; i < this.Top.length; i++)
                s.Append('<div style="background-color:#' + this.Top[i] + ';width: 11px; height: 11px; cursor: pointer;border:1px solid #cccccc;margin:2px;float:left;"><img src="/v2.0/images/space.gif" width=1 height=1/></div>');
            s.Append('</div>');
            // middle
            s.Append('<div style="margin:1px">');
            s.Append('<div style="float:left; width:11px;border:1px solid #808080;margin:2px;">');
            for (var i = 0; i < this.Mid.length; i++) {
                if ((i % 5) == 0 && i > 0)
                    s.Append('</div><div style=\"float:left; width:11px;border:1px solid #808080;margin:2px;\">');
                s.Append('<div style="background-color:#' + this.Mid[i] + ';width: 11px; height: 11px; cursor: pointer;"><img src="/v2.0/images/space.gif" width=1 height=1/></div>');
            }
            s.Append('</div>');
            s.Append('</div>');
            // standard
            s.Append('<div style="margin:1px;">');
            for (var i = 0; i < this.Bottom.length; i++)
                s.Append('<div style="background-color:#' + this.Bottom[i] + ';width: 11px; height: 11px; cursor: pointer;border:1px solid #cccccc;margin:2px;float:left;"><img src="/v2.0/images/space.gif" width=1 height=1/></div>');

            s.Append('</div>');
        }
        s.Append('</div>');
        $j(document.body).append(s.toString());
        var el = $j('.ColorPallette');
        el.bind('mouseleave', function () { $j(this).remove(); });
        el.bind('click', { delegate: onselect }, function (event) {
            var val = $j(event.target).css('background-color');

            if (val) {
                var rgb = val.substring(4).replace(')', '').split(',');
                var hex = '#';
                for (var i = 0; i < rgb.length; i++) {
                    var h = parseInt(rgb[i]).toString(16);
                    hex += (h.length == 1 ? '0' : '') + h;
                }
                event.data.delegate.call(this, hex);
                $j(this).remove();
            }
        });
        el.css({
            top: mouseY + 'px',
            left: mouseX + 'px'
        });
    }
}

function getMousePos(e)
{
if (!e)
var e = window.event || window.Event;

if (typeof e.pageX != 'undefined')
{
mouseX = e.pageX;
mouseY = e.pageY;
} else
{
if (document.body)
{
mouseX = e.clientX + GetScrollLeft();
mouseY = e.clientY + GetScrollTop();
}
}
}

function GetScrollTop()
{
var pos = 0;
if (window.pageYOffset)
{
pos = window.pageYOffset;
}
else if (document.documentElement && document.documentElement.scrollTop)
{
pos = document.documentElement.scrollTop;
}
else if (document.body)
{
pos = document.body.scrollTop;
}
return pos;
}

function GetScrollLeft()
{
var pos = 0;
if (window.pageXOffset)
{
pos = window.pageXOffset;
}
else if (document.documentElement && document.documentElement.scrollLeft)
{
pos = document.documentElement.scrollLeft;
}
else if (document.body)
{
pos = document.body.scrollLeft;
}
return pos;
}

// You need to tell Mozilla to start listening:
// document.captureEvents deprecated aparently?
//if(window.Event && document.captureEvents)
//	document.captureEvents(Event.MOUSEMOVE);
var BubbleRollOffTimeout;


function InitialiseAllTabs() {
    $j('.ui-tabs').tabs();
    $j('.ui-tabs').css('visibility', 'visible');

    $j('.ui-tabs > ul').each(function () {
        var ul = $j(this);
        var actualWidth = 0;
        var tabHeight = 0;
       
        ul.children('li').each(function () {
            var t = $j(this);
            actualWidth += t.outerWidth();
            if (tabHeight < t.outerHeight())
                tabHeight = t.outerHeight();
        });
        ul.css('width', actualWidth + 'px');
        var container = $j(ul.parent());
        if (container.hasClass('ui-tabs')) {
            // var b4 = ul.before('<div style="overflow:hidden" />');
            ul.wrap('<div style="overflow:hidden;position:relative;margin-bottom:-1px;" />');
            container = $j(ul.parent());
        }
        //container.css('overflow', 'hidden');
        ul.draggable("destroy");
        ul.css('position', 'absolute');
        if (actualWidth > container.width()) {
            var x = container.offset().left - actualWidth;
            var x2 = x + actualWidth + 10;
            ul.css('cursor', 'w-resize');

            //container.css('paddingTop', tabHeight + 'px');
            container.css('height', (tabHeight + 3) + 'px');
            //ul.css('marginTop', (-tabHeight - 1) + 'px');
            ul.draggable({ axis: 'x', containment: [x + container.width(), 0, x2, container.height()] });

            ul.children('li').css('cursor', 'w-resize');
            ul.children('li').children('a').css('cursor', 'w-resize');
        }
        else {
            ul.css('position', 'relative');
            ul.css('left', 0);
            ul.css('cursor', 'inherit');
            ul.children('li').css('cursor', 'inherit');
            ul.children('li').children('a').css('cursor', 'pointer');
        }

      
    });

   
}

function GetModuleHeight()
{
var winH = window.innerHeight ? window.innerHeight : document.documentElement.offsetHeight;
//var h = winH - (PosY($('ModuleHolderTable')) + GetHeight($('Footer')));
var h = winH - (PosY($('ModuleHolderTable')) - GetHeight($('ctl00_Footer')));
return h > 1 ? h : 1;
}

function PosX(obj)
{
    var curleft = 0;
    if (obj.offsetParent) {
        while (obj) {
            curleft += obj.offsetLeft
            obj = obj.offsetParent;
        }
    }
    else if (obj.x)
    {
        curleft += obj.x;
    }
    return curleft;
}

function PosY(obj)
{
    var curtop = 0;
    if (obj.offsetParent) {
       
        while (obj) {
            curtop += obj.offsetTop
            obj = obj.offsetParent;
        }
    }
    else if (obj.y)
    {
        curtop += obj.y;
    }
    return curtop;
}

function DescriptiveTextBoxOnLeave(sender, description)
{
    if (sender.value == null || sender.value.length == 0)
    {
        sender.value = description;
        sender.className = sender.className + ' EmptyTextBox';
    }
    else
    {
        RemoveEmptyTextBoxClass(sender);
    }
}
function DescriptiveTextBoxOnEnter(sender, description)
{
    if (sender.value == description)
    {
        sender.value = '';
    }
    RemoveEmptyTextBoxClass(sender);
}
function RemoveEmptyTextBoxClass(sender)
{
    if (sender.className)
        sender.className = sender.className.replace(/EmptyTextBox/g, '');
}
function GetDescriptiveTextBoxValue(ClientID, description)
{
    if ($(ClientID).value == description)
        return '';
    else
        return $(ClientID).value;
}
function getObjNN4(obj, name)
{
    var x = obj.layers;
    var foundLayer;
    for (var i = 0; i < x.length; i++)
    {
        if (x[i].id == name)
            foundLayer = x[i];
        else if (x[i].layers.length)
            var tmp = getObjNN4(x[i], name);
        if (tmp) foundLayer = tmp;
    }
    return foundLayer;
}
function GetHeight(elem)
{
    if (ns4)
    {
        xPos = elem.clip.height;
    }
    else if (op5)
    {
        xPos = elem.style.pixelHeight;
    }
    else
    {
        xPos = elem.offsetHeight;
    }
    return xPos;
}

function GetWidth(elem)
{
    if (ns4)
    {
        xPos = elem.clip.width;
    }
    else if (op5)
    {
        xPos = elem.style.pixelWidth;
    }
    else
    {
        xPos = elem.offsetWidth;
    }
    return xPos;
}

function IsMouseOver(id)
{
    var obj = $(id);
    if (!obj)
        return false;
        
//    var bounds = new Object();
//    bounds.Left = PosX(obj);
//    bounds.Right =  bounds.Left + GetWidth(obj);
//    bounds.Top = PosY(obj);
//    bounds.Bottom =  bounds.Top + GetHeight(obj);
//    alert(bounds.Left+" "+bounds.Right+" "+bounds.Top+" "+bounds.Bottom);
    return (mouseX >= PosX(obj)
            && mouseX <= PosX(obj)+GetWidth(obj)
            && mouseY >= PosY(obj)
            && mouseY <= PosY(obj)+GetHeight(obj));
}

var maxSteps = 10;
function __Toggle(id, div)
{




    var newView = $(id).style.display == "none" ? "block" : "none";

    if (div)
    {
        if (newView == "block")
            div.className = div.className.replace('ExpandPanelUp', 'ExpandPanelDown');
        else
            div.className = div.className.replace('ExpandPanelDown', 'ExpandPanelUp')

    }
    if ($(id + "_state"))
        $(id + "_state").value = newView == "block" ? "1" : "0";

    var originalPosition = $(id).style.position;
    $(id).style.display = "block";
    var originalSize = GetHeight($(id));
    $(id).style.display = "none";
    //$(id).style.position = "absolute";
    $(id).style.overflow = "hidden";

    if (newView == "block")
    {
        $(id).style.height = "0px";
        $(id).style.display = "block";
        OnAnimTimer(id, 0, newView, originalSize, originalPosition);

    }
    else
    {

        $(id).style.display = "block";
        OnAnimTimer(id, 0, newView, originalSize, originalPosition);
    }
}

function OnAnimTimer(id, step, view, originalSize, originalPosition)
{
    var end = view == "block" ? originalSize : 0;
    var start = view == "block" ? 0 : originalSize;
    var height = EaseInOut(start, end, maxSteps, step, 1);

    if (step == maxSteps)
    {
        if (view == "block")
        {
            $(id).style.height = null;
        }
        else
        {
            $(id).style.display = 'none';
        }
        $(id).style.position = originalPosition;
    }
    else
    {
        if ($(id))
        {
            $(id).style.height = height + 'px';
            setTimeout("OnAnimTimer('" + id + "', " + (step + 1).toString() + ", '" + view + "', " + originalSize + ", '" + originalPosition + "');", 10);
        }
    }
}
function EaseInOut(minValue, maxValue, totalSteps, actualStep, powr)
{
    //Generic Animation Step Value Generator By www.hesido.com
    totalSteps = Math.max(totalSteps, 1)
    var delta = maxValue - minValue;
    var stepp = minValue + (Math.pow(((1 / totalSteps) * actualStep), powr) * delta);
    return Math.ceil(stepp)
}

function DisableSelection(element)
{
    element.onselectstart = function()
    {
        return false;
    };
    element.unselectable = "on";
    element.style.MozUserSelect = "none";
    element.style.cursor = "default";
}
function EnableSelection(element)
{
    element.onselectstart = null;
    element.unselectable = "";
    element.style.MozUserSelect = "";
    element.style.cursor = "default";
}
function FormatDateUTC(d, forUrl)
{
    var minuteSep = forUrl ? '.' : ':';

    if (d.getHours() > 0 || d.getMinutes() > 0 || d.getSeconds() > 0 || forUrl) // only convert when there's time of some sort
        return d.getUTCFullYear().toString() + '-' + (d.getUTCMonth() + 1).toString() + '-' + d.getUTCDate().toString() + ' ' + d.getUTCHours().toString() + minuteSep + d.getUTCMinutes().toString() + minuteSep + d.getUTCSeconds().toString();
    else
        return d.getFullYear().toString() + '-' + (d.getMonth() + 1).toString() + '-' + d.getDate().toString();
}


function PadZero(num)
{
    return (num < 10) ? '0' + num : num;
}
function RdNthEtc(number)
{
    var num = number.toString();
    var txt = num;

    var lastChar = num.charAt(num.length - 1);

    if (lastChar == "1" && (number < 10 || number > 19))
        txt += ("st ");
    else if (lastChar == "2" && (number < 10 || number > 19))
        txt += ("nd ");
    else if (lastChar == "3" && (number < 10 || number > 19))
        txt += ("rd ");
    else if ((lastChar == "4" ||
        lastChar == "5" ||
        lastChar == "6" ||
        lastChar == "7" ||
        lastChar == "8" ||
        lastChar == "9" ||
        lastChar == "0" ||
        (number > 10 && number < 19)
        ) && number > 3)

        txt += ("th ");
    return txt;
}
function FormatDate(date, format)
{

    if (!amDesignator) // no am/pm in locale
    {
        format = format.replace(/\s?tt/g, '');
        format = format.replace(/h/g, 'H');
    }

    var sTmp = format;
    sTmp = sTmp.replace(/Dth/g, "<~>"); // th rd nd etc
    sTmp = sTmp.replace(/dddd/g, "<!!!!>");
    sTmp = sTmp.replace(/ddd/g, "<!!!>");
    sTmp = sTmp.replace(/dd/g, "<!!>");
    sTmp = sTmp.replace(/d/g, "<!>");
    sTmp = sTmp.replace(/yyyy/gi, "<****>");
    sTmp = sTmp.replace(/yy/gi, "<**>");
    sTmp = sTmp.replace(/MMMM/g, "<@@@@>");
    sTmp = sTmp.replace(/MMM/g, "<@@@>");
    sTmp = sTmp.replace(/MM/g, "<@@>");
    sTmp = sTmp.replace(/M/g, "<@>");
    sTmp = sTmp.replace(/mm/g, "<##>");
    sTmp = sTmp.replace(/m/g, "<#>");
    sTmp = sTmp.replace(/HH/g, "<||>");
    sTmp = sTmp.replace(/H/g, "<|>");
    sTmp = sTmp.replace(/hh/g, "<^^>");
    sTmp = sTmp.replace(/h/g, "<^>");
    sTmp = sTmp.replace(/ss/g, "<((>");
    sTmp = sTmp.replace(/s/g, "<(>");
    sTmp = sTmp.replace(/tt/gi, "<&>");

    sTmp = sTmp.replace("<~>", RdNthEtc(date.getDate()).trim());
    sTmp = sTmp.replace("<!!!!>", fullDayNames[date.getDay()]);
    sTmp = sTmp.replace("<!!!>", shortDayNames[date.getDay()]);
    sTmp = sTmp.replace("<!!>", PadZero(date.getDate()));
    sTmp = sTmp.replace("<!>", date.getDate());
    sTmp = sTmp.replace("<@@@@>", fullMonthNames[date.getMonth()]);
    sTmp = sTmp.replace("<@@@>", shortMonthNames[date.getMonth()]);
    sTmp = sTmp.replace("<@@>", PadZero(date.getMonth() + 1));
    sTmp = sTmp.replace("<@>", date.getMonth() + 1);
    sTmp = sTmp.replace("<##>", PadZero(date.getMinutes()));
    sTmp = sTmp.replace("<#>", date.getMinutes());
    sTmp = sTmp.replace("<((>", PadZero(date.getSeconds()));
    sTmp = sTmp.replace("<(>", date.getSeconds());
    
    sTmp = sTmp.replace("<||>", PadZero(date.getHours()));
    sTmp = sTmp.replace("<|>", date.getHours());
    sTmp = sTmp.replace("<^^>", PadZero(date.getHours() > 12 ? date.getHours() - 12 : date.getHours()));
    sTmp = sTmp.replace("<^>", date.getHours() > 12 ? date.getHours() - 12 : date.getHours());
    sTmp = sTmp.replace("<&>", date.getHours() < 12 ? amDesignator : pmDesignator);

    sTmp = sTmp.replace("<****>", date.getFullYear());
    sTmp = sTmp.replace("<**>", date.getFullYear().toString().substring(2));

    return sTmp;
}

function Global_CB_(/* "Veetro.v2_0.ClassName.MethodName", param string[] args*/)
{
    var s = "";
    for (var i = 1; i < arguments.length; i++)
    {
        if (s.length > 0)
            s += "\n";
        if (arguments[i])
            s += arguments[i].toString().replace(/\n/g, "\\n");
    }
    return Global_CBInternal(arguments[0], s);
}
var LoadTimeout;
function GlobalCB(/* "Veetro.v2_0.ClassName.MethodName", param string[] args*/)
{
    var ar = [];
    for (var i = 1; i < arguments.length; i++) { 
        ar.push(arguments[i]?arguments[i].toString():"");
    }

    UI(arguments[0], ar, function(e) {
       
        if (e && e.length > 1)
            eval(e);
    });

}

function ShowLoadingGlyph()
{
    if ($j('#LoadingGlyph').exists())
        $j('#LoadingGlyph').fadeIn();
}

function ClearLoadingGlyph()
{
    if (LoadTimeout)
        clearTimeout(LoadTimeout);
    if ($j('#LoadingGlyph').exists())
        $j('#LoadingGlyph').fadeOut();
}
function CollectFormDataWithin(hostid) {
    var keys = new Array();
    var values = new Array();
    var elements = $j('#' + hostid).find('input,select,textarea');
    for (var i = 0; i < elements.length; i++) {
        var el = elements[i];
        if ((el.type == 'radio' || el.type == 'checkbox') && !el.checked)
            continue;
        var idx = -1;
        var thisName = el.name.toLowerCase();
        for (var x = 0; x < keys.length; x++) {
            if (keys[x] == thisName) {
                idx = x;
                break;
            }
        }

        if (idx == -1) {
            keys.push(thisName);
            values.push(el.value);
            idx = keys.length - 1;
        }
        else
            values[idx] += "," + el.value;
    }
    var s = "";
    for (var i = 0; i < keys.length; i++) {
        if (s)
            s += "\n";
        s += keys[i] + '=' + values[i].replace(/\n/g, "#NL#");
    }
    //alert(s);
    return s;
}
function CollectFormData()
{
    var s = "";
    var keys = new Array();
    var values = new Array();

    for (var i = 0; i < document.forms[0].elements.length; i++)
    {
        var el = document.forms[0].elements[i];
       
        if ((el.tagName == 'INPUT'
            || el.tagName == 'SELECT' || el.tagName == 'TEXTAREA')
            && el.name
            && el.name != '__VIEWSTATE')
        {
            if ((el.type == 'radio' || el.type == 'checkbox') && !el.checked)
                continue;

            var idx = -1;
            var thisName = el.name.toLowerCase();
            for (var x = 0; x < keys.length; x++)
            {
                if (keys[x] == thisName)
                {
                    idx = x;
                    break;
                }
            }

            if (idx == -1)
            {
                keys.push(thisName);
                values.push(el.value);
                idx = keys.length - 1;
            }
            else
                values[idx] += "," + el.value;

        }
    }
    for (var i = 0; i < keys.length; i++)
    {
        if (s)
            s += "\n";
        s += keys[i] + '=' + values[i].replace(/\n/g, "#NL#");
    }
    //alert(s);
    return s;
}


function MarkModified()
{
    if ($('HasFormChanged'))
        $('HasFormChanged').value = '1';
}
function CancelEdit()
{
    if ($('HasFormChanged'))
        $('HasFormChanged').value = '0';
}

function FixIe6Hover()
{
    if (!ie6)
        return;

    var uls = document.getElementsByTagName("UL");
    for (var x = 0; x < uls.length; x++)
    {
        if (uls[x].className != "MiniDropDown")
            continue;

        var sfEls = uls[x].getElementsByTagName("LI");

        for (var i = 0; i < sfEls.length; i++)
        {
            sfEls[i].onmouseover = function()
            {
                this.className += " sfhover";
            }
            sfEls[i].onmouseout = function()
            {
                this.className = this.className.replace(new RegExp(" sfhover\\b"), "");
            }

        }
    }
}

if (ie6)
    window.attachEvent("onload", FixIe6Hover);

function PushTimeZone() {


    var d = new Date();
    var date1 = new Date(d.getFullYear(), 0, 1, 0, 0, 0, 0);
    var offsetDST = date1.getTimezoneOffset();
    var offsetNonDST = date1.getTimezoneOffset();
    var dstChangeDate;
    var stdChangeDate;
    for (var i = 0; i < 365; i++) {
        date1 = new Date(date1.getTime() + (1000 * 60 * 60 * 24));
        if (!dstChangeDate
            && date1.getTimezoneOffset() != offsetDST) {
            dstChangeDate = date1;
            offsetNonDST = date1.getTimezoneOffset();
        }
        else if (dstChangeDate
            && !stdChangeDate
            && date1.getTimezoneOffset() != offsetNonDST) {
            stdChangeDate = date1;
            break;
        }
    }

    GlobalCB('Calendar.StoreTimezoneBias', dstChangeDate ? FormatDate(dstChangeDate, 'yyyy-MM-dd') : '-', stdChangeDate ? FormatDate(stdChangeDate, 'yyyy-MM-dd') : '-', offsetNonDST, offsetDST);
}

function SetEntryProgress(event, sender, type, id)
{
    var width = GetWidth(sender);
    if (width == 0)
        return;

    width -= 9;
    var containerLeft = PosX(sender);//-9;

    var x = Math.round((mouseX - containerLeft) / width * 100);
    if (x > 95)
        x = 100;
    if (x < 5)
        x = 0;
        
    if (isNaN(x))
        return;
        
    //sender.childNodes[0].innerHTML = "<div class=\"Value\">"+x+"%</div>";
    //sender.childNodes[0].style.width = x+"%";
    sender.innerHTML = "<img src=\"/v2.0/images/ajax-loader.gif\"/>";
    GlobalCB('CalendarWidget.SetEntryProgress', id, x.toString());
}
function SetEntryProgressEl(event, sender, element)
{
    var width = GetWidth(sender);
    if (width == 0)
        return;

    width -= 9;
    var containerLeft = PosX(sender);//-9;

    var x = Math.round((mouseX - containerLeft) / width * 100);
    if (x > 95)
        x = 100;
    if (x < 5)
        x = 0;
    sender.childNodes[0].innerHTML = "<div class=\"Value\">"+x+"%</div>";
    sender.childNodes[0].style.width = x+"%";
    if ($(element))
        $(element).value = x.toString();
    //sender.innerHTML = "<img src=\"/v2.0/images/ajax-loader.gif\"/>";
    //GlobalCB('CalendarWidget.SetEntryProgress', id, x.toString());
}
DayOfWeek =
{
    "Sunday": 0,
    "Monday": 1,
    "Tuesday": 2,
    "Wednesday": 3,
    "Thursday": 4,
    "Friday": 5,
    "Saturday": 6
}
Date.prototype.addMonths = function(n)
{
    var day = this.getDate();
    this.setMonth(this.getMonth() + n);
    if (this.getDate() < day)
    {
        this.setDate(1);
        this.setDate(this.getDate() - 1);

    }
    return this;
}
Date.prototype.getFirstOfMonth = function()
{
    return new Date(parseDate(this.getFullYear() + '-' + (this.getMonth() + 1) + '-1', 'yyyy-MM-dd').setHours(0, 0, 0, 0));
}
Date.prototype.toServerString = function () {
    return FormatDate(this, 'yyyy-MM-dd HH:mm:ss');
}
Date.prototype.fromServerString = function (str) {
    this.setTime(parseDate(str, 'yyyy-MM-dd HH:mm:ss').getTime());
    return this;
}
Date.prototype.addDays = function(n)
{
    //AddDays(this, n);
    var offset1 = this.getTimezoneOffset();

    this.setTime(this.getTime() + n * 1000 * 60 * 60 * 24);
    var offset2 = this.getTimezoneOffset();
    if (offset1 != offset2) {
        this.setTime(this.getTime() + ((offset2 - offset1) * 60 * 1000));
        // window.status=('offset dif '+(offset2-offset1)+' mins');
    }
    return this;
}
Date.prototype.addSeconds = function (n) {
  
    var offset1 = this.getTimezoneOffset();

    this.setTime(this.getTime() + n * 1000 );
    var offset2 = this.getTimezoneOffset();
    if (offset1 != offset2) {
        this.setTime(this.getTime() + ((offset2 - offset1) * 60 * 1000));
    }
    return this;
}
Date.prototype.dateDiff = function (unit, end) {
    if (typeof end == 'string')
        throw "Invalid end date";

    var offset1 = this.getTimezoneOffset();
    var offset2 = end.getTimezoneOffset();
    var tzOff = offset1 != offset2 ? ((offset2 - offset1) * 60 * 1000) : 0;
    var diff = ((end - this) - tzOff);
    switch (unit) {
        case 'second': return parseInt(diff / 1000);
        case 'minute': return parseInt(diff / 60000);
        case 'hour': return parseInt(diff / 3600000);
        case 'day': return parseInt(diff / 86400000);
        case 'week': return parseInt(diff / (86400000 * 7));
        case 'month': return (end.getMonth() + 1) + ((end.getFullYear() - this.getFullYear()) * 12) - (this.getMonth() + 1);
        case 'year': return end.getFullYear() - this.getFullYear();
    }
    throw "Invalid dateDiff unit '" + unit + "'";
}  
   
Date.prototype.addMinutes = function(n)
{
    this.setTime(this.getTime() + n * 1000 * 60);
    return this;
}

Date.prototype.getWeekOfYear = function()
{
    var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
    var DoW = d.getDay();
    d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
    var ms = d.valueOf(); // GMT
    d.setMonth(0);
    d.setDate(4); // Thu in Week 1
    return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
}
Date.prototype.convertToUTC = function () {
    return new Date(this.getTime() + (this.getTimezoneOffset() * 60 * 1000));
}
Date.prototype.convertToLocal = function () {
    return new Date(this.getTime() + (this.getTimezoneOffset() * 60 * -1000));
}
function parseDate(value, format)
{
    var rx = new RegExp("(H?H|h?h|m?m|tt|d?d|M{1,3}|yyyy|ss)", "g");
    var searchPattern = "";
    var match = rx.exec(format);
    var indexes = new Object();
    var d = new Date();
    var hasTime = false;

    if (match != null
        && match.length > 0)
    {
        var x = 0;
        while (match != null)
        {
            x++;
            for (var i = 1; i < match.length; i++)
            {

                if (match[i] == 'h' || match[i] == 'hh' || match[i] == 'HH' || match[i] == 'H')
                {
                    if (searchPattern.length > 0)
                        searchPattern += '[^\\w]+';
                    searchPattern += '(\\d?\\d)?';
                    indexes.Hour = x;
                    hasTime = true;
                }
                if (match[i] == 'm' || match[i] == 'mm')
                {
                    if (searchPattern.length > 0)
                        searchPattern += '[^\\w]+';
                    searchPattern += '(\\d?\\d)?';
                    indexes.Minute = x;
                    hasTime = true;
                }
                if (match[i] == 'ss') {
                    if (searchPattern.length > 0)
                        searchPattern += '[^\\w]+';
                    searchPattern += '(\\d?\\d)?';
                    indexes.Second = x;
                    hasTime = true;
                }
                if (match[i] == 'tt')
                {
                    if (searchPattern.length > 0)
                        searchPattern += '[^\\w]*';
                    searchPattern += '(' + UserInfo.AMDesignator + '|' + UserInfo.PMDesignator + ')?';
                    indexes.AMPM = x;
                    hasTime = true;
                }
                if (match[i] == 'd' || match[i] == 'dd')
                {
                    if (searchPattern.length > 0)
                        searchPattern += '[^\\w]+';
                    searchPattern += '(\\d?\\d)';
                    indexes.Day = x;
                }
                if (match[i] == 'MM' || match[i] == 'M')
                {
                    if (searchPattern.length > 0)
                        searchPattern += '[^\\w]+';
                    searchPattern += '(\\d?\\d)';
                    indexes.Month = x;
                }
                if (match[i] == 'MMM')
                {
                    if (searchPattern.length > 0)
                        searchPattern += '[^\\w]+';
                    searchPattern += '([^-|\\s]+)'; // \w doesn't cover utf8??
                    indexes.MonthName = x;
                }1
                if (match[i] == 'yyyy')
                {
                    if (searchPattern.length > 0)
                        searchPattern += '[^\\w]+';
                    searchPattern += '(\\d{4})';
                    indexes.Year = x;
                }
            }
            match = rx.exec(format);
        }


        searchPattern = ".*?" + searchPattern + ".*?";
        this.HasTime = indexes.Hour ? true : false;

        var formattedRx = new RegExp(searchPattern, "i");
        var dataMatch = formattedRx.exec(value);

        if (dataMatch != null)
        {
            if (hasTime && dataMatch[indexes.Hour] && dataMatch[indexes.Minute])
            {
                var pm = dataMatch[indexes.AMPM] && dataMatch[indexes.AMPM].toLowerCase() == 'pm';
                var hour = parseInt(dataMatch[indexes.Hour], 10);
                if (indexes.AMPM) {
                    if (dataMatch[indexes.AMPM] && dataMatch[indexes.AMPM].toLowerCase() == 'pm') {
                        if (hour < 12)
                            hour += 12;
                    }
                    else if (hour == 12) // 12:00 AM = 0
                        hour = 0;
                }
          
                d.setHours(hour);
                d.setMinutes(parseInt(dataMatch[indexes.Minute], 10)); ;
                if (indexes.Second)
                    d.setSeconds(parseInt(dataMatch[indexes.Second], 10));
                else
                    d.setSeconds(0);
            }
            else
            {
                d.setHours(0);
                d.setMinutes(0);
                d.setSeconds(0);
            }
          

            if (indexes.Month)
            {
                var mo = parseInt(parseInt(dataMatch[indexes.Month], 10) - 1);
                d.setDate(1); // Must set date to 1st, otherwise this may fail
                d.setMonth( mo );
            }
            else if (indexes.MonthName)
            {
                for (var j = 0; j < 12; j++)
                {
                    if (dataMatch[indexes.MonthName] == UserInfo.MonthNames[j]) {
                        d.setDate(1); // Must set date to 1st, otherwise this may fail
                        d.setMonth(j);
                        break;
                    }
                }
            }

            d.setFullYear(parseInt(dataMatch[indexes.Year], 10));

            // Must set date last, otherwise might be trying to
            // parse 31st when no 31st in whatever month we
            // happen to be in.
            d.setDate(parseInt(dataMatch[indexes.Day], 10));
        }


    }
    else
        alert("Unable to convert '" + value + "' into date. Please enter a value in the format of '" + format + "'");

    return d;
}

function AddMonths(date, n)
{
    var d = new Date(date);
    var day = d.getDate();
    d.setMonth(d.getMonth() + n);
    if (d.getDate() < day)
    {
        d.setDate(1);
        d.setDate(d.getDate() - 1);
    }
    return d;
}
function AddDays(date, n)
{
    var d = new Date(date);

    var offset1 = d.getTimezoneOffset();

    d.setTime(d.getTime() + n * 1000 * 60 * 60 * 24);
    var offset2 = d.getTimezoneOffset();
    if (offset1 != offset2) {
        d.setTime(d.getTime() + ((offset2 - offset1) * 60 * 1000));
        // window.status=('offset dif '+(offset2-offset1)+' mins');
    }
  
    return d;
}
function AddYears(date, n)
{
    var d = new Date(date);
    d.setTime(d.getTime() + n * 365 * 1000 * 60 * 60 * 24);
    return d;
}

function HtmlEncode(s)
{
    if (!s)
        return "";

    return s.replace(/"/g, "&quot;").replace(/\</g, "&lt;").replace(/\>/g, "&gt;");
}
function URLEncode(clearString)
{
    var output = '';
    var x = 0;
    clearString = clearString.toString();
    var regex = /(^[a-zA-Z0-9_.]*)/;
    while (x < clearString.length)
    {
        var match = regex.exec(clearString.substr(x));
        if (match != null && match.length > 1 && match[1] != '')
        {
            output += match[1];
            x += match[1].length;
        } else
        {
            if (clearString[x] == ' ')
                output += '+';
            else
            {
                var charCode = clearString.charCodeAt(x);
                var hexVal = charCode.toString(16);
                output += '%' + (hexVal.length < 2 ? '0' : '') + hexVal.toUpperCase();
            }
            x++;
        }
    }
    return output;
}

function BuildColorPicker(holderID, fieldID, initialValue)
{
    var s = "";

    s += "<div id=\"" + fieldID + "_popup\"></div><table><tr><td><div id=\"" + fieldID + "_preview\" class=\"GradOverlay\" onmouseup=\"OpenColourPicker('" + fieldID + "');\" style=\"width: 16px; height: 16px; border:1px solid #555555; cursor: pointer; background-color:" + HtmlEncode(initialValue) + "; margin-bottom:2px;\"><img src=\"/v2.0/images/space.gif\" width=1 height=1 /></td><td><input style=\"width: 60px; border:1px solid #555555; cursor: pointer;\" onkeyup=\"UpdateColourPicker('" + fieldID + "');\" onclick=\"OpenColourPicker('" + fieldID + "');\" type=\"text\" value=\"" + HtmlEncode(initialValue) + "\" name=\"" + fieldID + "\" id=\"" + fieldID + "\" /></td></tr></table>";

    $(holderID).innerHTML = s;
    UpdateColourPicker(fieldID);
}
function UpdateColourPicker(fieldID)
{
    $(fieldID + '_preview').style.backgroundColor = $(fieldID).value.replace(/\s/g, "");
}
function SetColourPicker(fieldID, colour)
{
    $(fieldID).value = colour;
    UpdateColourPicker(fieldID);
    ColourPickerCancelClose();
    $(fieldID + '_popup').innerHTML = '';
}
function ColourPickerCancelClose()
{
    if (colourPickerTimeout)
        clearTimeout(colourPickerTimeout);
}
var colourPickerTimeout;
function CloseColourPicker(fieldID)
{
    ColourPickerCancelClose();
    colourPickerTimeout = setTimeout("CloseColourPickerDelayed('" + fieldID + "')", 500);
}
function CloseColourPickerDelayed(fieldID)
{
    $(fieldID + '_popup').innerHTML = '';
}


function OpenColourPicker(fieldID)
{
    var s = "";

    //var colors = "#D3CBF9,#DFC3C2,#FDD1DE,#CEC2E5,#E3D7D1,#D3F8F8,#F6E4C5,#CDE8DB,#CEF7D8,#DDFAF2,#F4E5E0,#EEECF3,#F4FFD7,#DFCAFE,#D1D4FF,#E0FFD9,#E0C7CD,#E9E3EF,#FFF4E6,#D1ECF2,#CEE1CA,#EBE3F6,#DAD6EF,#F3E9C8,#C3C7D6,#CCD5D1,#D0EBD1,#E1D2DF,#E9D5C9,#C4CFD8,#F0F5FE,#E0F3E5,#FDD4F0,#DDE6DD,#FFE8C1,#C7EDCE,#E3C4F4,#CEC9FD,#F6D6FF,#FFD4DD,#CAEEF4,#EDF6E4,#D8C7DB,#C4F7D9,#EAC9FB,#FCEBEE,#DFE8C0,#E4F3C1,#FACFD6,#F3FECA,#DFC9D7,#C3F9C8,#C1E1D1,#C4FEF8,#F9C9C7,#CED7DB,#C7F7DB,#FDCEFE,#DBD3F1,#D3E4DD,#DFE3EA,#E8D3C4,#EECEC4,#E5CCD6,#E9DFC2,#F6F7D6,#C5E3C0,#E3E6D8,#E3E4E0,#E0EED4,#DBEAE6,#EDC4DA,#E5E6E8,#C8F2DB,#E0D8EE,#F4DDC9,#C1C6DF,#C6D3D3,#E8CBC9,#E4CBEC,#CBC5C3,#C3CCE5,#EBF1FE,#CDD4FF,#C4F1EA,#C1E2D8,#FCEADA,#CAD8CD,#FEECF6,#EFF7D8,#ECF8D3,#D4F4EE,#D5D9EC,#C0E5C5,#E4FCC1,#E9C4EE,#E8F5D4,#C4FDE2,#F0FBD5,#F9C2C2";
    //var colors = "#D3CBF9,#DFC3C2,#FDD1DE,#CEC2E5,#E3D7D1,#D3F8F8,#F6E4C5,#CDE8DB,#CEF7D8,#DDFAF2,#F4E5E0,#EEECF3,#F4FFD7,#DFCAFE,#D1D4FF,#E0FFD9,#E0C7CD,#E9E3EF,#FFF4E6,#D1ECF2,#CEE1CA,#EBE3F6,#DAD6EF,#F3E9C8,#C3C7D6,#CCD5D1,#D0EBD1,#E1D2DF,#E9D5C9,#C4CFD8,#F0F5FE,#E0F3E5,#FDD4F0,#DDE6DD,#FFE8C1,#C7EDCE,#E3C4F4,#CEC9FD,#F6D6FF,#FFD4DD,#CAEEF4,#EDF6E4,#D8C7DB,#C4F7D9,#EAC9FB,#FCEBEE,#DFE8C0,#E4F3C1,#FACFD6,#F3FECA,#DFC9D7,#C3F9C8,#C1E1D1,#C4FEF8,#F9C9C7,#CED7DB,#C7F7DB,#FDCEFE,#DBD3F1,#D3E4DD,#DFE3EA,#E8D3C4,#EECEC4,#E5CCD6,#E9DFC2,#F6F7D6,#C5E3C0,#E3E6D8,#E3E4E0,#E0EED4,#DBEAE6,#EDC4DA,#E5E6E8,#C8F2DB,#E0D8EE,#F4DDC9,#C1C6DF,#C6D3D3,#E8CBC9,#E4CBEC,#CBC5C3,#C3CCE5,#EBF1FE,#CDD4FF,#C4F1EA,#C1E2D8,#FCEADA,#E2CDFF,#FFB8B5,#FFDDFF,#D6B5FF,#FFEDDD,#E2FFFF,#FFFFBE,#D2FFF7,#D6FFF0,#BAD8F0,#CDBEB8,#FFBAF5,#BEFFB0";
    //var colors = "#A5D18C,#698559,#D1CF8C,#858359,#D1D1D1,#737C85,#B4C2D1,#858272,#D1C7B4,#85737B,#D1B4C1,#D1606D,#FFC4C4,#B38989,#FFE2C4,#B39E89,#B3AD89,#CCCCCC,#D8FFC4,#97B389,#B3B389,#C4FFE9,#89B3A3,#C6FFC4,#8BB389,#FFC4F9,#B389AE,#FF5EB9,#B34282,#FFC4D3,#B38994,#FF6C5E,#B34B42,#C4E3FF,#899FB3,#B3A389,#D3CBF9,#DFC3C2,#FDD1DE,#CEC2E5,#E3D7D1,#D3F8F8,#F6E4C5,#CDE8DB,#CEF7D8,#DDFAF2,#F4E5E0,#EEECF3,#F4FFD7,#DFCAFE,#D1D4FF,#E0FFD9,#E0C7CD,#E9E3EF,#FFF4E6,#D1ECF2,#CEE1CA,#EBE3F6,#DAD6EF,#F3E9C8,#C3C7D6,#CCD5D1,#D0EBD1,#E1D2DF,#E9D5C9,#EDC4DA,#E5E6E8,#C8F2DB,#E0D8EE,#F4DDC9";
    var top = "FFFFFF,000000,F6EAD2,1A3E72,527AAE,B84540,96B655,7F66A0,4AACC5,F59D56";
    var mid = "D2D2D2,BABABA,9A9A9A,828282,727272,"; // grays
        mid +="727272,6A6A6A,4E4E4E,363636,1E1E1E,";
        mid +="B6ADA6,9A968D,726F6A,4E4A47,363231,";
        mid +="C2CEDA,869AB5,4E6B97,122E53,0C1E32,";
        mid +="D2DEF4,A6BAD5,7A9AC1,3C557E,26364F,";
        mid +="EECECF,DA9E9E,CA726E,86332F,55221E,";
        mid +="E1EED2,CADAAB,AFC67E,6B823E,425126,";
        mid +="DFD9E7,BFB2CE,9F8DB7,5F4C79,403351,";
        mid +="D3EAF2,A5D5E3,78C1D4,388096,255664,";
        mid +="FCE7D6,FACEAB,F7B680,B77640,7A4E2B";
        
    var std = "B20D11,E9161D,FFB90B,FFFF00,96D642,19AA41,02B2EE,0072BB,2D3799,6F3098";
    
   

    s += "<div id=\"" + fieldID + "_table\" onmouseout=\"CloseColourPicker('" + fieldID + "');\" onmousemove=\"ColourPickerCancelClose()\" style=\"border: 1px solid #D3D3D3;background-color:#FBFBFB;width:174px;\">";
    {
    // top row
        s += "<div style='margin:1px' onmousemove=\"ColourPickerCancelClose()\">";
        {
            var ar = top.split(',');
            for (var i = 0; i < ar.length; i++)
                s += "<div onclick=\"SetColourPicker('" + fieldID + "', '#" + ar[i] + "')\" onmousemove=\"ColourPickerCancelClose()\" style='background-color:#"+ ar[i] +";width: 11px; height: 11px; cursor: pointer;border:1px solid #cccccc;margin:2px;float:left;'><img src=\"/v2.0/images/space.gif\" width=1 height=1/></div>";
        }       
        s += "</div>";
        // middle
        s += "<div style='margin:1px' onmousemove=\"ColourPickerCancelClose()\">";
        {
            var ar = mid.split(',');
            s += "<div style=\"float:left; width:11px;border:1px solid #808080;margin:2px;\">";
            for (var i = 0; i < ar.length; i++)
            {
                 if ((i % 5) == 0 && i > 0)
                  s += "</div><div style=\"float:left; width:11px;border:1px solid #808080;margin:2px;\">";
               s += "<div onclick=\"SetColourPicker('" + fieldID + "', '#" + ar[i] + "')\" onmousemove=\"ColourPickerCancelClose()\" style='background-color:#"+ ar[i] +";width: 11px; height: 11px; cursor: pointer;'><img src=\"/v2.0/images/space.gif\" width=1 height=1/></div>";
            }
            s += "</div>";
        }
        s += "</div>";
        // standard
        s += "<div style='margin:1px;' onmousemove=\"ColourPickerCancelClose()\">";
        {
            var ar = std.split(',');
            for (var i = 0; i < ar.length; i++)
                s += "<div onclick=\"SetColourPicker('" + fieldID + "', '#" + ar[i] + "')\" onmousemove=\"ColourPickerCancelClose()\" style='background-color:#"+ ar[i] +";width: 11px; height: 11px; cursor: pointer;border:1px solid #cccccc;margin:2px;float:left;'><img src=\"/v2.0/images/space.gif\" width=1 height=1/></div>";
        }
        s += "</div>";
    }
    s += "</div>";
//    for (var i = 0; i < ar.length; i++)
//    {
//        if ((i % 10) == 0 && i > 0)
//        {
//            s += "</tr><tr>";
//        }
//        s += "<td onmousemove=\"ColourPickerCancelClose()\" style=\"width: 15px; height: 12px; cursor: pointer;\" onclick=\"SetColourPicker('" + fieldID + "', '#" + ar[i] + "')\" bgcolor=\"#" + ar[i] + "\"><img src=\"/v2.0/images/space.gif\" width=1 height=1/></td>";
//    }
//    s += "</tr>";
//    s += "</table>";

    var holder = $(fieldID + "_popup");
    holder.innerHTML = s;
    var table = $(fieldID + "_table");
    table.style.position = "absolute";
    //table.style.top = (mouseY+10).toString()+"px"; //PosY($(fieldID))+GetHeight($(fieldID))+"px";
    //table.style.left = mouseX.toString()+"px"; //PosX($(fieldID))+"px";
    table.style.marginTop = "25px";
    table.style.zIndex = 200;


}
function FormatDateUTCUrlString(date1, date2, utc)
{
    var s = FormatDateUTC(date1, true);
    if (date2)
        s += ' to ' + FormatDateUTC(date2, true);
    return s;
}

//
// PopupItemBubble
//

var PopupItemID;
var PopupItemTimeout;
var PopupCurrentLink;

var BalloonBounds = { X: 0, Y: 0, W: 0, H: 0,
    LastSet: 0,
    IsReset: function() { return this.W == 0; },
    toString: function() { return "X:" + this.X + " Y:" + this.Y + " W:" + this.W + " H:" + this.H; },
    Reset: function() { this.H = this.W = this.X = this.Y = 0; $j('#TestBox').remove(); },
    IsMouseInBounds: function() { return mouseX > this.X && mouseX < this.X + this.W && mouseY > this.Y && mouseY < this.Y + this.H; },
    Set: function(x, y, w, h) {
        this.X = x; this.Y = y; this.W = w; this.H = h;
        this.LastSet = new Date().getTime();
        // Bounds debug helper        
//        if (!$j('#TestBox').exists())
//            $j(document.body).append('<div id="TestBox" style="border:1px solid red;"></div>');
//        $j('#TestBox').css('position', 'absolute');
//        $j('#TestBox').css('width', w + 'px');
//        $j('#TestBox').css('height', h + 'px');
//        $j('#TestBox').css('top', y + 'px');
//        $j('#TestBox').css('left', x + 'px');
    }
};

function PopupItemBubbleDelete(type, pk) { 
    var BubbleRequest = new Object();
    BubbleRequest.Type = type;
    BubbleRequest.ID = pk;


    UI('ItemBubble.Delete', BubbleRequest, function(r) {
        if (PopupCurrentLink)
            PopupCurrentLink.html('<s>' + PopupCurrentLink.html() + '</s>');
        if ($j('#PreviewBalloonDetails').exists()) {
            $j('#PreviewBalloonDetails').html(r);
            var balloon = $j("#PreviewBalloon");
            var linkBottom = PopupCurrentLink.bottom();
            var linkCenter = (PopupCurrentLink.left() + PopupCurrentLink.outerWidth() / 2)
            balloon.css('top', (PopupCurrentLink.top() - (balloon.outerHeight() + 25)) + 'px');
            balloon.css('left', (linkCenter - 110) + 'px');
            balloon.effect("bounce", { times: 3, distance: 10 }, 100);
            $j('.' + type + pk).fadeOut(function() { $j(this).remove(); });
        }
    });
}
function PopupItemBubble(event, type, pk, occurrence, noDelay) {
    PopupPreviewBubbleCancelTimeout();

    if (PopupItemID == pk)
       return;
   
    var link = $j(event.currentTarget || event.srcElement);
    
    BalloonBounds.Set(link.offset().left, link.offset().top, link.outerWidth(), link.outerHeight());
    if (noDelay)
        PopupItemBubbleThreaded(type, pk, occurrence, link);
    else
        PopupItemTimeout = setTimeout(function () {
            PopupItemBubbleThreaded(type, pk, occurrence, link);
            
        }, 1500);
}

function PopupItemBubbleThreaded(type, pk, occurrence, link) {

    if (!BalloonBounds.IsMouseInBounds()) // Cursor moved off link
        return;
        
    var BubbleRequest = new Object();
    BubbleRequest.Type = type;
    BubbleRequest.ID = pk;
    BubbleRequest.Occurrence = occurrence;
    UI('ItemBubble.Render', BubbleRequest, function (r) {

        if (!BalloonBounds.IsMouseInBounds()) // Cursor moved off link
            return;

        PopupItemID = pk;

        var s = "";
        s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"Inner\">";
        s += "<a href=\"javascript:;\" onclick=\"PopupPreviewBubbleCancelDelayed();\" class=\"Close\"></a>";
        s += "<span id=\"PreviewBalloonDetails\">" + r + "</span>";
        s += "</div><div class=\"Triangle\"></div></div>";
        $j("#PreviewBalloonHolder").css('visibility', 'hidden');
        $j("#PreviewBalloonHolder").css('display', 'block');
        $j("#PreviewBalloonHolder").html(s);

        var balloon = $j("#PreviewBalloon");
        PopupCurrentLink = link;
        // Position to top-right corner bounds of link
        var linkBottom = PopupCurrentLink.bottom();
        var linkCenter = (PopupCurrentLink.left() + PopupCurrentLink.outerWidth() / 2)
        balloon.css('top', (PopupCurrentLink.top() - (balloon.outerHeight() + 25)) + 'px');
        balloon.css('left', (linkCenter - 110) + 'px');
        balloon.keepOnScreen();
        BalloonBounds.Set(balloon.offset().left, balloon.offset().top, balloon.outerWidth(), (linkBottom - balloon.offset().top));
        balloon.css('display', 'none');
        $j("#PreviewBalloonHolder").css('visibility', 'visible');

        if (!BalloonBounds.IsMouseInBounds())
            PopupPreviewBubbleCancelDelayed();
        else {
            balloon.fadeIn();
           
        }
    });
}

function PopupItemDetailsThreaded(type, pk, occurrence, x, y)
{
    var detailsElement = $('PreviewBalloonDetails');
    if (!detailsElement)
        return;

    GlobalCB('CalendarWidget.RenderItemBubble', type, pk.toString(), occurrence.toString(), x, y);

}

function PopupPreviewBubbleCancelTimeout() {
    if (PopupItemTimeout)
        clearTimeout(PopupItemTimeout);
    PopupItemTimeout = 0;
}

function PopupPreviewBubbleCancel() {
    PopupPreviewBubbleCancelDelayed();
}
function PopupPreviewBubbleCancelDelayed() {
    PopupPreviewBubbleCancelTimeout();
    $j("#PreviewBalloonHolder").fadeOut(function() { $j(this).html(''); $j(this).css('display', 'none'); BalloonBounds.Reset(); PopupItemID = 0; });
}

function DialogBalloonHolderCancel() {
    PopupItemID = 0;
    $j("#DialogBalloonHolder").fadeOut(function() { $j(this).html(''); $j(this).css('display', 'block'); });
}


function __Popup(_url, pWidth, pHeight, extra)
{
    if (!extra)
        extra = "";
    var pLeft = (screen.width) / 2 - (pWidth / 2);
    var pTop = (screen.height) / 2 - (pHeight / 2);
    var d = new Date();
    var unique = d.getTime();
    pWin = open(_url, 'popUpWin' + unique, 'width=' + pWidth + ',height=' + pHeight + ',left=' + pLeft + ',top=' + pTop + ',screenX=' + pLeft + ',screenY=' + pTop + ',toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes' + extra);
    pWin.opener = this;
}

function readCookie(name)
{
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++)
    {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
}

function BuildFileUploader(fileType, 
            javascript_id,
            Callback, 
            Comment,
            FolderID,
            EntryID,
            EntityID,
            LeadID,
            InvoiceID)
{
    var s = new StringBuilder();
    s.Append("<iframe id=\"UploadWindow\" src=\"/UploadEx?FolderID=");
    s.Append(FolderID);
    s.Append("&EntryID=");
    s.Append(EntryID);
    s.Append("&EntityID=");
    s.Append(EntityID);
    s.Append("&LeadID=");
    s.Append(LeadID);
    s.Append("&InvoiceID=");
    s.Append(InvoiceID);
    s.Append("&Type=");
    s.Append(fileType);
    s.Append("&Callback=");
    s.Append(Callback);
    s.Append("&javascript_id=");
    s.Append(javascript_id);
    s.Append("\" frameborder=\"0\" width=\"280\" height=\"55\">");
    s.Append("></iframe>");
    return s.ToString();
}

function EditComment(NotationID)
{
    var commentDiv = $("Notation" + NotationID + "_Body");
    if (!commentDiv)
        return;
   
    commentDiv.innerHTML = "<div class=\"Loading\"></div>";
    GlobalCB("EntryEditor.GetNotationEditor", NotationID);
    commentDiv.style.display = 'block';
}

function DeleteComment(NotationID)
{
    if (!confirm('Really delete this notation? This is not undoable.'))
        return;
    
    var commentDiv = $("Notation" + NotationID + "_Body");
    if (!commentDiv)
        return;
    commentDiv.innerHTML = "<div class=\"Loading\"></div>";
    GlobalCB("EntryEditor.DeleteNotation", NotationID);
}

function DeleteMessage(MessageID)
{
    if (!confirm('Really delete this message? This is not undoable.'))
        return;
    
    var commentDiv = $("Message" + MessageID + "_Body");
    if (!commentDiv)
        return;
    commentDiv.innerHTML = "<div class=\"Loading\"></div>";
    GlobalCB("EntryEditor.DeleteMessage", MessageID);
}


function OnGetNotationEditor(res, NotationID)
{
    var commentDiv = $("Notation" + NotationID + "_Body");
    if (!commentDiv)
        return;
    commentDiv.innerHTML = res;
    setTimeout("HtmlEdit_OnInitialise('CommentEditor" + NotationID + "');", 500);
}

function EditCommentApply(NotationID)
{
    var commentDiv = $("Notation" + NotationID + "_Body");
    if (!commentDiv)
        return;

    var newHtml = $("CommentEditor" + NotationID).value;
    HtmlEdit_Close("CommentEditor" + NotationID);
    GlobalCB("EntryEditor.UpdateNotation", NotationID, newHtml);
}

function OnUpdateNotation(res, NotationID)
{
    var commentDiv = $("Notation" + NotationID + "_Body");
    if (!commentDiv)
        return;
    commentDiv.innerHTML = res;
}

function EditCommentCancel(NotationID)
{
    var commentDiv = $("Notation" + NotationID + "_Body");
    if (!commentDiv)
        return;
        
    HtmlEdit_Close("CommentEditor" + NotationID);
    GlobalCB("EntryEditor.GetNotation", NotationID);
}

function OnGetNotation(res, NotationID)
{
    var commentDiv = $("Notation" + NotationID + "_Body");
    if (!commentDiv)
        return;
    commentDiv.innerHTML = res;
}

function MarkItemsAsRead(itemsString, ElementID, ElementID2)
{
    GlobalCB("EntryEditor.MarkItemsRead", itemsString);

    var el = $(ElementID);
    if (el)
        el.style.display = "none";
    el = $(ElementID2);
    if (el)
        el.style.display = "none";
}

/*
* Catch Tab logic from
* http://www.webdeveloper.com/forum/showthread.php?s=&threadid=32317
*/

function setSelectionRange(input, selectionStart, selectionEnd)
{
    if (input.setSelectionRange)
    {
        input.focus();
        input.setSelectionRange(selectionStart, selectionEnd);
    }
    else if (input.createTextRange)
    {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
    }
}

function replaceSelection(input, replaceString)
{
    if (input.setSelectionRange)
    {
        var selectionStart = input.selectionStart;
        var selectionEnd = input.selectionEnd;
        var scrollTop = input.scrollTop; // fix scrolling issue with Firefox
        input.value = input.value.substring(0, selectionStart) + replaceString +
                                input.value.substring(selectionEnd);
        input.scrollTop = scrollTop;
        if (selectionStart != selectionEnd)
        {
            setSelectionRange(input, selectionStart, selectionStart + replaceString.length);
        }
        else
        {
            setSelectionRange(input, selectionStart + replaceString.length, selectionStart + replaceString.length);
        }

    }
    else if (document.selection)
    {
        var range = document.selection.createRange();

        if (range.parentElement() == input)
        {
            var isCollapsed = range.text == '';
            range.text = replaceString;

            if (!isCollapsed)
            {
                range.moveStart('character', -replaceString.length);
                range.select();
            }
        }
    }
}
// We are going to catch the TAB key so that we can use it, Hooray!
function CatchTab(item, e) {
    
    c = e.which ? e.which : e.keyCode; 
   
    if (c == 9)
    {
        replaceSelection(item, String.fromCharCode(9));
       
        return false;
    }

}

function FocusNext(sender)
{
    var focusNext = false;
    for (var i = 0; i < document.forms[0].elements.length; i++)
    {
        if (focusNext)
        {
            switch (document.forms[0].elements[i].tagName)
            {
                case "INPUT":
                    if (document.forms[0].elements[i].type != "hidden")
                    {
                        document.forms[0].elements[i].focus();
                        return;
                    }
                    break;
                case "TEXTAREA":
                case "SELECT":
                    document.forms[0].elements[i].focus();
                    return;
            }
 
        }
        if (document.forms[0].elements[i] == sender)
            focusNext = true;
    }
}
function ToggleCalendarIDShowState(id)
{
    if (!$('Calendar'))
        window.location = "/calendar?cid=" + id;
}

////////////////////////////////////////////////////
// BASIC GRID
////////////////////////////////////////////////////

var BasicGrid_searchTimeout;

function BasicGrid_CreateRequest(uid, commandName, arg1, arg2) {
    var GridRequest = new Object();
    GridRequest.State = $j.parseJSON($j('#' + uid + '_State').val());
    GridRequest.CmdName = commandName;
    GridRequest.CmdArg1 = arg1;
    GridRequest.CmdArg2 = arg2;
    if ( GridRequest.State.PostData)
        GridRequest.PostedData =  CollectFormData() ;
    return GridRequest;
}
function BasicGrid_SubmitRequest(GridRequest) {
    var uid = GridRequest.State.UID;
    if ($j('#' + uid + ' .BlueBoxFooter .InnerRight div').exists())
        $j('#' + uid + ' .BlueBoxFooter .InnerRight div').addClass('GridLoading');
    if ($j('.Loading' + uid).exists()) {
        $j('.Loading' + uid).addClass('LoadingTextBox');
    }
    UI('BasicGrid.OnCallback', GridRequest, function(r) {
        if (r)
            eval(r);
        if ($j('.Loading' + uid).exists()) {
            $j('.Loading' + uid).removeClass('LoadingTextBox');
        }
    });
}
function BasicGrid_Do(uid, commandName, arg1, arg2) {
    var GridRequest = BasicGrid_CreateRequest(uid, commandName, arg1, arg2);
    BasicGrid_SubmitRequest(GridRequest);
}

function BasicGrid_Sort(uid, column, type) {
    var GridRequest = BasicGrid_CreateRequest(uid, "sort", column, type);
    BasicGrid_SubmitRequest(GridRequest);
}

function BasicGrid_SetTab(uid, tab) {
    var GridRequest = BasicGrid_CreateRequest(uid, "tab", tab);
    BasicGrid_SubmitRequest(GridRequest);
}

function BasicGrid_PerformSearch(uid) {
    var GridRequest = BasicGrid_CreateRequest(uid, "search", $(uid + '_kw').value);
    BasicGrid_SubmitRequest(GridRequest);
}

function BasicGrid_MenuCmd(uid, cmd, arg) {
    var GridRequest = BasicGrid_CreateRequest(uid, "menu", cmd, arg);
    BasicGrid_SubmitRequest(GridRequest);
}
function BasicGrid_Command(uid, cmd, arg) {
    var GridRequest = BasicGrid_CreateRequest(uid, "cmd", cmd, arg);
    BasicGrid_SubmitRequest(GridRequest);
}
function BasicGrid_DropDownOpen(uid, col) {
    var div = $j('#' + uid + '_' + col + ' .DropDown div');
    //div.css('margin-top', $j('#' + uid + '_' + col + ' .DropDown').height() + 'px');
    div.bind('mouseleave', function() { $j(this).fadeOut(function() { $j(this).unbind('mouseleave'); }); });
    div.css('display', 'block');
}
function BasicGrid_FilterOpen(uid, col) {
    if ($j('#' + uid + '_' + col + ' .Filter div').exists())
        return;
    var div = $j('#' + uid + '_' + col + ' .Filter');
    var s = new StringBuilder;
    var options = $j.parseJSON(div.attr('options'));
    var state = $j.parseJSON($j('#' + uid + '_State').val());

    s.Append('<div>');
    for (var i = 0; i < options.length; i++) {
        var chid = uid + '_' + col + '_f' + i;
        var checked = false;
        if (state.Filters)
            for (var x = 0; x < state.Filters.length; x++)
                if (state.Filters[x].Col == col && state.Filters[x].Val == options[i].Val)
                    checked = true;
        s.Append('<input type="checkbox" id="' + chid + '" name="' + uid + '_' + col + '_f" value="' + options[i].Val + '" ' + (checked ? 'checked' : '') + ' /><label for="' + chid + '">' + options[i].Label + '</label><br/>');
    }
    s.Append('</div>');
    div.html(s.ToString());
    div = $j('#' + uid + '_' + col + ' .Filter div');
    div.bind('mouseleave',
    function() {
        var GridRequest = BasicGrid_CreateRequest(uid, "filter");

        var ar = [];
        var originalVals = [];
        var newVals = [];
        if (GridRequest.State.Filters) {
            for (var i = 0; i < GridRequest.State.Filters.length; i++) {
                if (GridRequest.State.Filters[i].Col == col) {
                    originalVals.push(GridRequest.State.Filters[i].Val);
                    continue;
                }
                ar.push(GridRequest.State.Filters[i]);
            }
        }
        $j('#' + uid + '_' + col + ' .Filter div input:checkbox:checked').each(function(index) {
            var o = new Object();
            o.Col = col;
            o.Val = $j(this).val();
            ar.push(o);
            newVals.push(o.Val);
        });

        // Make sure something changed
        if (originalVals.length == newVals.length) {
            var same = true;
            for (var i = 0; i < newVals.length; i++)
                if (newVals[i] != originalVals[i])
                same = false;
            if (same) {
                div.fadeOut(function() { $j(this).remove(); });
                return;
            }
        }

        GridRequest.State.Filters = ar;
        div.html('<img src="/v2.0/images/ajax-loader.gif"/>');
        UI('BasicGrid.OnCallback', GridRequest, function(r) {
            div.fadeOut(function() {
                if (r)
                    eval(r);
            });
        });

    });
}
function BasicGrid_ContextMenu(sender, uid, menuIndex, arg) {
    var data = $(uid + '_menu_' + menuIndex).value.split('\n');
    var s = new StringBuilder();

    s.Append("<ul class=\"CtxMenu\" style=\"position:absolute;left:auto; width:auto;\"><ul style=\"left:auto; width:auto;\">");
    
    for (var i = 0; i < data.length; i++) {
        var params = data[i].replace(/\r|\n/g, '').split('`');

        if (params[0] == '--') // break
            s.Append("<li class=\"MenuBreak\"><img height=\"1\" width=\"1\" src=\"/v2.0/images/space.gif\"/></li>");
        else if (params[2] == '1') // URL
            s.Append("<li><a href=\"" + params[1].replace(/#arg#/g, arg) + "\">" + params[0] + "</a></li>");
        else // callback
            s.Append("<li><a href=\"javascript:;\" onmousedown=\"BasicGrid_MenuCmd('" + params[1] + "', '" + arg + "');\"><span>&nbsp;</span>" + params[0] + "</a></li>");
    }
    s.Append('</ul></ul>');
    $j(sender).children('div').after(s.ToString());
    $j(sender).children('.CtxMenu').bind('mouseleave', function() { $j(this).remove(); });
    $j(sender).children('.CtxMenu').bind('click', function() {
        // $j(this).unbind('mouseleave');
        setTimeout("$j('.CtxMenu').remove();", 100); // FF 3.5.6 fix
    });
}
var previousMenu;
var previousMenuInner;
var previousMenuInt;
var previousSender;

function BasicGrid_ContextMenu2(sender, uid, menuIndex, arg)
{
    if (sender == previousSender
        && previousMenu)
        return; // Link probably click, don't kill the link
    
    if (previousMenuInt)
        clearTimeout(previousMenuInt);
        
    if (previousMenu)
        previousMenu.innerHTML =  previousMenuInner;
    
    
    previousSender = sender;
    previousMenuInner = sender.innerHTML;

    var data = $(uid + '_menu_' + menuIndex).value.split('\n');

    var s = "<div><ul><li><div style=\"display: block; margin-right: 20px;\" id='currentMenuOuter'>" + previousMenuInner + "</div><ul id='currentMenu' style='min-width:" + GetWidth(sender) + "px; position: absolute; left: " + mouseX + "px' onmouseover='BasicGrid_ContextOver()' onmouseout='BasicGrid_ContextOut()'>";
    for(var i=0;i<data.length;i++)
    {
        var params = data[i].replace(/\r|\n/g,'').split('`');
        
        if (params[0]=='--') // break
            s += "<li onmouseover='BasicGrid_ContextOver()' onmouseout='BasicGrid_ContextOut()' class=\"MenuBreak\"><img height=\"1\" width=\"1\" src=\"/v2.0/images/space.gif\"/></li>";
        else if (params[2]=='1') // URL
            s += "<li onmouseover='BasicGrid_ContextOver()' onmouseout='BasicGrid_ContextOut()'><a href=\""+params[1].replace(/#arg#/g, arg)+"\">"+params[0]+"</a></li>";
        else // callback
            s += "<li onmouseover='BasicGrid_ContextOver()' onmouseout='BasicGrid_ContextOut()'><a href=\"javascript:;\" onmousedown=\"BasicGrid_MenuCmd('" + params[1] + "', '" + arg + "');\"><span>&nbsp;</span>" + params[0] + "</a></li>";
    }
    s += "</ul></li></ul></div>";

    sender.innerHTML = s;
    previousMenu = sender;
}
function BasicGrid_ContextOut()
{
 if (previousMenuInt)
        clearTimeout(previousMenuInt);
 previousMenuInt = setTimeout("if (previousMenuInner) {previousMenu.innerHTML =  previousMenuInner; previousMenu=null; previousMenuInner=null; clearTimeout(previousMenuInt); }", 500);
}
function BasicGrid_ContextOver()
{
    if (previousMenuInt)
        clearTimeout(previousMenuInt);
}
function BasicGrid_PerformSearchDelayed(uid, method, state, postData)
{
    if (BasicGrid_searchTimeout)
        clearTimeout(BasicGrid_searchTimeout);
    BasicGrid_searchTimeout = setTimeout('BasicGrid_PerformSearch("' + uid + '")', 1500);
}
function RefreshBasicGrid(uid)
{
    if ($(uid + "_State")) {
       
       
        BasicGrid_Do(uid, 'refresh');
    }
}




function ToggleHelp(HelpEntry)
{
    var IsHidden = $("HelpContent").style.display == "none";
    GlobalCB("HelpWidget.StoreHelpState", HelpEntry, IsHidden ? "1" : "0");
    __Toggle("HelpContent");
}

function PopupTagDialog(event, tagsElement, cssClass, EntityID) {
    var TagBalloon = new Balloon(event, 'TagBalloon', 'bottom');
    var o = new Object();
    o.TagsElement = tagsElement;
    o.CssClass = cssClass;
    o.Entities = EntityID;
    UI('ContactEditor2.OnRenderTagDialog2', o, function(r) { TagBalloon.html(r); });

}

function PopupTagRemoveDialog2(event, EntityID) {
    var TagBalloon = new Balloon(event, 'TagBalloon', 'bottom');
    var o = new Object();
    o.Entities = EntityID;
    UI('ContactEditor2.OnRenderTagRemoveDialog2', o, function(r) { TagBalloon.html(r); });
}

function PopupTagRemoveDialog(event, tagsElement, cssClass, EntityID, tag)
{
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"PopupPreviewBubbleCancelDelayed();\" class=\"Close\"></a>";

    s += "<span id=\"TagBalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> Fetching tags ... <br/><br/></p></span>";
    s += "</div><div class=\"Triangle\"></div></div>";
    $("PreviewBalloonHolder").innerHTML = s;

    PositionBalloon(mouseX, mouseY);

    GlobalCB("ContactEditor2.OnRenderTagRemoveDialog", tagsElement, cssClass ? cssClass : ' ', EntityID, tag);
}

function PositionBalloon(x, y, id)
{
    if (!x)
    {
        x = LastBalloonPosX;
        y = LastBalloonPosY;
    }
    if (!id)
        id = "PreviewBalloon";

    var balloon = $(id);
    var posY = (y - (GetHeight(balloon) + 30));

    if (posY < GetScrollTop() + 5)
        posY = GetScrollTop() + 5;
    
    if (x < 115)
        x = 115;
    balloon.style.display = "block";
    balloon.style.left = (x - 110) + "px";
    balloon.style.top = posY + "px";
    LastBalloonPosX = x;
    LastBalloonPosY = y;
}
function PositionBalloonTop(x, y, id)
{
    if (!x)
    {
        x = LastBalloonPosX;
        y = LastBalloonPosY;
    }
    if (!id)
        id = "PreviewBalloon";

    var posY = (y + 30);
    
    if (posY < GetScrollTop() + 5)
        posY = GetScrollTop() + 5;

    if (x < 115)
        x = 115;

    var balloon = $(id);

    if (x + GetWidth(balloon) > GetWidth(document.body))
        x = GetWidth(document.body) - GetWidth(balloon) + 110;
        
    balloon.style.display = "block";
    balloon.style.left = (x - 110) + "px";
    balloon.style.top = posY + "px";

    LastBalloonPosX = x;
    LastBalloonPosY = y;
}
function CollectSelectedCheckBoxes(inputName)
{
    var inputs = document.getElementsByTagName('input');
    var selection = '';
    for (var i = 0; i < inputs.length; i++)
    {
        if (inputs[i].name == inputName
            && inputs[i].checked)
        {
            if (selection.length > 0)
                selection += ',';
            selection += inputs[i].value;
        }
    }
    return selection;
}

function ToggleAllByName(sender, name)
{
    var inputs = document.getElementsByTagName('input');
    for (var i = 0; i < inputs.length; i++)
    {
        if (inputs[i].name == name)
            inputs[i].checked = sender.checked;
    }
}

function OpenFeedbackDialog()
{
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"TriangleTopRight\"></div><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"TagBalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloonTop(mouseX, mouseY);

    GlobalCB("Home.RenderFeedbackForm", x, y, window.location);
}

function SendBetaFeedback(x, y)
{
    var feedback = $('BetaFeedback').value;

    if (feedback.length === 0)
    {
        $('BetaFeedbackError').style.display = 'block';
        return;
    }

    $("TagBalloonDetails").innerHTML = "<p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> Sending your feedback ... <br/><br/></p>";
    PositionBalloon(x, y);
    GlobalCB("Home.SendBetaFeedback", x, y, window.location, feedback);
}


/////////////////////////////////////////////////
// REMINDER DIALOGS
/////////////////////////////////////////////////

function RemoveReminder(ReminderID)
{
    GlobalCB("EntryEditor.OnRemoveReminder", ReminderID);
    if ($("Reminder" + ReminderID))
        $("Reminder" + ReminderID).style.display = 'none';
}

function OpenReminderDialog(EntryID)
{
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"ReminderBalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div><div class=\"Triangle\"></div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloon(mouseX, mouseY);

    GlobalCB("EntryEditor.OnRenderReminderForm", EntryID, x, y);
}

function SetReminder(EntryID, x, y)
{
    var type = $('ReminderType_value').value;
    var offset = $('ReminderOffset_value').value;

    $("ReminderBalloonDetails").innerHTML = "<p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> Saving reminder ... <br/><br/></p>";
    PositionBalloon(x, y);
    GlobalCB("EntryEditor.OnSetReminder", EntryID, type, offset);
}

/////////////////////////////////////////////////
// PAYMENT DIALOGS
/////////////////////////////////////////////////


function OpenSupplierPaymentDialog(EntryID)
{
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"PaymentBalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div><div class=\"Triangle\"></div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloon(mouseX, mouseY);

    GlobalCB("Finances.OnRenderSupplierPaymentDialog", EntryID, x, y);
}




function OpenPaymentDialog(InvoiceID, EntryID)
{
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"PaymentBalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div><div class=\"Triangle\"></div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloon(mouseX, mouseY);

    GlobalCB("Finances.OnRenderPaymentDialog", InvoiceID, EntryID, x, y);
}


function SetPayment(InvoiceID, EntryID, x, y)
{
    var date = $('PaymentDate').value;
    var amount = $('PaymentAmount').value;
    var receipt = $('PaymentReceipt').value;
    var account = $('PaymentAccount_value').value;

    $("PaymentBalloonDetails").innerHTML = "<p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + "  <br/><br/></p>";
    //PositionBalloon(x, y);
    GlobalCB("Finances.OnSetPayment", InvoiceID, EntryID, x, y, date, amount, receipt, account);
}

function OpenRefundDialog(InvoiceID) {
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"PaymentBalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div><div class=\"Triangle\"></div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloon(mouseX, mouseY);

    GlobalCB("Finances.OnRenderRefundDialog", InvoiceID, x, y);
}
function SetRefund(InvoiceID, x, y) {
    var date = $('PaymentDate').value;
    var amount = $('PaymentAmount').value;
    var receipt = $('PaymentReceipt').value;
    var account = $('PaymentAccount_value').value;

    $("PaymentBalloonDetails").innerHTML = "<p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + "  <br/><br/></p>";
    //PositionBalloon(x, y);
    GlobalCB("Finances.OnSetRefund", InvoiceID, x, y, date, amount, receipt, account);
}
function OnEnterKeyDown(event, command)
{
    if (event.keyCode == 13)
    {
        event.returnValue = false;
        if (event.preventDefault)
            event.preventDefault();

        if (command)
            setTimeout(command, 10);
            //eval(command); // must return immediately, otherwise sometimes doesn't work FF3
           
        return false;
    }
    return true;
}

/////////////////////////////////////////////////
// PROJECT DUPLICATE DIALOGS
/////////////////////////////////////////////////
function OpenDuplicateDialog(EntryID) {
    var b = new Balloon(null, 'DuplicateBalloon', 'top-or-bottom');

    GlobalCB("EntryEditor.OnRenderDuplicateDialog", EntryID);
}
function PerformDuplicate(mEntryID)
{
    var DupeType = '';

    if ($('DupeTypeSingle').checked)
        DupeType = 'SingleProject';
    else if ($('DupeTypeProjects').checked)
        DupeType = 'AllProjects';
    else if ($('DupeTypeAll').checked)
        DupeType = 'ProjectsAndTasks';

    var o =
    {
        EntryID: mEntryID,
        Type: DupeType,
        Date: $('DupeDate').value,
        DupeDateType: $('DupeDateType_value').value,
        EntityID: $('DupeClient_value').value,
        EntityName: $('DupeClient_text').value,
        DupeName: $('DupeName').value,
        TakeOwnership: $j('#TakeOwnership').attr('checked')
    }

    GetBalloon('DuplicateBalloon').html("<p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> Duplicating ... <br/><br/></p>");
    UI('EntryEditor.OnPerformDuplicate', o, function (r) {
        GetBalloon('DuplicateBalloon').html(r);
    });

}


function OnDeleteEvent(res)
{
   
    //
    // just refresh, OnRefreshHistory will try 
    // auto detect currently viewed Entry
    //
    RefreshHistory();
    if ($('OnDeleteEventCalls')
        && $('OnDeleteEventCalls').value)
        eval($('OnDeleteEventCalls').value);
     DialogBalloonHolderCancel();
}

function RefreshHistory() {
    RefreshActivityBoxes();
    
    if (!$('AttachmentsDiv'))
        return;
        
    GlobalCB('EntryEditor.OnRefreshHistory', CollectFormData());
}
function SetHistoryPage(page)
{
    $('HistoryPage').value = page;
    RefreshHistory();
}


/////////////////////////////////////////////////
// COMMENT COMPOSER
/////////////////////////////////////////////////
function NewComment(EntryID, EntityID,InvoiceID)
{
    var div = $('NewCommentHolder');
    $('CommentSubject').value = '';
    $('CommentReplyTo').value = '0';
    HtmlEdit_Reset('CommentHtml');
    $('CommentEntryID').value = EntryID;
    $('CommentEntityID').value = EntityID;
    $('CommentInvoiceID').value = InvoiceID;
    div.style.display = 'block';
    div.focus();
}

function ReplyComment(NotationID, Subject)
{
    HtmlEdit_Reset('CommentHtml');
    var div = $('NewCommentHolder');
    $('CommentSubject').value = 'Re: ' + Subject.replace(/re\:\s*/gi, '');
    $('CommentReplyTo').value = NotationID.toString();
    $('CommentEntryID').value = '0'; // will fetch from parent
    $('CommentEntityID').value = '0'; // will fetch from parent
    $('CommentHtml').value = '';
    div.style.display = 'block';
    div.focus();
    $('CommentHtml_window').focus();
}

function CancelComment(EntryID, EntityID, InvoiceID)
{
    var div = $('NewCommentHolder');
    $('CommentSubject').value = '';
    $('CommentReplyTo').value = '0';
    $('CommentEntryID').value = EntryID;
    $('CommentEntityID').value = EntityID;
    $('CommentInvoiceID').value = InvoiceID;
    div.style.display = 'none';
}

/////////////////////////////////////////////////
// CONTACT MERGE
/////////////////////////////////////////////////
function OpenMergeContactDialog(event, EntityID) {
    var MergeBalloon = new Balloon(event, 'MergeBalloon', 'bottom');
    UI('Contacts.OnRenderMergeDialog2', { Entities: EntityID }, function(r) { MergeBalloon.html(r); });
}

/////////////////////////////////////////////////
// CONTACT MAILINGLIST SUBSCRIBE
/////////////////////////////////////////////////
function OpenMailingListDialog(event, EntityID) {
    var MailingListBalloon = new Balloon(event, 'MailingListBalloon', 'bottom');
    UI('Contacts.OnRenderMailingListDialog', { Entities: EntityID }, function(r) { MailingListBalloon.html(r); });
}

/////////////////////////////////////////////////
// AVATAR DIALOG
/////////////////////////////////////////////////

var photoGuid;
var photoMethod;
function OpenPhotoUploadDialog(EditingGuid, PHRASE_SELECT_AVATAR, GlobalCBMethod) {
    photoGuid = EditingGuid;
    photoMethod = GlobalCBMethod;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"TriangleTop\"></div><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";
    s += BuildFileUploader('avatar', 'FilePhotoFlash', 'OnPhotoChanged', PHRASE_SELECT_AVATAR, 0, 0);
    s += "</div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    var x = mouseX;
    var y = mouseY;
    var balloon = $("PreviewBalloon");
    balloon.style.display = "block";
    balloon.style.left = (x - 110) + "px";
    balloon.style.top = (y + 30) + "px";
}

function OnPhotoChanged(o) {
    GlobalCB(photoMethod, o.Guid, photoGuid);
}

function OnImportFileUploaded(o) {
    $j('#CsvFile').val(o.Guid);
    $j('#CsvFileName').val(o.Name);
    BasicGrid_Command('ImportGrid', 'SetStep', 'csv');
    //GlobalCB(photoMethod, o.Guid, photoGuid);
}

var avatarGuid;
function OpenAvatarUploadDialog(EditingGuid, PHRASE_SELECT_AVATAR)
{
    avatarGuid = EditingGuid;

    var b = new Balloon(null, 'AvatarBalloon', 'top');
    b.html(BuildFileUploader('avatar', 'FilePhotoFlash', 'OnEntityAvatarChanged', PHRASE_SELECT_AVATAR, 0, 0));
    /*
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"TriangleTop\"></div><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += BuildFileUploader('avatar', 'FilePhotoFlash', 'OnEntityAvatarChanged', PHRASE_SELECT_AVATAR, 0, 0);
    //s += "<span id=\"PreviewBalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> Fetching contact details ... <br/><br/></p></span>";
    s += "</div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    var x = mouseX;
    var y = mouseY;
    var balloon = $("PreviewBalloon");
    balloon.style.display = "block";
    balloon.style.left = (x - 110) + "px";
    balloon.style.top = (y + 30) + "px";
    
    $j(balloon).keepOnScreen();*/
}

function OnEntityAvatarChanged(o)
{

    GlobalCB('ContactEditor2.OnEntityAvatarChanged', o.Guid, avatarGuid);
}


var catalogGuid;
function OpenCatalogPhotoUploadDialog(EditingGuid, PHRASE_SELECT_AVATAR)
{
    catalogGuid = EditingGuid;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"TriangleTop\"></div><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += BuildFileUploader('avatar', 'FilePhotoFlash', 'OnCatalogPhotoChanged', PHRASE_SELECT_AVATAR, 0, 0);
    //s += "<span id=\"PreviewBalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> Fetching contact details ... <br/><br/></p></span>";
    s += "</div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    var x = mouseX;
    var y = mouseY;
    var balloon = $("PreviewBalloon");
    balloon.style.display = "block";
    balloon.style.left = (x - 110) + "px";
    balloon.style.top = (y + 30) + "px";
}

function OnCatalogPhotoChanged(o)
{
    GlobalCB('Sales.OnCatalogPhotoChanged', o.Guid, catalogGuid);
}


function OnAddressModified(sender, guid)
{
    switch (sender)
    {
        case "fax":
        case "phone":
            {
                if ($('AddrPhone_' + guid))
                {
                    var newPhone = "";
                    if ($('PhoneNum_' + guid)
                        && $('PhoneNum_' + guid).value.length > 0)
                    {
                        newPhone += "p. " + HtmlEncode($('PhoneNum_' + guid).value);
                        if ($('PhoneExt_' + guid).value.length > 0
                            && $('PhoneExt_' + guid).value!="Ext.")
                            newPhone += " Ext. " + HtmlEncode($('PhoneExt_' + guid).value);
                        newPhone += "<br/>";
                    }
                    if ($('FaxNum_' + guid)
                        && $('FaxNum_' + guid).value.length > 0)
                    {
                        newPhone += "f. " + HtmlEncode($('FaxNum_' + guid).value);
                    }
                    $('AddrPhone_' + guid).innerHTML = newPhone;
                }
            }
            break;
        case "address":
            var newAddr = "";
            if ($('AddrSuburb_' + guid)
                && $('AddrSuburb_' + guid).value.length > 0
                && $('AddrSuburb_' + guid).className != "EmptyTextBox")
                newAddr += $('AddrSuburb_' + guid).value;
                
            if ($('AddrState_' + guid)
                && $('AddrState_' + guid).value.length > 0
                && $('AddrState_' + guid).className != "EmptyTextBox")
            {
                if (newAddr.length > 0)
                    newAddr += ", ";
                newAddr += $('AddrState_' + guid).value;
            }
            if ($('AddrCountry_' + guid + '_text')
                && $('AddrCountry_' + guid + '_text').value.length > 0)
            {
                if (newAddr.length > 0)
                    newAddr += ", ";
                newAddr += $('AddrCountry_' + guid + '_text').value;
            }

            if ($('PhoneAddr_' + guid))
                $('PhoneAddr_' + guid).innerHTML = HtmlEncode(newAddr);

            if ($('FaxAddr_' + guid))
                $('FaxAddr_' + guid).innerHTML = HtmlEncode(newAddr);

            break;
    }
}

function RefreshField(id)
{
    if (!$(id + '_TypeName'))
        return;
        
    var typeName = $(id+'_TypeName').value;
    var info = $(id+'_Info').value;
    GlobalCB('InlineEditField2`1[' + typeName + '].OnCallback',
            info, 'noop', CollectFormData(), '', '');
}

function GoToElement(id)
{
    var el = $(id);
    if (!el)
        return;

    switch (el.tagName.toLowerCase())
    {
        case "select":
        case "input":
            el.focus();
            break;
        default:
        
            var px = 0;
            var py = 0;
            while (el != null)
            {
                px += el.offsetLeft;
                py += el.offsetTop;
                el = el.offsetParent;
            }
            window.scrollTo(px, py);

            break;
    }
}
function OpenMap(EntityID, address)
{

    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\"><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<iframe id=\"MapWindow\" border=\"0\" style=\"width: 350px; height: 180px; border:0px;\" src=\"http://maps.veetro.com/?address=" + address + "&w=340px&h=150px\"></iframe>";
    s += "</div><div class=\"Triangle\"></div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloon(mouseX, mouseY);
}

var _JournalWidgetTimeChange;
function OnJournalWidgetTimeChanged(sender)
{
    if (_JournalWidgetTimeChange)
        return;

    // EntryEditor now has unique field names
    // need to truncate the '_d6sd' Editing Guid garbage at the end and
    // use this to find other controls on the page which will all end with
    // the same unique id.
    var EditingGuid = '';
    if (sender.indexOf('_') > -1) {
        EditingGuid = sender.substring(sender.indexOf('_'));
        sender = sender.substring(0, sender.indexOf('_'));
    }

    var JournalTimeStart = $('JournalTimeStart') ? $('JournalTimeStart') : $('timeStart' + EditingGuid);
    var JournalTimeEnd = $('JournalTimeEnd') ? $('JournalTimeEnd') : $('timeEnd' + EditingGuid);
    var JournalHours = $('JournalHours' + EditingGuid);
    var JournalMins = $('JournalMins' + EditingGuid);

    if (!JournalTimeEnd)
        return;

    _JournalWidgetTimeChange = true;
    var isCalendarPresent = typeof dragDateStart != 'undefined';

    switch (sender) { // this is sender's ID with editing guid truncated
        case 'dateStart':
        case 'dateEnd':
        case 'timeStart':
        case 'timeEnd':
        case 'JournalTimeStart':
        case 'JournalTimeEnd':
            {
                var JournalTimeStartString = JournalTimeStart.value;
                var JournalTimeEndString = JournalTimeEnd.value;

                if (!JournalTimeStartString)
                    JournalTimeStartString = "00:00";

                if (!JournalTimeEndString)
                    JournalTimeEndString = "00:00";

                if (JournalTimeStartString.search(/^\d{1,2}:\d{2}/i) == -1
                    || JournalTimeEndString.search(/^\d{1,2}:\d{2}/i) == -1) {
                    _JournalWidgetTimeChange = false;
                    return;
                }

                var date = $('dateStart' + EditingGuid) ? $('dateStart' + EditingGuid).value : FormatDate((isCalendarPresent ? dragDateStart : new Date()), 'd-MMM-yyyy');
                var dateEnd = $('dateEnd' + EditingGuid) ? $('dateEnd' + EditingGuid).value : FormatDate((isCalendarPresent ? dragDateEnd : new Date()), 'd-MMM-yyyy');
                var start = parseDate(date + ' ' + JournalTimeStartString, 'd-MMM-yyyy ' + prefs.ShortTimePattern);
                var end = parseDate(dateEnd + ' ' + JournalTimeEndString, 'd-MMM-yyyy ' + prefs.ShortTimePattern);
                if (end < start)
                    end = parseDate(FormatDate(new Date(start).addDays(1), 'd-MMM-yyyy') + ' ' + JournalTimeEnd.value, 'd-MMM-yyyy ' + prefs.ShortTimePattern);

                var diff = end - start;
                var hours = Math.floor(diff / TO_HOURS);
                var minutes = Math.floor((diff - (hours * TO_HOURS)) / TO_MINS);
                var allDay = (start.getHours() + start.getMinutes()) == 0 && (end.getHours() + end.getMinutes()) == 0;
                if (allDay)
                    hours += 24; //inclusive
                if ($('dateAllDay' + EditingGuid))
                    $('dateAllDay' + EditingGuid).value = allDay ? "1" : "0";
                JournalHours.value = hours;
                JournalMins.value = minutes;
                if (isCalendarPresent) {
                    dragDateStart = start;
                    dragDateEnd = end;
                }
            } break;
        case "JournalMins":
        case "JournalHours":
            {
                if (!JournalHours.value
                    || !JournalMins.value) {
                    _JournalWidgetTimeChange = false;
                    return;
                }
                var date = $('dateStart' + EditingGuid) ? $('dateStart' + EditingGuid).value : FormatDate((isCalendarPresent ? dragDateStart : new Date()), 'd-MMM-yyyy');
                var dateEnd = $('dateEnd' + EditingGuid) ? $('dateEnd' + EditingGuid).value : FormatDate((isCalendarPresent ? dragDateEnd : new Date()), 'd-MMM-yyyy');

                var start = parseDate(date + ' ' + JournalTimeStart.value, 'd-MMM-yyyy ' + prefs.ShortTimePattern);
                var end = new Date(start).addMinutes(parseFloat(JournalHours.value) * 60 + parseFloat(JournalMins.value));

                if (end < start)
                    end = parseDate(FormatDate(new Date(start).addDays(1), 'd-MMM-yyyy') + ' ' + JournalTimeEnd.value, 'd-MMM-yyyy ' + prefs.ShortTimePattern);

                JournalTimeEnd.value = FormatDate(end, prefs.ShortTimePattern);
                if ($('dateEnd' + EditingGuid))
                    $('dateEnd' + EditingGuid).value = FormatDate(end, 'd-MMM-yyyy');

                JournalTimeStart.title = start;
                JournalTimeEnd.title = end;

                var allDay = (start.getHours() + start.getMinutes()) == 0 && (end.getHours() + end.getMinutes()) == 0;
                if ($('dateAllDay' + EditingGuid))
                    $('dateAllDay' + EditingGuid).value = allDay ? "1" : "0";
                if (isCalendarPresent) {
                    dragDateStart = start;
                    dragDateEnd = end;
                }
            } break;

    }

    _JournalWidgetTimeChange = false;
}
function roundNumber(num, dec)
{
    var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
    return result;
}
function SignaturePaste(editor)
{
    GlobalCB("EntryEditor.OnSignaturePaste", editor);
}
function SignatureEdit()
{
    var x = mouseX;
    var y = mouseY;
    var s = "";
    var b = new Balloon(null, "SigBalloon", 'top');
//    b.html();
//    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\" style=\"width: 400px;\"><div class=\"Inner\">";
//    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

//    s += "<span id=\"SigBalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
//    s += "</div><div class=\"Triangle\"></div></div>";
//    $("DialogBalloonHolder").innerHTML = s;

//    PositionBalloon(mouseX, mouseY);

    GlobalCB("EntryEditor.OnSignatureEditDialog", x, y, "edit");
}

function LeadProfitCalculate()
{
    GlobalCB('Sales.OnCalculateProfits', CollectFormData());
}

function LeadConversionOpen(leadid) 
{
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\" style=\"width: 400px;\"><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"LeadConvertDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div><div class=\"Triangle\"></div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloon(mouseX, mouseY);

    GlobalCB("Sales.OnLeadConversionDialog", x, y, leadid);
}
var alertTimeout;
function PollForAlerts() {

    if (alertTimeout)
        clearTimeout(alertTimeout);

    if ($j('#AlertNotifyHolder').exists())
        UI("Module.GetAlerts2", null, function(r) {

            if (r) {
                $j('#AlertNotifyHolder').html(r);
                $j('#AlertNotifyHolder').fadeIn();
            }
            else {
                $j('#AlertNotifyHolder').css('display', 'none');
                //$j('#AlertNotifyHolder').fadeOut();
            }
            alertTimeout = setTimeout('PollForAlerts()', 60 * 1000);
        });
}

function Community_AvatarDialogOpen() {
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\" style=\"width: 400px;\"><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"AvatarDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloonTop(mouseX, mouseY);

    GlobalCB("Community.OnAvatarDialog", CollectFormData());
}
function Community_AvatarDialogApply() {
    GlobalCB("Community.OnAvatarDialog", CollectFormData());
}
function InsertText(input, insTexte, startTag, endTag)
{

     if (document.all)
     {
         if (input.createTextRange)
         {
              input.focus(input.caretPos);
              input.caretPos = document.selection.createRange().duplicate();
              if(input.caretPos.text.length>0)
              {
               input.caretPos.text = startTag + input.caretPos.text + endTag;
              }
              else
              {
                input.caretPos.text = startTag + " " + insTexte + " " + endTag;
              }
        }
        else 
        {   
            input.value += startTag + insTexte + endTag;
        }
    }
    else
    {
        input.focus();
        var start = input.selectionStart;
        var end = input.selectionEnd;
        if (!insTexte)
            insTexte = input.value.substring(start, end);
        newVal = input.value.substring(0, start) + startTag + insTexte + endTag +input.value.substring(end);
        start = (input.value.substring(0, start) + startTag + insTexte + endTag).length;
        input.value = newVal;
        input.selectionEnd = 0;
        input.selectionStart = start;
        
    }
}

function FStyle(textareaid, tag)
{
    var input = document.getElementById(textareaid);
    if (!input)
        return;
    InsertText(input, '', '['+tag+']', '[/'+tag+']');
}
function FUrl(textareaid)
{
     var input = document.getElementById(textareaid);
    if (!input)
        return;
    var link=prompt('Enter url:', '');
    if (link)
    InsertText(input, '', '[url='+link+']', '[/url]');
}
function FImageUpload() {
    //
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\" style=\"width: 300px;\"><div class=\"TriangleTop\"></div><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"AttachmentDetails\">" + BuildFileUploader('todisk', 'ForumAttachment', 'FOnUploadComplete', 'Select an image...', '', '') + "</span>";
    s += "</div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloonTop(mouseX, mouseY);

}
function FOnUploadComplete(o) 
{
    GlobalCB('Community.OnUploadComplete', o.Guid, o.Name, o.MIMEType);
}


function OpenBalloonBottom(func, action, arg)
{
    var x = mouseX;
    var y = mouseY;
   
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\" style=\"width: 400px;\"><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"BalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div><div class=\"Triangle\"></div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloon(mouseX, mouseY);

    GlobalCB(func, x, y,  action, arg);
}

function OpenBalloonTop(func, action, arg)
{
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\" style=\"width: 400px;\"><div class=\"TriangleTop\"></div><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"BalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloonTop(mouseX, mouseY);

    GlobalCB(func, x, y,  action, arg);
}
var NewActivityBalloon;
function OnNewActivityCancel()
{
    if (NewActivityBalloon)
        $("DialogBalloonHolder").removeChild(NewActivityBalloon);
        
}
function OpenNewActivity()
{
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"NewActivityBalloon\" class=\"NewEntryBaloon\" style=\"width: 400px;\"><div class=\"TriangleTop\"></div><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"OnNewActivityCancel();\" class=\"Close\"></a>";

    s += "<span id=\"BalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div></div>";
    
    NewActivityBalloon = document.createElement("span");
    NewActivityBalloon.innerHTML = s;
  
    $("DialogBalloonHolder").appendChild(NewActivityBalloon);
 
    PositionBalloonTop(mouseX, mouseY, "NewActivityBalloon");

    GlobalCB('EntryEditor.OnRenderNewActivityDialog', x, y,  'init', CollectFormData());
}

function OpenBalloonTopRight(func, action, arg)
{
    var x = mouseX;
    var y = mouseY;
    var s = "";
    s += "<div id=\"PreviewBalloon\" class=\"NewEntryBaloon\" style=\"width: 400px;\"><div class=\"TriangleTopRight\"></div><div class=\"Inner\">";
    s += "<a href=\"javascript:;\" onclick=\"DialogBalloonHolderCancel();\" class=\"Close\"></a>";

    s += "<span id=\"BalloonDetails\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
    s += "</div></div>";
    $("DialogBalloonHolder").innerHTML = s;

    PositionBalloonTop(mouseX, mouseY);

    GlobalCB(func, x, y,  action, arg);
}

function ShowShareLeads()
{
     OpenBalloonBottom("Sales.OnShareLeadsDialog", 'edit');
}

function OpenAttachmentDialog(EntryID, EntityID, LeadID, InvoiceID)
{
    OpenBalloonBottom("Documents.OnAttachmentDialog", EntryID+'|'+EntityID+'|'+LeadID+'|'+InvoiceID);
}
function OnAttachmentUploaded(o)
{
   RefreshHistory();
   DialogBalloonHolderCancel();

}

/**
*
*  Unselectable text
*  http://www.webtoolkit.info/
*
**/

var Unselectable = {

    enable: function(e) {
        var e = e ? e : window.event;

        if (e.button != 1) {
            var target = e.target ? e.target : e.srcElement;
            if (target) {
                if (target.className && target.className.indexOf('NoSelect') > -1) {
                    return false;
                }
            }
        }
    },

    disable: function() {
        return true;
    }

}

if (typeof (document.onselectstart) != "undefined") {
    document.onselectstart = Unselectable.enable;
} else {
    document.onmousedown = Unselectable.enable;
    document.onmouseup = Unselectable.disable;
}

function GetDocumentHeight() {
    var pageHeight;
    if (window.innerHeight && window.scrollMaxY) // Firefox 
    {
        pageWidth = window.innerWidth + window.scrollMaxX;
        pageHeight = window.innerHeight + window.scrollMaxY;
    }
    else if (document.body.scrollHeight > document.body.offsetHeight) // all but Explorer Mac
    {
        pageWidth = document.body.scrollWidth;
        pageHeight = document.body.scrollHeight;
    }
    else // works in Explorer 6 Strict, Mozilla (not FF) and Safari
    {
        pageWidth = document.body.offsetWidth + document.body.offsetLeft;
        pageHeight = document.body.offsetHeight + document.body.offsetTop;
    }
    return pageHeight;
}
function PlayVideo(videoid, title) {
    var w = 570;
    var h = 370;
    var b = new Balloon(null, 'VidBalloon', 'none');
    var el = $j('#' + b.id);
    el.draggable({ handle: 'h1' });
    el.css({ width: 'auto', height: 'auto' });
    b.title(title);
   

    //var movie = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="548" height="328" id="viddler_3c0b67ed"><param name="movie" value="http://www.viddler.com/simple/' + viddlerid + '/" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><embed src="http://www.viddler.com/simple/' + viddlerid + '/" width="548" height="328" type="application/x-shockwave-flash" allowScriptAccess="always" allowFullScreen="true" name="viddler_3c0b67ed"></embed></object>';
    var movie = '<object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/' + videoid + '&hl=en&fs=1&rel=0&color1=0x3a3a3a&color2=0x999999&hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/' + videoid + '&hl=en&fs=1&rel=0&color1=0x3a3a3a&color2=0x999999&hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>'
    b.html(movie);

//    var s = new StringBuilder();
//    s.Append( '<div id="VideoLayer">');
//    s.Append('<div style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: black; opacity: 0.4;"></div>');
//    s.Append('<div class="NewEntryBaloon" style="width: ' + w + 'px; height: ' + h + 'px; position: fixed; top: 50%; left: 50%; margin-left:-' + (w / 2) + 'px; margin-top: -' + (h / 2) + 'px;">');
//     s.Append('<a class="Close" onclick="CloseVideo();" href="javascript:;"/></a><h1>' + title + '</h1><hr/>');
//     s.Append(movie);
//     s.Append( '</div>');
//     s.Append('</div>');

//     CloseVideo();

//     var h = document.createElement("span");

//     h.innerHTML = s.toString();
//     document.body.appendChild(h);

}
function CloseVideo() {
    if ($('VideoLayer'))
        $('VideoLayer').parentNode.removeChild($('VideoLayer'))
}
function SubmitFullSearch() {
    window.location = '/search?kw=' + URLEncode($('FullSearchText').value)
}
function API(webMethod, data, onsuccess)
{
    $j.ajax({
        url: '/Json/' + webMethod,
        type: 'POST',
        data: $j.toJSON(data),
        dataType: 'json',
        contentType: 'application/json; charset=utf-8',
        success: onsuccess,
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(XMLHttpRequest.responseText);
        }
    });
}
function UI(webMethod, data, onsuccess, sender) {
    ClearLoadingGlyph();
    LoadTimeout = setTimeout("ShowLoadingGlyph();", 2000);
    $j.ajax({
        url: '/UIJson/' + webMethod+'?path='+window.location,
        type: 'POST',
        data: $j.toJSON(data),
        dataType: 'json',
        contentType: 'application/json; charset=utf-8',
        success: onsuccess,
        context: sender,
        complete: function() { ClearLoadingGlyph(); },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
        if (XMLHttpRequest.responseText
            && XMLHttpRequest.responseText.indexOf('0x80070020') == -1
            && !XMLHttpRequest.responseText.startsWith('<html>')
            )
                alert(XMLHttpRequest.responseText);
        }
    });
}

function DynamicHelpShow(key) {

    API('GetTranslation', { 'key': key },
        function (r) {

            var helpBalloon = new Balloon(null, 'helpBalloon', 'none');
            helpBalloon.html(r);
            $j('#helpBalloon').draggable();
            $j('#helpBalloon').css({zIndex:10000});
        });
}

function DynamicHelpClose() {
    $j('#HelpRegion').slideUp(function() { $j('#HelpRegion').remove(); });
}

var _IsBatchWatermarking = false;

//
// ======================= PAGE READY ROUTINE =======================
//
$j(document).ready(function () {

    $j(document).unbind('ready');

    $j(document.body).mousemove(function (e) {
        mouseX = e.pageX;
        mouseY = e.pageY;

        // Close preview balloons out of bounds
        if (BalloonBounds
            && !BalloonBounds.IsReset()) {
            if (!BalloonBounds.IsMouseInBounds()
                && new Date().getTime() - BalloonBounds.LastSet > 100) {
                //window.status = $j(e.currentTarget).context.nodeName;
                if (!BubbleRollOffTimeout)
                    BubbleRollOffTimeout = setTimeout("PopupPreviewBubbleCancelDelayed();", 1000);
                //BalloonBounds.Reset();
            }
            else {
                if (BubbleRollOffTimeout)
                    clearTimeout(BubbleRollOffTimeout);
                BubbleRollOffTimeout = null;
            }
        }

    });

    $j(document.body).mouseup(function (e) {
        if (typeof (CloseAllCombos) == "function")
            CloseAllCombos();
        if (typeof (allBallooons) != 'undefined')
            for (var i = 0; i < allBallooons.length; i++)
                if (allBallooons[i].isDisposed)
                    allBallooons[i].close();
    });

    $j(document.body).unload(function (e) {
        IsNavigatingAway = true;
    });
    $j(document.body).resize(function () {
        InitialiseAllTabs();
    });


    AutoWatermark();

    $j("[readonly='readonly']").makeReadOnly();

    // Setup tabs
    //InitialiseAllTabs();
    $j(document.body).resize();

    // [2.6 only] Hide/show side-bar and wire up events
    if ($j('.SideBarHandle').exists()) {
        if ($j.cookie('sidebar') == '1') {
            $j('.SideBarHandle').removeClass('SideBarHandleOut');
            $j('.SideBarHandle').addClass('SideBarHandleIn');
            $j('.SideBar').css('display', 'none');
        }
        $j('.SideBarHandle').click(function () {
            if ($j('.SideBarHandle').hasClass('SideBarHandleOut')) {
                $j.cookie('sidebar', '1');
                $j('.SideBarHandle').removeClass('SideBarHandleOut');
                $j('.SideBarHandle').addClass('SideBarHandleIn');
                $j('.SideBar').css('display', 'none');
            }
            else {
                $j.cookie('sidebar', '0');
                $j('.SideBarHandle').removeClass('SideBarHandleIn');
                $j('.SideBarHandle').addClass('SideBarHandleOut');
                $j('.SideBar').css('display', 'table-cell');
            }
        });
    }

    // [All versions] Make .DropDownMenu's popups show above when appropriate
    CheckDropDownPopupPositions();
    InitAdvancedDetails();

    // [2.6 only] Render bookmarks
    if ($j('#Bookmarks').exists()) {
        BookmarksInit();
    }
});

function AutoWatermark() {
    $j('.AutoWatermark').watermark();
    setTimeout("AutoWatermark()", 500);
}

// Make .DropDownMenu's popups show above when appropriate
function CheckDropDownPopupPositions() {
    var footer = $j('#Foot');
    if (footer.exists()) {
        var footerBottom = footer.bottom();
        $j('.DropDownMenu ul ul').each(function(index) {
            var dd = $j(this);
            if (dd.attr('orig-margin')) {
                dd.css('margin', dd.attr('orig-margin'));
            }
            var overlap = dd.bottom() - footerBottom;
            if (overlap > 0) {
                var orig = dd.css('margin-top');
                if (!dd.attr('orig-margin'))
                    dd.attr('orig-margin', orig);
                overlap = dd.bottom() - 2 - dd.parent().offset().top;
                dd.css('margin-top', (overlap * -1) + 'px');
                if (dd.offset().top < 0)
                    dd.css('margin-top', orig);
            }
            //else 
        });
    }
}

//
// =================================================================
//


//
// TRANSLATOR
//
var _CurrentUIInfo;
var _Changes;
var _CurrentKey;
var _TranslatorWindow;
function OpenTranslatorExcel(language) {
   // var UIBuildRequest = new Object();
  //  UIBuildRequest.Language = language ? language : null;
    window.location = '/UIJson/TranslationEditor.SendReference?Language=' + language;
   // UI('TranslationEditor.SendReference', UIBuildRequest, function(UIInfo) { });
}
function OpenTranslatorExcelUpload(language) {
    var b = new Balloon(null, 'LanguageCsvDialog', 'none');
    b.title('Upload *.CSV translation file');
    b.html('<p>Your excel file should be saved as either a utf-8 <b>Comma Delimited *.csv</b> or a <b>TAB delimited Unicode *.txt</b> file.</p>' +
    BuildFileUploader('todisk', b.id, "TranslatorExcelUploaded",
    'Select *.csv file', 0, 0, 0, 0, 0));
}
function TranslatorExcelUploaded(o)
{
    var b = GetBalloon(o.ID);
    //o.Name, Guid: o.Guid, MIMEType: o.MIMEType
    b.html('Processing file...');
    UI('TranslationEditor.ProcessReference', { UploadGuid: o.Guid, Language: _CurrentUIInfo.Language }, function (r) {
        b.html(r);
    }, b);
}
function OpenTranslator(language) {

    
    _TranslatorWindow = new Balloon(window.event, "Translator", 'none');
    _TranslatorWindow.title('Initializing editor');
    
    
//    if (!$j('#Translator').exists()) {
//        $j(document.body).append('<div id="Translator" style="display:none"><h1>Initializing editor</h1><p>Please wait..</p></div>');
//    }
//    $j('#Translator').center(true);
//    $j('#Translator').fadeIn();
  
    var UIBuildRequest = new Object();
    UIBuildRequest.Language = language ? language : null;
    UI('TranslationEditor.BuildUI', UIBuildRequest, function (UIInfo) {
        var s = new StringBuilder();
        _CurrentUIInfo = UIInfo;
        _CurrentUIInfo.Modified = [];

        //s.Append('<h1 style="cursor:move;">Translation for ' + _CurrentUIInfo.Language + '</h1>');
        s.Append('<table><tr valign="top"><td><h2>Keys</h2>');
        s.Append('<input type="text" style="width:200px;" id="KeysListSearch" class="AutoWatermark" title="Search/Filter"/>');
        s.Append('<select style="min-width:200px;" size="20" id="KeysList" name="KeysList" onchange="OnTranslatorSelect()">');
        for (var k in _CurrentUIInfo.Keys) {
            if (k == "Language" || k == "Keys")
                continue;
            s.Append('<option>' + k + '</option>');
        }
        s.Append('</select>');
        s.Append('</td><td width="100%">');
        s.Append('<h2>English Edition</h2><div id="TransEnglish" style="height: 100px; overflow-y: auto; margin: 0 0 5px 0p;"></div>');
        s.Append('<h2>Translation (do your thing here):</h2><textarea id="TransNative" disabled="disabled" onkeyup="OnTranslatorEdit()" class="CodeTextBox"></textarea>');
        s.Append('<div id="TransFeedback" style="display:none;"></div>');
        s.Append('</td></tr></table>');

        s.Append('<div class="SaveTools"><hr/>');
        s.Append('<a href="javascript:OpenTranslatorExcel(\'' + _CurrentUIInfo.Language + '\');" style="float:left;">Download for Excel</a>');
        s.Append('<br/><a href="javascript:OpenTranslatorExcelUpload(\'' + _CurrentUIInfo.Language + '\');" style="float:left;">Upload *.CSV File</a>');

        s.Append('<span id="TransChangeCount" style="font-style:italic;color:#555555;">0 changes</span> <input type="Button" class="Button" value=" Save Changes " onclick="OnTranslatorSave()"/> or <a href="javascript:OnTranslatorClose();">cancel</a></div>');

        _TranslatorWindow.html(s.ToString());
        _TranslatorWindow.title('Translations for ' + _CurrentUIInfo.Language);
        $j('#Translator').css('width', '800px');
        $j('#Translator').draggable({ handle: 'h1' });
        $j('#KeysListSearch').bind('keyup', function () {
            OnFilterTranslator();
        });
        //        $j('#Translator').html(s.ToString());
        //        $j('#Translator').center(true);
        //        $j('#Translator').fadeIn();
        //        $j('#Translator').draggable({ handle: 'h1' });

    });
}
function OnFilterTranslator() {
    var s = new StringBuilder();
    var search = $j('#KeysListSearch').val();
    
    for (var k in _CurrentUIInfo.Keys) {
            if (k == "Language" || k == "Keys")
                continue;
            if (!search
                || k.match(search, 'i')
                || (_CurrentUIInfo.Keys[k] && _CurrentUIInfo.Keys[k].match(search,'i'))
                || (_CurrentUIInfo.Native[k] && _CurrentUIInfo.Native[k].match(search,'i')))
            s.Append('<option>' + k + '</option>');
        }
        $j('#KeysList').html(s.ToString());
}
function OnTranslatorClose() {
    _TranslatorWindow.close();
    _TranslatorWindow = null;
    //$j('#Translator').fadeOut(function() { $j(this).remove(); });
}
function OnTranslatorSelect()
{
    var val = $j('#KeysList').val();
    _CurrentKey = val;
    if (_CurrentKey) {
        $j('#TransEnglish').text(_CurrentUIInfo.Keys[_CurrentKey]);
        $j('#TransNative').val(_CurrentUIInfo.Native[_CurrentKey]);
        $j('#TransNative').attr('disabled', null);
    }
    else {
        $j('#TransNative').attr('disabled', 'disabled');
    }
     $j('#TransFeedback').fadeOut();
}
function OnTranslatorEdit() {
    if (!_CurrentKey)
        return;
    var val = $j('#TransNative').val();
    var eng = _CurrentUIInfo.Keys[_CurrentKey];

    var tags = eng.match(/\{\d+\}/g);
    var missing = '';
    for (var i in tags) {
        var tag = tags[i];
        if (val.indexOf(tag) == -1) {
            if (missing.length > 0)
                missing += ', ';
            missing += tag;
        }
    }

    if (missing.length > 0) {
        $j('#TransFeedback').addClass('FeedbackError');
        $j('#TransFeedback').html('The following &quot;replacement fields&quot; are absent from your translation: <b>' + missing + '</b>. This translation cannot be accepted until you add all replacement fields.');
        if ($j('#TransFeedback').css('display') != 'block')
            $j('#TransFeedback').fadeIn();
        return;
    }
    else {
        if ($j('#TransFeedback').css('display') == 'block')
            $j('#TransFeedback').fadeOut();
    }
    
    _CurrentUIInfo.Native[_CurrentKey] = val;
    if (_CurrentUIInfo.Modified.indexOf(_CurrentKey) == -1) {
        _CurrentUIInfo.Modified.push(_CurrentKey);
        $j('#TransChangeCount').html(_CurrentUIInfo.Modified.length + " changes");
    }
}
function OnTranslatorSave() {
    $j('#TransFeedback').removeClass('FeedbackSuccess');
    $j('#TransFeedback').removeClass('FeedbackError');
    $j('#TransFeedback').removeClass('FeedbackInfo');
    $j('#TransFeedback').addClass('FeedbackInfo');
    $j('#TransFeedback').html('Saving, please wait...');
    $j('#TransFeedback').fadeIn();
     
    var UICommitRequest = new Object();
    UICommitRequest.Language = _CurrentUIInfo.Language;
    UICommitRequest.Native = new Object();
    for (var i = 0; i < _CurrentUIInfo.Modified.length; i++) {
        var s = _CurrentUIInfo.Modified[i];
        UICommitRequest.Native[s] = _CurrentUIInfo.Native[s];
    }
    UI('TranslationEditor.Commit', UICommitRequest, function(UICommitResult) {
        if (UICommitResult.Success) {
            $j('#TransFeedback').addClass('FeedbackSuccess');
            $j('#TransFeedback').html('Your changes have been saved! Try your changes in another window or <a href="javascript:OnTranslatorClose();">click here</a> to close this editor.');
            $j('#TransFeedback').fadeIn();
            _CurrentUIInfo.Modified = [];
            $j('#TransChangeCount').html("0 changes");
        }
        else {
            $j('#TransFeedback').addClass('FeedbackError');
            $j('#TransFeedback').html(UICommitResult.Message);
        }
    });
}

function GettingStartedWizardOpen() {
    if (!$j('#Wizard').exists()) {
        $j('#aspnetForm').append("<div id='WizardBg'></div><div id='Wizard'></div>");
    }
    GlobalCB('Home.OnRenderGettingStarted', CollectFormData());
}
function GettingStartedWizardClose() {
    $j('#WizardBg').fadeOut(function() { $j('#WizardBg').remove(); });
    $j('#Wizard').fadeOut(function() { $j('#Wizard').remove(); })
}

//
// BOOKMARKS
//
var _CurrentPageBookmark;
var _Bookmarks;
function BookmarksUID(obj) {
    if (obj == null)
        return null;
    return obj.Type + obj.PrimaryKey;
}
function BookmarksInit() {
    _Bookmarks = $j.parseJSON($j('#BookmarkData').val());
    _CurrentPageBookmark = _Bookmarks.Current;

    var s = new StringBuilder();
    
    s.Append('<h1>' + _Bookmarks.WORD_BOOKMARKS + '</h1>');
    s.Append('<span id="BookmarkExpColLink" style="position: absolute; width: 200px; margin-top:-25px; text-align:right;display:block;"></span>');
    s.Append('<div id="BookmarksInner" style="display:' + (_Bookmarks.IsCollapsed?'none':'block') + ';">');
    BookmarksRenderItems(s)
    s.Append('</div>');
    $j('#Bookmarks').html(s.ToString());
    SetBookmarkExpColLink();
    BookmarksWire();
}
function SetBookmarkExpColLink() {
    $j('#BookmarkExpColLink').html('<a href="javascript:;" onclick="BookmarksToggleCollapse()" class="' + (_Bookmarks.IsCollapsed ? 'ExpandLink' : 'CollapseLink') + '">' + (_Bookmarks.IsCollapsed ? _Bookmarks.WORD_EXPAND : _Bookmarks.WORD_COLLAPSE) + '</a>');
}
function BookmarksUpdate() {
    var s = new StringBuilder();
    BookmarksRenderItems(s);
    $j('#BookmarksInner').html(s.ToString());
    BookmarksWire();
}
function BookmarksWire() {
    $j('#BookmarksInner li').unselectable();
    $j('#BookmarksInner li').droppable({ hoverClass: 'DragHover', accept: '.BMRow', drop: function(event, ui) {
        BookmarksSwitchIndex($j(ui.draggable), $j(this));
    } 
    });
    $j('#BookmarksInner li').draggable({ revert: true, containment: 'parent' });
    //$j('#BookmarksInner li').mousedown(function() { $j(this).draggable({ revert: true }); });
    //$j('#BookmarksInner li').mouseup(function() { $j(this).draggable(); });
}
function BookmarksFind(uid) {
    for (var idx in _Bookmarks.Rows) {
        var i = _Bookmarks.Rows[idx];
        if (BookmarksUID(i) == uid)
            return i;
    }
    return null;
}
function BookmarksSwitchIndex(source, target) {
    var html = source.html();
    source.remove();
    target.before(html);
    BookmarksWire();
    var bookSource = BookmarksFind(source.attr('id').substring(1));
    var bookTarg = BookmarksFind(target.attr('id').substring(1));
    bookSource.Index = bookTarg.Index;
    UI('UserBookmarks.Set', bookSource, function(r) {
        _Bookmarks.Rows = r.Rows;
        BookmarksUpdate();
    });
    
}
function BookmarksRenderItems(s) {
    if (_CurrentPageBookmark.PrimaryKey) {
        if (_Bookmarks.IsCurrentBookmarked)
            s.Append('<a href="javascript:;" class="DelPage" onclick="BookmarkRemove(BookmarksUID(_CurrentPageBookmark));">' + _Bookmarks.WORD_REMOVE_BOOKMARK + '</a>');
        else
            s.Append('<a href="javascript:;" class="AddPage" onclick="BookmarkSet(_CurrentPageBookmark);">' + _Bookmarks.WORD_ADD_BOOKMARK + '</a>');
    }
    else
        s.Append('<span  class="AddPage" style="cursor:not-allowed">' + _Bookmarks.WORD_ADD_BOOKMARK_NOT_ALLOWED + '</span>');
        
    var total = _Bookmarks.Rows.length;
    if (total == 0) {
        s.Append('<p style="text-align:center;"><small>' + _Bookmarks.WORD_NO_BOOKMARKS + '</small></p>');
        return;
    }
    s.Append('<ul>');
    for (var idx = 0; idx < _Bookmarks.Rows.length; idx++) {
        if (_Bookmarks.ViewSize != 0 && idx >= _Bookmarks.ViewSize)
            break;
        var i = _Bookmarks.Rows[idx];

        var uid = BookmarksUID(i);
        s.Append('<li id="r' + uid + '" class="BMRow"><table><tr><td width="20"><img src="/v2.0/images/CalendarViewType_' + i.Icon + '.png"/></td><td width="100%"><a href="' + i.Url + '" title="' + i.NameHtml + '">' + i.NameHtml + '</a></td><td><a href="javascript:;" onclick="BookmarkRemove(\'' + uid + '\')" class="Delete">x</a></td></tr></table></li>');
    }
    s.Append('</ul>');
    s.Append('<div id="ViewSizes">');
    for (var i = 5; i <= 20 && i < total; i+=5) {
        s.Append('[');
        if (_Bookmarks.ViewSize != i)
            s.Append('<a href="javascript:;" onclick="BookmarksSetViewSize(' + i + ')">');
        s.Append(i);
        if (_Bookmarks.ViewSize != i)
            s.Append('</a>');
        s.Append('] ');
    }
    if (total > 5) {
        s.Append('[');
        if (_Bookmarks.ViewSize != 0)
            s.Append('<a href="javascript:;" onclick="BookmarksSetViewSize(0)">');
        s.Append(_Bookmarks.WORD_ALL);
        if (_Bookmarks.ViewSize != 0)
            s.Append('</a>');
        s.Append('] ');
    }
    s.Append('</div>');
}
function BookmarkRemove(uid) {
    $j('#r' + uid).fadeOut();
    var i = BookmarksFind(uid);
    if (!i)
        return;
    i.Delete = true;
    UI('UserBookmarks.Set', i, function(r) {
        if (BookmarksUID(i) == BookmarksUID(_CurrentPageBookmark))
            _Bookmarks.IsCurrentBookmarked = false;
        _Bookmarks.Rows = r.Rows;
        BookmarksUpdate();
    });
}
function BookmarkSet(row) {
    UI('UserBookmarks.Set', row, function(r) {
        if (BookmarksUID(row) == BookmarksUID(_CurrentPageBookmark))
            _Bookmarks.IsCurrentBookmarked = true;

        // Update bookmarks widget if present
        if (_Bookmarks) {
            _Bookmarks.Rows = r.Rows;
            BookmarksUpdate();
        }
        // Update arbitrary bookmark glyphs on the page as well
        var isBookmarked = false;
        for (var x = 0; x < r.Rows.length; x++) {
            if (BookmarksUID(r.Rows[x]) == BookmarksUID(row))
                isBookmarked = true;
        }
        $j('.BK_' + BookmarksUID(row)).html('<img src="/v2.0/images/' + (isBookmarked ? "book_added.png" : "book_notadded.png") + '"/>')
    });
}

function BookmarkToggle(type, primarykey) {
    var obj = new Object();
    obj.Type = type;
    obj.PrimaryKey = primarykey;
    obj.Toggle = true;
    BookmarkSet(obj);
    
}
function BookmarksToggleCollapse() {
    var div = $j('#BookmarksInner');
    if (div.css('display') == 'block') {
        div.slideUp();
        _Bookmarks.IsCollapsed = true;
    }
    else {
        div.slideDown();
        _Bookmarks.IsCollapsed = false;
    }
    SetBookmarkExpColLink();
    UI('UserBookmarks.SetCollapseState', _Bookmarks.IsCollapsed, null);
}
function BookmarksSetViewSize(size) {
    _Bookmarks.ViewSize = size;
    UI('UserBookmarks.SetViewSize', _Bookmarks.ViewSize, null);
    BookmarksUpdate();
}


/////////////////////////////////////////////////
// QUICK ADD CONTACT
/////////////////////////////////////////////////
function QuickAddContactInit() {
    var info = $j.parseJSON($j('#QuickAddInfo').val());
    var s = new StringBuilder();
    s.Append('<div id="QuickAddErr"></div>');
    s.Append('<p>');
    s.Append('<input type="radio" id="QuickAddNameIsPerson" name="NameIsPerson" checked=\"checked\" value=\"true\"/><label for="QuickAddNameIsPerson">' + info.WORD_PERSON + '</label>');
    s.Append('<input type="radio" id="QuickAddNameIsCompany" name="NameIsPerson" value=\"false\"/><label for="QuickAddNameIsCompany">' + info.WORD_COMPANY + '</label>');
    s.Append('</p>');
    s.Append('<p><input type="text" id="QuickAddName" value="" /></p>');
    s.Append('<p><input type="text" id="QuickAddCompany" value="" /></p>');
   
    s.Append('<p><input type="text" id="QuickAddEmail" value="" /></p>');
    s.Append('<p><input type="text" id="QuickAddPhone" value="" /></p>');
    s.Append('<div id="QuickAddPhoneType">');
    s.Append('<input type="radio" id="QuickAddPhoneMobile" name="PhoneIsMobile" title="' + info.WORD_MOBILE + '" checked=\"checked\" value=\"true\"/><label for="QuickAddPhoneMobile">' + info.WORD_MOBILE + '</label>');
    s.Append('<input type="radio" id="QuickAddPhoneLandline" title="'+ info.WORD_LANDLINE+'" name="PhoneIsMobile" value=\"false\"/><label for="QuickAddPhoneLandline">' + info.WORD_LANDLINE + '</label>');
    s.Append('</div>');
    s.Append('<p><textarea type="text" id="QuickAddAddress" /></p>');
   
    s.Append('<p><input type="button" id="QuickAddSubmit" class="Button" value=" ' + info.WORD_ADD + ' " onclick="QuickAddContactSubmit()"/></p>');
    
    $j('#QuickAddContact').html(s.ToString());
   
    $j('#QuickAddName').watermark(info.WORD_NAME);
    $j('#QuickAddEmail').watermark(info.WORD_EMAIL);
    $j('#QuickAddPhone').watermark(info.WORD_MOBILE);
    $j('#QuickAddAddress').watermark(info.PHRASE_ENTER_OR_PASTE_ADDRESS);
    $j('#QuickAddCompany').watermark(info.WORD_COMPANY);
    $j('#QuickAddNameIsCompany').change(function() {
        $j('#QuickAddPhoneLandline').attr('checked', 'checked');
        $j('#QuickAddPhoneLandline').change();
        $j('#QuickAddPhoneType').slideUp();
        $j('#QuickAddCompany').slideUp();
        $j('#QuickAddCompany').val('');

    });
    $j('#QuickAddNameIsPerson').change(function() {
        $j('#QuickAddPhoneType').slideDown();
        $j('#QuickAddCompany').slideDown();
    });
    $j('#QuickAddPhoneLandline,#QuickAddPhoneMobile').change(function() {
        $j('#QuickAddPhone').watermark($j(this).attr('title'));
    });
}
function QuickAddContactSubmit() {

    $j('#QuickAddSubmit').after('<span class="Loading" style="position: absolute;">&nbsp;</span>');
    $j('#QuickAddSubmit').attr('disabled', 'disabled');
    var QuickAddRequest = new Object();
    QuickAddRequest.Name  = $j('#QuickAddName').val();
    QuickAddRequest.NameIsPerson = $j("input[name='NameIsPerson']:checked").val()=='true' ? true : false;
    QuickAddRequest.Email = $j('#QuickAddEmail').val();
    QuickAddRequest.Phone = $j('#QuickAddPhone').val();
    QuickAddRequest.PhoneIsMobile = $j("input[name='PhoneIsMobile']:checked").val() == 'true' ? true : false;
    QuickAddRequest.Address = $j('#QuickAddAddress').val();
    QuickAddRequest.Company = $j('#QuickAddCompany').val();

    UI('QuickAddContactWidget2.Submit', QuickAddRequest, function(r) {
        if (r.Success) {
            $j('#QuickAddErr').removeClass();
            $j('#QuickAddErr').addClass('FeedbackSuccess');
            $j("#QuickAddContact input:text").val('').change();
            $j("#QuickAddContact textarea").val('').change();
            RefreshBasicGrid('DirectoryGrid');
        }
        else {
            $j('#QuickAddErr').removeClass();
            $j('#QuickAddErr').addClass('FeedbackError');
        }
        $j('#QuickAddErr').html(r.Feedback);
        $j('.Loading').remove();
        $j('#QuickAddSubmit').attr('disabled', '');
    });
}


/////////////////////////////////////////////////
// ENTRY EDITOR PRODUCT PRICE UPDATE
/////////////////////////////////////////////////
var RefreshPriceTimeout;
function RefreshPriceDelayed(guid) {
    if (!guid)
        guid = '';
    if (RefreshPriceTimeout)
        clearTimeout(RefreshPriceTimeout);

    RefreshPriceTimeout = setTimeout('RefreshPrice("'+guid+'")', 1000);
}
function RefreshPrice(guid) {
    if (!guid)
        guid = '';
    if ($('PriceWait' + guid))
        $('PriceWait' + guid).style.display = 'block';
    GlobalCB('EntryEditor.OnProductCatalogItemChanged', $('CatalogCombo' + guid + '_value').value + ' ', $('Qty' + guid).value + ' ', guid);
}

/////////////////////////////////////////////////
// BALLOON
/////////////////////////////////////////////////
var allBallooons = [];
function GetBalloon(id) {
    for (var i = 0; i < allBallooons.length; i++)
        if (allBallooons[i].id == id)
        return allBallooons[i];
    var o = new Object(); // when not found return a dummy object that cant crash.
    o.close = function () { };
    o.html = function () { };
    o.reposition = new function () { };
    return o;
}
/// Returns 'top' or 'bottom' based on which location the mouse pointer is at.
function GetBestTopOrBottomPosition() {
    var mouseWindowY = mouseY - $j(window).scrollTop();
    return mouseWindowY >= $j(window).height()/2 ? 'bottom' : 'top';
}
function Balloon(event, ID, pos) {
    if (ID && $j('#' + ID).exists())
        return GetBalloon(ID);

            this.id = ID;
            this.link = event ? $j(event.currentTarget || event.srcElement) : null;
            if (pos) {
                this.position = pos;
            }
            if (!this.id)
                this.id = "bal_" + (new Date()).getTime();
            var s = "";
            var calculatedPos = this.position;
            if (calculatedPos == 'top-or-bottom') {
                calculatedPos = GetBestTopOrBottomPosition();
            }
            switch (calculatedPos) {
                case 'top':
                    s += "<div id=\"" + this.id + "\" class=\"NewEntryBaloon\" style=\"width: 400px;\"><div class=\"TriangleTop\"></div><div class=\"Inner\">";
                    s += "<span><a href=\"javascript:;\" onclick=\"GetBalloon('" + this.id + "').close();\" class=\"Close\"></a></span>";
                    s += "<span id=\"" + this.id + "Details\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
                    s += "</div></div>";
                    break;
                case 'top-right':
                    s += "<div id=\"" + this.id + "\" class=\"NewEntryBaloon\" style=\"width: 400px;\"><div class=\"TriangleTopRight\"></div><div class=\"Inner\">";
                    s += "<span><a href=\"javascript:;\" onclick=\"GetBalloon('" + this.id + "').close();\" class=\"Close\"></a></span>";

                    s += "<span id=\"" + this.id + "Details\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
                    s += "</div></div>";
                    break;
                case 'bottom':
                    s += "<div id=\"" + this.id + "\" class=\"NewEntryBaloon\" style=\"width: 400px;\"><div class=\"Inner\">";
                    s += "<span><a href=\"javascript:;\" onclick=\"GetBalloon('" + this.id + "').close();\" class=\"Close\"></a></span>";

                    s += "<span id=\"" + this.id + "Details\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
                    s += "</div><div class=\"Triangle\"></div></div>";
                    break;
                case 'none':
                    s += "<div id=\"" + this.id + "\" class=\"NewEntryBaloon BoxShadow\" style=\"width: 400px;\"><div class=\"Inner\">";
                    s += "<span><a href=\"javascript:;\" onclick=\"GetBalloon('" + this.id + "').close();\" class=\"Close\"></a></span>";

                    s += "<span id=\"" + this.id + "Details\"><p align=\"center\"><br/><img src=\"/v2.0/images/ajax-loader.gif\" /> " + JS_PLEASE_WAIT + " <br/><br/></p></span>";
                    s += "</div></div>";
                    break;

            }
            $j('#DialogBalloonHolder').append(s);
            allBallooons.push(this);
            this.reposition();
}
Balloon.prototype.id = '';
Balloon.prototype.position = 'bottom';
Balloon.prototype.disableKeepOnScreen = false;
Balloon.prototype.closeDelegates = [];
Balloon.prototype.onclose = function (func) {
    if (func instanceof Function) {
        this.closeDelegates.push(func);
    }

}
Balloon.prototype.css = function(a,b) {
    $j('#'+this.id).css(a,b);
}
Balloon.prototype.title = function(text) {
    var closeLink = '<span>' + $j('#' + this.id).find('.Close:first').parent().html() + '</span>';
    $j('#' + this.id).find('.Close:first').remove();
    if (!$j('#' + this.id).find('.TitleBar:first').exists()) {
        $j('#' + this.id).find('.Inner:first').before('<h1 class="TitleBar">' + closeLink + text + '</h1>');
    }
    else {
        $j('#' + this.id).find('.TitleBar:first').html(closeLink + text);
    }
}
Balloon.prototype.html = function (html) {
    var container = $j('#' + this.id + 'Details');
    if(container.exists())
        container.html(html);
    this.reposition();
    //$j('#' + this.id).effect("bounce", { times: 3, distance: 10 }, 100);
};
Balloon.prototype.close = function () {
    $j('#' + this.id).fadeOut(function () {
        $j(this).remove();
    });
    allBallooons.splice(allBallooons.indexOf(this), 1);
    for (var i = 0; i < this.closeDelegates.length; i++) {
        this.closeDelegates[i].call(this);
    }
};
Balloon.prototype.reposition = function () {

    var el = $j('#' + this.id);

    el.css('position', 'absolute');

    if (!this.link && !this.originalPos)
        this.originalPos = { x: mouseX, y: mouseY };

    var x = this.link ? this.link.left() : this.originalPos.x;
    var y = this.link ? this.link.top() : this.originalPos.y;

    var calculatedPos = this.position;
    if (calculatedPos == 'top-or-bottom') {
        calculatedPos = GetBestTopOrBottomPosition();
    }
    switch (calculatedPos) {
        case 'none':
            el.center(true);
            return;
        default:
        case 'bottom':
            {
                var posY = (y - (el.outerHeight() + 30));
                if (!this.disableKeepOnScreen)
                    if (posY < GetScrollTop() + 5)
                        posY = GetScrollTop() + 5;
                var linkWidth = this.link != null ? this.link.outerWidth() : 1;
                x += linkWidth / 2.0;
                x -= 115;
                if (x < 115)
                    x = 115;
                else if (x + el.outerWidth() + 5 > $j(window).width())
                    x = $j(window).width() - el.outerWidth() - 5;
                y = posY + 'px';
                x = x + 'px';

            } break;
        case 'top-right':
        case 'top':
            {
                var posY = (y + 45);
                if (!this.disableKeepOnScreen)
                    if (posY < GetScrollTop() + 5)
                        posY = GetScrollTop() + 5;
                var linkWidth = this.link != null ? this.link.outerWidth() : 1;
                x += linkWidth / 2.0;
                x -= 115;
                if (x < 115)
                    x = 115;
                else if (x + el.outerWidth() + 5 > $j(window).width())
                    x = $j(window).width() - el.outerWidth() - 5;
                y = posY + 'px';
                x = x + 'px';

            } break;
    }

    el.css({ left: x, top: y });
};
    


function MoveMessage(event, MessageID) {
    var b = new Balloon(event, 'Move' + MessageID, 'bottom');
    UI('EntryEditor.MoveMessageRender', MessageID,
    function(html) {
        b.html(html);
    });
}
function MoveMessageSubmit(MessageID) {
    var b = GetBalloon('Move' + MessageID);
    var EntryID = parseInt($j('#MessageMovePicker' + MessageID + '_value').val());
    if (isNaN(EntryID))
        EntryID = 0;
    var MoveMessageSubmitArgs = new Object();
    MoveMessageSubmitArgs.MessageID = MessageID;
    MoveMessageSubmitArgs.EntryID = EntryID;
    UI('EntryEditor.MoveMessageSubmit', MoveMessageSubmitArgs,
    function(html) {
        b.html(html);
    });
}
var currentArchiveDialog; // prevent dupe windows on double-click
function ArchiveDialogOpen(event, type, id, archive) {
    if (currentArchiveDialog)
        return;
    currentArchiveDialog = true;
    var b = new Balloon(event, 'Archive' + type + id, 'bottom');
    var ArchiveRequest = new Object();
    ArchiveRequest.Type = type;
    ArchiveRequest.ID = id;
    ArchiveRequest.Archive = archive;
    b.Req = ArchiveRequest;
    
    UI('EntryEditor.ArchiveRender', ArchiveRequest,
    function (ArchiveResponse) {
        HandleArchiveResult(b, ArchiveResponse);
        currentArchiveDialog = false;
    });
}
function HandleArchiveResult(b, ArchiveResponse) {
    if (ArchiveResponse.IsComplete) {
        b.link.html(ArchiveResponse.IsArchived ? ArchiveResponse.WORD_UNARCHIVE : ArchiveResponse.WORD_ARCHIVE);
        b.link.removeClass();
        b.link.addClass(ArchiveResponse.IsArchived ? 'UnarchiveLink' : 'ArchiveLink');
        b.link.attr('onclick', '');
        b.link.unbind('click');
        b.link.bind('click',
        { js: "ArchiveDialogOpen(event, '" + b.Req.Type + "', '" + b.Req.ID + "', " + (ArchiveResponse.IsArchived ? 'false' : 'true') + ")" },
        function(event) {
            eval(event.data.js);
        }
        );
    }
    b.html(ArchiveResponse.Html);
}
function ArchiveDialogSubmit(balloonID) {
    var b = GetBalloon(balloonID);
    var ArchiveRequest = b.Req;
    ArchiveRequest.SelectedIDs = [];
    var sel = $j('#' + balloonID + ' table :checked');
    for (var i = 0; i < sel.length; i++)
        ArchiveRequest.SelectedIDs.push(sel[i].value);

    UI('EntryEditor.ArchiveSubmit', ArchiveRequest,
    function(ArchiveResponse) {
        HandleArchiveResult(b, ArchiveResponse);
    });
}


/////////////////////////////////////////////////
// DELETE DIALOG
/////////////////////////////////////////////////
function DeleteDialogOpen(Request) {
    var b = new Balloon(null, 'DeleteDialog', 'top-or-bottom');
    b.Request = Request;
    UI('EntryEditor.DeleteRender', Request, function (r) {
        b.html(r.Html);
    }, b);
}

function DeleteDialogSubmit() {
    var b = GetBalloon('DeleteDialog');
    var Request = b.Request;
    Request.SelectedIDs = [];
    var sel = $j('#DeleteDialog table :checked');
    for (var i = 0; i < sel.length; i++)
        Request.SelectedIDs.push(sel[i].value);
    Request.Submit = true;
    UI('EntryEditor.DeleteRender', Request, function (r) {
        b.html(r.Html);
        if (r.Redirect)
            setTimeout(function () { window.location = r.Redirect }, 2000);
        if (r.ExecJS)
            eval(r.ExecJS);
    }, b);
}

/////////////////////////////////////////////////
// CONTACT DIRECTORY3 FUNCTIONS
/////////////////////////////////////////////////
var _CurrentCD3ID;
function LightBoxRowShow(RowID) {
    var row = $j('#' + RowID);

    if (!row.attr('LightBox1'))
        return;
    row.trigger('resize');
    //$j('#' + row.attr('LightBox1')).css({ display: 'block' });
    //$j('#' + row.attr('LightBox2')).css({ display: 'block' });
    $j('#' + row.attr('LightBox1')).fadeIn();
    $j('#' + row.attr('LightBox2')).fadeIn();
}
function LightBoxRowInit(RowID) {
    var row = $j('#' + RowID);

    if (row.attr('LightBox1'))
        return;
        
    row.attr('LightBox1', '_lb1_' + (new Date()).getTime());
    row.attr('LightBox2', '_lb2_' + (new Date()).getTime());

    $j(document.body).append('<div id="' + row.attr('LightBox1') + '" class="Shade15"></div><div id="' + row.attr('LightBox2') + '" class="Shade15"></div>');

    var LightBox1 = $j('#' + row.attr('LightBox1'));
    var LightBox2 = $j('#'+ row.attr('LightBox2'));
    LightBox1.css('display', 'none');
    LightBox1.css('position', 'absolute');
    LightBox2.css('display', 'none');
    LightBox2.css('position', 'absolute');
    row.resize(function () {
        var row = $j(this);
        if (!row.attr('LightBox1'))
            return;
        var LightBox1 = $j('#' + row.attr('LightBox1'));
        var LightBox2 = $j('#' + row.attr('LightBox2'));
        LightBox1.css('top', $j(this).parent().top() + 'px');
        LightBox1.css('left', $j(this).parent().left() + 'px');
        LightBox1.css('width', $j(this).parent().width() + 'px');
        LightBox1.css('height', ($j(this).top() - $j(this).parent().top()) + 'px');
        LightBox2.css('top', ($j(this).bottom()) + 'px');
        LightBox2.css('left', $j(this).parent().left() + 'px');
        LightBox2.css('width', $j(this).parent().width() + 'px');
        LightBox2.css('height', ($j(this).parent().bottom() - $j(this).bottom()) + 'px');

        var hasCompanyColumn = $j('#r' + _CurrentCD3ID + '_c1_2').exists();

        $j('.AddressContainer', row).css({
            width: (row.children(":nth-child(2)").width() + row.children(":nth-child(3)").width() + (hasCompanyColumn?row.children(":nth-child(4)").width():0)) + 'px'
        });
    });

}
function LightBoxRowRemove(RowID, deleteRow) {
    var row = $j('#' + RowID);

    if (!row.attr('LightBox1'))
        return;

    row.unbind('resize');
    
    var LightBox1 = $j('#' + row.attr('LightBox1'));
    var LightBox2 = $j('#' + row.attr('LightBox2'));

    LightBox1.fadeOut(function() { $j(this).remove(); })
    LightBox2.fadeOut(function() { $j(this).remove(); })
    row.attr('LightBox1', '');
    row.attr('LightBox2', '');
    if (deleteRow)
        row.remove();
}

function CD3RemoveLB() {
    if (_CurrentCD3ID == 0)
        return;

    LightBoxRowRemove('r' + _CurrentCD3ID);

    var col1 = $j('#r' + _CurrentCD3ID + '_c1').html('');
    var col1_1 = $j('#r' + _CurrentCD3ID + '_c1_2').html('');
    var col2 = $j('#r' + _CurrentCD3ID + '_c2').html('');
    var col3 = $j('#r' + _CurrentCD3ID + '_c3').html('');
    $j('#r' + _CurrentCD3ID).children(":nth-child(2)").css('background-image', '');
    $j('#r' + _CurrentCD3ID + ' .Ex').html('<img src="/v2.0/images/expand.png"/>');

    var row = $j('#r' + _CurrentCD3ID);
    row.children(":nth-child(1)").css(
        {
            backgroundImage: ''
        });


        $j('.CD3R0', row).css('height', null);

    if ($j('#r' + _CurrentCD3ID).hasClass('Alt_')) {
        $j('#r' + _CurrentCD3ID).removeClass('Alt_');
        $j('#r' + _CurrentCD3ID).addClass('Alt');
    }
    _CurrentCD3ID = 0;
}
function CD3SelectAddress(idx) { 
    $j('.CD3Addr').css('display','none');
    $j('.CD3AddrLink').removeClass('AddrSelected');

    $j('#addrLink' + idx).addClass('AddrSelected');
    $j('#addr' + idx).css('display', 'block');
    var addressText = $j('#addr' + idx).text().replace('\n', ' ');
    $j('#CD3Map').attr('title', addressText);
    $j('#CD3Map').attr('href', 'http://maps.google.com/?q=' +addressText);
}

function CD3Toggle(RowID) {

    var row = $j('#r' + RowID);
    
    if (!row.exists()) {
        CD3RemoveLB();
        return;
    }
    var col1 = $j('#r' + RowID + '_c1', row);
    var col1_2 = $j('#r' + RowID + '_c1_2', row);
    var col2 = $j('#r' + RowID + '_c2', row);
    var col3 = $j('#r' + RowID + '_c3', row);
    
    if (_CurrentCD3ID) {
        col1.css('display', 'none');
        col1_2.css('display', 'none');
        col2.css('display', 'none');
        col3.css('display', 'none');
        CD3RemoveLB();
        return;
    }

    _CurrentCD3ID = RowID;

    LightBoxRowInit('r' + _CurrentCD3ID);

    $j('.Ex', row).html('<img src="/v2.0/images/ajax-loader.gif"/>');

    var actualEntityID = $j('.CD3ID', row).attr('EntityID');

    UI('Contacts.GetCD3Details', actualEntityID, function (r) {
        //var row = $j('#r' + EntityID);
        row.children(":nth-child(1)").css(
        {
            backgroundImage: 'url(/?SendAvatar=' + actualEntityID + '&width=48&height=48)'
            , backgroundPosition: '50% 30px'
            , backgroundRepeat: 'no-repeat'
        });

        col1.css('display', 'none');
        col1.html(r.Column1);
        col1_2.css('display', 'none');
        col1_2.html(r.Column1_2);
        col2.css('display', 'none');
        col2.html(r.Column2);
        col3.css('display', 'none');
        col3.html(r.Column3);

        col1.css('display', 'block');
        col1_2.css('display', 'block');
        col2.css('display', 'block');
        col3.css('display', 'block');
        //col3.slideDown();

        if (row.hasClass('Alt')) {
            row.removeClass('Alt');
            row.addClass('Alt_');
        }

        $j('.Ex', row).html('<img src="/v2.0/images/collapse.png"/>');

        // $j('.CD3R1').css('margin-right', '50px');
        for (var i = 0; i < 3; i++) {
            var max = i == 1 ? 28 : 0; // CD3R1 min height of 28px to cover half the logo height 
            $j('.CD3R' + i, row).each(function () {
                if (max < $j(this).outerHeight())
                    max = $j(this).outerHeight();
            });
            $j('.CD3R' + i, row).css('height', max + 'px');
        }
        var addressHeight = $j('.AddressContainer li', row).length == 0 ? '0px' : '180px';
        var hasCompanyColumn = $j('#r' + _CurrentCD3ID + '_c1_2').exists();

        $j('.AddressContainer', row).css({
            width: (row.children(":nth-child(2)").width() + row.children(":nth-child(3)").width() + (hasCompanyColumn ? row.children(":nth-child(4)").width() : 0)) + 'px',
            minHeight: addressHeight,
            position: 'absolute',
            marginTop: '8px'
        });
        $j('.AddressContainerHeight', row).css({ height: addressHeight });
        $j('.AddressContainer', row).bind('resize', { sender: row }, function (event) {
            //console.log('resize ' + $j(this).outerHeight() + ' - ' + event.data.sender);
            $j('.AddressContainerHeight', event.data.sender).css({ height: ($j(this).outerHeight()+10) + 'px' });
        });

        CheckDropDownPopupPositions();
        InitialiseAllTabs();

        LightBoxRowShow('r' + RowID);
    });

}


/////////////////////////////////////////////////
// MINI ENTRY EDITOR FUNCTIONS
/////////////////////////////////////////////////
//
//
//  struct CreateNewRequest
//  {
//       public MiniEntryEditorType Type;
//       public int Relation;
//       public int EntryID_Parent;
//       public DateTime? Start;
//       public DateTime? End;
//       public string BalloonID;
//  }
function CreateEntry(event, args) {
    var b = new Balloon(event, null, 'none');
    var el = $j('#' + b.id);
    el.draggable({ handle: 'h1' });
    args.BalloonID = b.id;
    UI('MiniEntryEditor.CreateEntry', args, function(r) {
        HandleMiniEntryEditorResult(b, r);
    });
}
function CreateMessage(event, args) {
    var b = new Balloon(event, null, 'none');
    b.MessageRequest = args;
    var el = $j('#' + b.id);
    el.draggable({ handle: 'h1' });
    args.BalloonID = b.id;
    UI('MiniEntryEditor.CreateMessage', args, function(r) {
        HandleMiniEntryEditorResult(b, r);
    });
}
function CreateEntity(event, args) {
    var b = new Balloon(event, null, 'none');
    b.MessageRequest = args;
    var el = $j('#' + b.id);
    el.draggable({ handle: 'h1' });
    args.BalloonID = b.id;
    UI('MiniEntryEditor.CreateEntity', args, function (r) {
        HandleMiniEntryEditorResult(b, r);
    });
}
function HandleMiniEntryEditorResult(b, r) {
    var el = $j('#' + b.id);
    if (r.Title)
        b.title(r.Title);

    el.css('width', 'auto'); //r.DesiredWidth?r.DesiredWidth: '500px'
    if (r.RedirectMessage) {
        b.html("<div>&nbsp;</div>" + r.RedirectMessage);
        b.isDisposed = true;
        //setTimeout('GetBalloon("' + b.id + '").close()', 5000);
        el.bind('click', function () { GetBalloon($j(this).attr('id')).close(); });
        window.NewEntryID = r.NewEntryID;
        if (r.ExecJS)
            eval(r.ExecJS);
        RefreshCalendar();
        RefreshActivityList();
        RefreshActivityBoxes();
    }
    else {
        b.html("<div>&nbsp;</div>" + r.Html);
        EmailAttachmentsRefresh(b.id);
    }
    if ($j('#' + b.id + '_Suggest').exists()) {
        $j('#' + b.id + '_Suggest').unbind('mouseleave');
        $j('#' + b.id + '_Suggest').bind('mouseleave', function() { $j(this).css('display', 'none'); });
    }
    if (b.SaveBar) {
        var saveTools = $j('#' + b.id).find('.SaveTools:first');
        saveTools.html(b.SaveBar);
        b.SaveBar = null;
    }
    $j('.AutoWatermark').watermark();
    InitAdvancedDetails();
}

function CommitEntry(BalloonID) {
    var CommitRequest = new Object();
    CommitRequest.BalloonID = BalloonID;
    CommitRequest.Data = CollectFormDataWithin(BalloonID);
    var b = GetBalloon(BalloonID);

    SaveToolsWait(b.id);
    
    UI('MiniEntryEditor.CommitEntry', CommitRequest, function(r) {
        HandleMiniEntryEditorResult(b, r);
    });
}
function SaveToolsWait(container) {
    var b = GetBalloon(container);
    var saveTools = $j('#' + container).find('.SaveTools:first');
    if (b)
        b.SaveBar = saveTools.html();
    saveTools.html('<hr/><div class="Loading" style="float:right">' + JS_PLEASE_WAIT + '</div>');
}

//public struct MessageRequest
//{
//    public bool IsEmail;
//    public string BalloonID;
//    public int EntityID;
//    public int EntryID;
//    public int InvoiceID;
//    public int LeadID;
//    public int NotationID_Parent;
//    public string Body;
//    public string Subject;
//    public string To;
//    public string CC;
//    public string BCC;
//}
function CommitMessage(BalloonID) {
    var b = GetBalloon(BalloonID);

    var MessageRequest = b.MessageRequest;
    MessageRequest.Body = $j('#'+b.id+'_Body').val();
    MessageRequest.Subject = $j('#' + b.id + '_Subject').val();
    if (MessageRequest.IsEmail) {
        MessageRequest.To = $j('#' + b.id + '_To').val();
        MessageRequest.CC = $j('#' + b.id + '_CC').val();
        MessageRequest.BCC = $j('#' + b.id + '_BCC').val();
        MessageRequest.From = $j('#' + b.id + '_From').val();
        MessageRequest.Attachments = $j('#' + b.id + '_Attachments').val()?$j.parseJSON( $j('#' + b.id + '_Attachments').val()):[];
    }
    MessageRequest.Submit = true;

    SaveToolsWait(b.id);
    
    UI('MiniEntryEditor.CreateMessage', MessageRequest, function(r) {
        HandleMiniEntryEditorResult(b, r);
    });
}

function CommitEntity(BalloonID) {
    var b = GetBalloon(BalloonID);
    var request = b.MessageRequest;
    request.Data = CollectFormDataWithin(BalloonID);
    request.Commit = true;
    SaveToolsWait(b.id);

    UI('MiniEntryEditor.CreateEntity', request, function (r) {
        HandleMiniEntryEditorResult(b, r);
    });
}

function EmailAttachmentRemove(BalloonID, index) {
    var b = GetBalloon(BalloonID);
    if (!$j('#' + b.id + '_Attachments').exists())
        return;
    var atts = $j.parseJSON($j('#' + b.id + '_Attachments').val());
    atts.splice(index, 1);
    $j('#' + b.id + '_Attachments').val($j.toJSON(atts));
    EmailAttachmentsRefresh(BalloonID);
}
function EmailAttachmentsRefresh(BalloonID) {
    var b = GetBalloon(BalloonID);
    if (!$j('#' + b.id + '_Attachments').exists())
        return;
    var atts = $j('#' + b.id + '_Attachments').val()?$j.parseJSON($j('#' + b.id + '_Attachments').val()):[];
    var s = new StringBuilder();
   

    for (var i = 0; i < atts.length; i++) {
        var rx = new RegExp(/[^\.]+$/gi);
        s.Append('<div style="background:url(/v2.0/images/filetypes/'+rx.exec(atts[i].Name)+'.gif) no-repeat 0 50%; padding-left: 20px;">');
        s.Append(atts[i].Name + ' <a href="javascript:;" onclick="EmailAttachmentRemove(\'' + BalloonID + '\','+i+')">[x]</a><br/>');
        s.Append('</div>');
    }


    s.Append('<a href="javascript:;" onclick="EmailAttachmentsNew(event, \'' + BalloonID + '\');">+ ' + $j('#' + b.id + '_AttachmentsView').attr('PHRASEADDATTACHMENT') + '</a>');
    $j('#' + b.id + '_AttachmentsView').html(s.ToString());
}
function EmailAttachmentsNew(event, BalloonID) {
    var b = new Balloon(event, null, 'top');
    var emailBalloon = GetBalloon(BalloonID);
    emailBalloon.AttachBalloon = b;
    b.html(BuildFileUploader('todisk', BalloonID, 'EmailAttachmentAdded', '', 0, 0));
}
function EmailAttachmentAdded(o) {

    var b = GetBalloon(o.ID);
    b.AttachBalloon.close();
    
    var atts = $j.parseJSON($j('#' + b.id + '_Attachments').val());
    atts.push({ Name: o.Name, Guid: o.Guid, MIMEType: o.MIMEType });
    $j('#' + b.id + '_Attachments').val($j.toJSON(atts));
    EmailAttachmentsRefresh(b.id);
}
function InitAdvancedDetails() {
    $j('.AdvancedDetailsToggle').each(function() { 
         var container = $j(this).parents('.ContactEditorTable');
         if (!container)
            return;
         var editorType =  $j(container).attr('editortype');
         var isHidden = $j(container).find('.AdvancedDetails:first').css('display') == 'none';
         if ($j(this).attr('isHidden') == '0' && isHidden)
            ToggleAdvancedDetails(this, true);
    });
}
function ToggleAdvancedDetails(sender, skipSave) {
    var container = $j(sender).parents('.ContactEditorTable');
    var editorType =  $j(container).attr('editortype');
    var isHidden = $j(container).find('.AdvancedDetails:first').css('display') == 'none';
    if (isHidden) {
        container.find('.AdvancedDetails').css('display', $j.browser.msie?'block':'table-row');
        $j(sender).css('background-image', 'url(/v2.0/images/collapse.png)');
        $j(sender).html($j(sender).attr('WORDHIDEADVANCEDDETAILS'));
    }
    else {
        container.find('.AdvancedDetails').css('display', 'none');
        $j(sender).html($j(sender).attr('WORDSHOWADVANCEDDETAILS'));
        $j(sender).css('background-image', 'url(/v2.0/images/expand.png)');
    }
    if (!skipSave && editorType)
        SetUserSetting(editorType + "_basic", isHidden ? '0' : '1');
}
function RefreshCalendar() {
    if (typeof RefreshEntries == 'function') {
        ClearSelectionBlocks();
        RefreshEntries();
    }
}
function RefreshActivityList() {
    if (!$j('#AttachmentsDiv').exists())
        return;
    var RenderActivityRequest = new Object();
    RenderActivityRequest.EntityID = parseInt($j('#AttachmentsDiv').attr('EntityID'));
    RenderActivityRequest.EntryID = parseInt($j('#AttachmentsDiv').attr('EntryID'));
    RenderActivityRequest.InvoiceID = parseInt($j('#AttachmentsDiv').attr('InvoiceID'));
    UI('EntryEditor.RenderActivity', RenderActivityRequest, function(r) {
        $j('#AttachmentsDiv').html(r);
    });
}
function SetUserSetting(key, value) {
    UI('EntryEditor.SetUserSetting', { Key: key, Value: value }, function() { });
}

//======================================
// ACTIVITY BOX
//======================================
//var PagedHistoryRequest;
var _ActivityBoxes = [];
function GetActivityBoxReq(uid) {
    for (var i = 0; i < _ActivityBoxes.length; i++)
        if (_ActivityBoxes[i].UID == uid)
            return _ActivityBoxes[i];
    return null;
}
function SetActivityBoxReq(req) {
    for (var i = 0; i < _ActivityBoxes.length; i++)
        if (_ActivityBoxes[i].UID == req.UID) {
            _ActivityBoxes[i] = req;
            return;
        }
    _ActivityBoxes.push(req);
}
function RefreshActivityBoxes() {
    for (var i = 0; i < _ActivityBoxes.length; i++)
        RefreshActivityBox(_ActivityBoxes[i].UID);
}
function RefreshActivityBox(uid) {
    var context = $j('#' + uid);
    if (!context.exists())
        return;

    var prev = null;
    var PagedHistoryRequest = GetActivityBoxReq(uid);
    
    if (PagedHistoryRequest) {
        prev = PagedHistoryRequest;
    }

    PagedHistoryRequest = $j.parseJSON($j('#PagedHistoryRequest', context).val());
    SetActivityBoxReq(PagedHistoryRequest);

    if (prev) {
        PagedHistoryRequest.Sort = prev.Sort;
        PagedHistoryRequest.SortAsc = prev.SortAsc;
        PagedHistoryRequest.Period = prev.Period;
    }

    PagedHistoryRequest.Keywords = $j('#kw', context).val();

    $j('.ActivityBox', context).html('<div class="Inner"></div>');
    if (PagedHistoryRequest.EntryID != 0) {
        $j('.ActivityBox', context).css('height', 'auto');
        //$j(window).unbind('scroll'); // don't break main page activity view when opening popup activity boxes
        $j(window).bind('scroll', function() { PagedHistoryScrollPage(uid); });
    }
    else {
        $j('.ActivityBox', context).unbind('scroll');
        $j('.ActivityBox', context).scrollTo(0);
        $j('.ActivityBox', context).bind('scroll', function () { PagedHistoryScroll(uid, $j(this).scrollTop()); });
    }



    var checks = $j("input[name='ViewTypes']:checked", context);
    var viewTypes = 0;
    for(var i=0;i<checks.length;i++)
        viewTypes |= parseInt(checks[i].value);
    PagedHistoryRequest.Types = viewTypes;
    PagedHistoryRequest.StartIndex = 0;
    if ($j('#HideInactiveItems', context).attr('checked'))
        PagedHistoryRequest.Flags |= 1 << 13;
    else
        PagedHistoryRequest.Flags &= ~(1 << 13);
    $j('.ActivityBoxRemainder', context).remove();
    if ($j('#PagedHistoryResult', context).exists()) {
        var PagedHistoryResult = $j.parseJSON($j('#PagedHistoryResult', context).val());
        PagedHistoryResultRender(PagedHistoryResult);
        $j('#PagedHistoryResult', context).remove();
        return;
    }

    $j('.ActivityBox', context).css('background-image', 'url(/v2.0/images/ajax-loader-big.gif)');

    UI('EntryEditor.RenderHistoryPagedScroll',
        PagedHistoryRequest,
        function (PagedHistoryResult) {
           
            PagedHistoryResultRender(PagedHistoryResult);
        });
}
var _PagedHistoryScrollTimeout;

function PagedHistoryScroll(uid, top) {

    var PagedHistoryRequest = GetActivityBoxReq(uid);

    if (!_PagedHistoryScrollTimeout
        && !PagedHistoryRequest.NoMoreResults
        && $j('.ActivityBox .Inner').outerHeight() - $j('.ActivityBox').scrollTop() < ($j('.ActivityBox').height()+50))
        _PagedHistoryScrollTimeout = setTimeout("PagedHistoryScrollNext('"+uid+"') ", 50);

}
function PagedHistoryScrollPage(uid) {
    var PagedHistoryRequest = GetActivityBoxReq(uid);
    
    if (!_PagedHistoryScrollTimeout
        && !PagedHistoryRequest.NoMoreResults
        && $j(document).height() - $j(window).scrollTop() - $j(window).height() < $j(window).height()/2.0)
        _PagedHistoryScrollTimeout = setTimeout("PagedHistoryScrollNext('" + uid + "') ", 50);

}
function PagedHistoryScrollNext(uid) {
    var PagedHistoryRequest = GetActivityBoxReq(uid);
    var context = $j('#' + uid);

    $j('.ActivityBoxRemainder div', context).html(JS_PLEASE_WAIT);
    $j('.ActivityBoxRemainder div', context).fadeIn();
    $j('.ActivityBoxRemainder', context).css('background-image', 'url(/v2.0/images/ajax-loader-EEF3FA.gif)');
    //$j('.ActivityBox').css('background-image', 'url(/v2.0/images/ajax-loader-big.gif)');
    UI('EntryEditor.RenderHistoryPagedScroll', 
        PagedHistoryRequest,
        function (PagedHistoryResult) {
            PagedHistoryResultRender(PagedHistoryResult); 
        });
}
function PagedHistoryResultRender(r) {


    var PagedHistoryRequest = GetActivityBoxReq(r.UID);
    var context = $j('#' + r.UID);

    clearTimeout(_PagedHistoryScrollTimeout);
    _PagedHistoryScrollTimeout = null;

    $j('.ActivityBoxRemainder div', context).fadeOut();
    $j('.ActivityBoxRemainder', context).css('background-image', 'none');
    $j('.ActivityBox', context).css('background-image', 'none');

    var s = new StringBuilder();
    
    for (var i = 0; i < r.Data.length; i++) {
        s.Append(r.Data[i]);
    }

    if (s.Buffer.length == 0
        && r.StartIndex == 0) {
        $j('.ActivityBox .Inner', context).html('<p style="text-align:center;"><small>No activity to display.</small></p>');
    }
    else {
        if (r.StartIndex==0)
            $j('.ActivityBox .Inner', context).html(s.ToString());
        else
            $j('.ActivityBox .Inner', context).append(s.ToString());
    }
    if (window.location.hash
        && $j(window.location.hash + '_Body').exists()) {
        $j(window.location.hash + '_Body').css('display', 'block');
    }
    PagedHistoryRequest.Remaining = r.RecordCount - (r.StartIndex + r.FetchSize);
    PagedHistoryRequest.RecordCount = r.RecordCount;
    if (PagedHistoryRequest.Remaining > 0) {
        PagedHistoryRequest.StartIndex += r.FetchSize;
        if (!$j('.ActivityBoxRemainder', context).exists())
            $j('.ActivityBox', context).after('<div class="ActivityBoxRemainder"><div></div></div>');
        $j('.ActivityBoxRemainder div', context).html("Scroll here for " + PagedHistoryRequest.Remaining + " more results...");
        $j('.ActivityBoxRemainder div', context).fadeIn();

    }
    else {
        PagedHistoryRequest.NoMoreResults = true;
        $j('.ActivityBoxRemainder', context).fadeOut(function () { $j(this).remove(); });
    }
    CheckDropDownPopupPositions();
    
}

function OpenMoreItemsBox(id) {
    $j('#' + id).unbind('mouseleave');
    $j('#' + id).bind('mouseleave', function() { $j(this).fadeOut(); });
    $j('#' + id).fadeIn();

}

function PagedHistorySetPeriod(uid, val, label) {
    var context = $j('#' + uid);
    var PagedHistoryRequest = GetActivityBoxReq(uid);
    PagedHistoryRequest.Period = val;
    $j('#PeriodOptionsLink', context).html(label);
    RefreshActivityBox(uid);
}
function PagedHistorySetSort(uid, val, label) {
    var context = $j('#' + uid);
    var PagedHistoryRequest = GetActivityBoxReq(uid);
    PagedHistoryRequest.Sort = val;
    $j('#SortOptionsLink #Field').html(label);
    RefreshActivityBox(uid);
}
function PagedHistorySetSortAsc(uid, asc, label) {
    var context = $j('#' + uid);
    var PagedHistoryRequest = GetActivityBoxReq(uid);
    PagedHistoryRequest.SortAsc = asc;
    $j('#SortOptionsLink #Asc', context).html(label);
    RefreshActivityBox(uid);
}

// =====================================
// SyncSettings
// =====================================
//function OpenCalSyncSettings(id) {

//    $j('#cal' + id).after('<tr id="cal' + id + '_details"><td colspan=10><div class="Loading"></div></td></tr>');
//    var newRow = $j('#cal' + id + '_details');
//    LightBoxRowInit('cal' + id + '_details');
//    LightBoxRowShow('cal' + id + '_details');
//    UI('SystemSettings.CalendarSyncInit', { PrimaryKey: id }, function(r) {
//        newRow.html('<td colspan=5>'+r.Html+'</td>');
//    });

//}
function OpenCalSyncCreate(event, id) {
    var b = new Balloon(event, 'SyncCreate' + id, 'none');
    var el = $j('#' + b.id);
    el.draggable({ handle: 'h1' });
    UI('SystemSettings.CalendarSyncCreate', { PrimaryKey: id }, function(r) {
        b.title(r.Title);
        b.html(r.Html);
    });
}
function SubmitOpenCalSync(id, cmd, arg) {
    var SyncCreateRequest = {
        PrimaryKey: id,
        Data: CollectFormDataWithin('SyncCreate' + id),
        Cmd:cmd,
        Arg:arg
    };
    var b = GetBalloon('SyncCreate' + id);
    UI('SystemSettings.CalendarSyncCreate', SyncCreateRequest, function(r) {
        b.title(r.Title);
        b.html(r.Html);
        if (r.IsComplete)
            RefreshBasicGrid('CalendarsGrid');
    });
}

//function CloseCalSyncSettings(id) { 
//    LightBoxRowRemove('cal' + id + '_details', true);
//}
function OpenCalSyncPush(event, id) {
    var b = new Balloon(event, 'SyncPush' + id, 'none');
    UI('SystemSettings.CalendarSyncPush', {PrimaryKey:id}, function(r) {
        b.title(r.Title);
        b.html(r.Html);
    });
}
function OpenEntryTriggers(entryID) {
    var b = new Balloon(null, 'Triggers', 'top-or-bottom');
    UI('EntryEditor.TriggersRender', { EntryID: entryID }, function (r) {
        b.css({width:'auto'});
        b.html(r);
    });
}
function AdjustLISubMenu(sender) {
    var li = $j(sender);
    var ul = $j('ul:first', li);
    if (!ul.exists())
        return;
    //debugger;
    var w = ul.outerWidth();
    var h = ul.outerHeight();
    var scrollTop = GetScrollTop();
    var y = li.top();
    var x = li.right()-10;
    if (y + h > scrollTop + $j(window).height())
        y = scrollTop + $j(window).height() - h - 5;
    if (x + w > $j(window).width())
        x = li.left() - w + 5;

    ul.css({ marginLeft: (x - li.left()) + 'px', marginTop: (y - li.bottom()) + 'px' });

}



/////////////////////////////////////////////////
// ACTIVITY VIEWER 2
/////////////////////////////////////////////////
var ActivityViews = [
    'Activity',
    'Priority',
    'Progress',
    'Documents']

function ActivityViewer(ObjectType, PK) {
    this._ObjectType = ObjectType;
    this._PK = PK;
    this._Obj = null;
    this._Data = null;

    this.Render = function (containerID) {
        var s = new StringBuilder();
        // [Latest Activity][Priority][Progress][Documents]
        s.Append('<ul>');
        $j.each(ActivityViews, function (index, value) {
            s.Append('<li><a class="' + value + '">' + value + '<span></span></a></li>');
        });
        s.Append('</ul>');
        s.Append('<div>');
        if (1) {
            s.Append('<table width="100%" cellpadding=0 cellspacing=0 border=0><tr>');
            s.Append('<td>Period:</td><td><span class="Link DropLink Bold">All</span></td>');
            s.Append('<td> </td>');
            s.Append('<td>Sort:</td><td><span class="Link DropLink Bold">Descending</span></td>');
            s.Append('<td> </td>');
            s.Append('<td>Member:</td><td><span class="Link DropLink Bold">Everyone</span></td>');
            s.Append('<td> </td>');
            s.Append('<td><input type="text" title="search"/></td>');
            s.Append('</tr></table>');
        }
        s.Append('</div>');

        s.Append('<table class="DataTable" width="100%" cellpadding=0 cellspacing=0 border=0><tr><th>');
        if (1) {
            s.Append('<table width="100%" cellpadding=0 cellspacing=0 border=0><tr>');
            s.Append('<td><a href="" class="CollapseLink">Collapse</a></td>');
            s.Append('<td> </td>');
            s.Append('<td>Activities:</td><td><span class="Link DropLink Bold">All</span></td>');
            s.Append('<td> </td>');
            s.Append('</tr></table>');
        }
        s.Append('</th><th width=50>');
        s.Append('<img src="/v2.0/images/priority_high.gif" />');
        s.Append('</th><th width=150>');
        s.Append('Activity');
        s.Append('</th><th width=150>');
        s.Append('Progress');
        s.Append('</th>');
        s.Append('</tr>');
        s.Append('</table>');

        this._Obj = $j(s.ToString());
        $j('#' + containerID).append(this._Obj);
    }

    this.Refresh = function () {

        var DataTable = $j('.DataTable', this._Obj);

    }
}