AMCal = function()
{
    var me = this;
    this.base_url = 'http://admiral.fxservice.com/tools/ekocal/';
    this.current_lang = 'en';
    this.current_theme = 'admiral';
    this.dialog_open = false;
    this.get_vars = [];
    this.initial_vars = [];
    this.owner_vars = [];
    this.dialog_open = false;
    this.autoreload = null;
    
    /*
        Loads JSON data from a remote script
        
        pUrl - Url of the script
        pCallback - A function to execute with the returned data
    */
    this.loadRemoteData = function(pUrl, pCallback)
    {
        var loader = document.getElementById('amscriptloader');
        
        if (loader)
        {
            loader.parentNode.removeChild(loader);
        }
        
        loader = document.createElement('script');
        loader.id = 'amscriptloader';
        var hh = document.getElementsByTagName('head')[0];
        hh.appendChild(loader);
        
        if (pUrl.indexOf('?') > -1)
            pUrl += '&cback=' + encodeURIComponent(pCallback) + '&rnd=' + Math.random();
        else
            pUrl += '?cback=' + encodeURIComponent(pCallback) + '&rnd=' + Math.random();
            
        loader.src = pUrl;
        
    }
    
    /*
        Sets a variable in get_vars URL parameter array
        
        pName - The name of the variable to set
        pVal - Variable value
    */
    this.setVar = function(pName, pVal)
    {
        for (var i = 0; i < this.get_vars.length; i++)
            if (this.get_vars[i].name == pName)
            {
                this.get_vars[i].val = pVal;
                return;
            }
        
        // Parameter could not be found
        this.get_vars[this.get_vars.length] = {'name':pName, 'val': pVal};
    }
    
    /*
        Returns a variable from get_vars array
        
        pName - The name of the variable
    */
    this.getVar = function(pName)
    {
        for (var i = 0; i < this.get_vars.length; i++)
            if (this.get_vars[i].name == pName)
            {
                return this.get_vars[i].val;
            }
        
        // Parameter could not be found
        return '';
    }
    
    /*
        Clones variables array to initial variables array to have
        a storage for last used settings.
    */
    this.cloneVars = function()
    {
        this.initial_vars = [];
        
        for (var i = 0; i < this.get_vars.length; i++)
        {
            this.initial_vars[this.initial_vars.length] = {'name': this.get_vars[i].name, 'val': this.get_vars[i].val};
        }
    }
    
    /*
        Clones variables array to script owner's settings array
    */
    this.saveOwnerVars = function()
    {
        this.owner_vars = [];
        
        for (var i = 0; i < this.get_vars.length; i++)
        {
            this.owner_vars[this.owner_vars.length] = {'name': this.get_vars[i].name, 'val': this.get_vars[i].val};
        }
    }
    
    /*
        Sets and clones the initial variables
        
        pVars - Var objects array (name, value)
    */
    this.initWithVars = function(pVars)
    {
        for (var i = 0; i < pVars.length; i++)
        {
            this.setVar(pVars[i].name, pVars[i].val);
        }
        
        this.saveOwnerVars();
        this.cloneVars();
        this.reloadCalendar();
    }
    
    /*
        Clones initial variables array back to variables array.
    */
    this.restoreVars = function()
    {
        this.get_vars = [];
        
        for (var i = 0; i < this.initial_vars.length; i++)
        {
            this.get_vars[this.get_vars.length] = {'name': this.initial_vars[i].name, 'val': this.initial_vars[i].val};
        }
    }
    
    /*
        Generates url parameters from get_vars array
    */
    this.getUrlParams = function()
    {
        var urlline = '';
        
        for (var i = 0; i < this.get_vars.length; i++)
        {
            if (i == 0)
                urlline += '?' + this.get_vars[i].name + '=' + encodeURIComponent(this.get_vars[i].val);
            else
                urlline += '&' + this.get_vars[i].name + '=' + encodeURIComponent(this.get_vars[i].val);
        }
        
        return urlline;
    }
    
    /*
        Generates url parameters from original values, set in the caller's script
    */
    this.getOwnerParams = function()
    {
        var urlline = '';
        
        for (var i = 0; i < this.owner_vars.length; i++)
        {
            if (i == 0)
                urlline += '?' + this.owner_vars[i].name + '=' + encodeURIComponent(this.owner_vars[i].val);
            else
                urlline += '&' + this.owner_vars[i].name + '=' + encodeURIComponent(this.owner_vars[i].val);
        }
        
        return urlline;
    }

    /*
        Reloads calendar data
    */
    this.reloadCalendar = function()
    {
        var url = this.base_url + 'caldata.js.php' + this.getUrlParams();
        this.loadRemoteData(url, 'am_cal.onCalendarLoaded');
    }
    
    /*
        Reloads calendar with last user settings
    */
    this.reloadInitialCalendar = function()
    {
        this.restoreVars();
        var url = this.base_url + 'caldata.js.php' + this.getUrlParams();
        this.loadRemoteData(url, 'am_cal.onCalendarLoaded');
    }
    
    /*
        Triggers when calendar data loads
    */
    this.onCalendarLoaded = function(pData)
    {
        var caldiv = document.getElementById('amcal_main');
        caldiv.innerHTML = pData.html;
        this.current_theme = pData.theme;
        this.current_lang = pData.lang;
        this.switchCalendarScript(pData.theme);
        this.switchCalendarStyle(pData.theme);
        this.get_vars = [];
        
        for (var i = 0; i < pData.vars.length; i++)
        {
            this.get_vars[this.get_vars.length] = {'name': pData.vars[i].name, 'val': pData.vars[i].val};
        }
        
        this.cloneVars();
        this.autoreload = setTimeout('am_cal.reloadInitialCalendar()', 60000);
    }
    
    /*
        Switches the script of the current calendar theme
        
        pTheme - Theme name
    */
    this.switchCalendarScript = function(pTheme)
    {
        var scriptobj = document.getElementById('amcalthemescript');
        
        if (!scriptobj)
        {
            scriptobj = document.createElement('script');
            scriptobj.id = 'amcalthemescript';
            var hh = document.getElementsByTagName('head')[0];
            hh.appendChild(scriptobj);
        }
        
        var urlsrc = this.base_url + 'themes/' + pTheme + '/img/themescript.js';
        
        if (scriptobj.src != urlsrc)
            scriptobj.src = urlsrc;
    }
    
    /*
        Switches the stylesheet of the current calendar theme
        
        pTheme - Theme name
    */
    this.switchCalendarStyle = function(pTheme)
    {
        var styleobj = document.getElementById('amcalthemestyle');
        
        if (!styleobj)
        {
            styleobj = document.createElement('link');
            styleobj.rel = 'stylesheet';
            styleobj.id = 'amcalthemestyle';
            styleobj.type = 'text/css';
            var hh = document.getElementsByTagName('head')[0];
            hh.appendChild(styleobj);
        }
        
        var urlsrc = this.base_url + 'themes/' + pTheme + '/img/themestyle.css';
        
        if (styleobj.href != urlsrc)
            styleobj.href = urlsrc;
    }
    
    /*
        Loads details dialog for an event
        
        pEvent - Mouse event
        pId - Event id
    */
    this.showDetails = function(pEvent, pId)
    {
        clearTimeout(this.autoreload);
        this.prepDialog(pEvent, pId);
        this.loadRemoteData(this.base_url + 'details.js.php?pid=' + pId + '&lang=' +
                            this.current_lang, 'am_cal.onDetailsLoaded');
    }
    
    this.showData = function(pEvent, pId)
    {
        clearTimeout(this.autoreload);
        this.prepDialog(pEvent, pId);
        this.loadRemoteData(this.base_url + 'graph.js.php?pid=' + pId + '&lang=' +
                            this.current_lang, 'am_cal.onGraphDataLoaded');
    }
    
    this.onGraphDataLoaded = function(pData)
    {
        this.setDialogContent(pData.html);
    }
    
    /*
        Triggers when details data loads
    */
    this.onDetailsLoaded = function(pData)
    {
        this.setDialogContent(pData.html);
    }
    
    /*
        Loads graphs dialog for an event
        
        pEvent - Mouse event
        pId - Event id
    */
    this.showGraph = function(pEvent, pId)
    {
        clearTimeout(this.autoreload);
        alert('This function is temporarily unavailable.');
    }
    
    /*
        Dims the screen and prapares/shows a content dialog
        
        pEvent - Mouse event
    */
    this.prepDialog = function(pEvent)
    {
        var fullscr = document.getElementById('amcal_fullscr');
        var tbldims = getElementDimensions('amcal_caltbl');
        var tblpos = getElementPos('amcal_caltbl');
        var neww = tbldims.width;
        var newh = tbldims.height;
        fullscr.style.width = neww + 'px';
        fullscr.style.height = newh + 'px';
        fullscr.style.left = tblpos.left + 'px';
        fullscr.style.top = tblpos.top + 'px';
        fullscr.style.display = 'block';
        var mpos = window.mousePos(pEvent);
        var newh = 400;
        var neww = 700;
        var dims = document.dimensions();
        var dlg = document.getElementById('amcal_dlg');
        var dlghdr = document.getElementById('amcal_dlghdr');
        var dlgcontent = document.getElementById('amcal_dlgcontent');
        var newy = 0;
        var newx = 0;
        var conth = 0;

        newy = mpos.y;
        
        if (newy + newh > tbldims.height + tblpos.top)
            newy = tbldims.height + tblpos.top - newh;
 
        conth = newh - 20; 
        newx = Math.round(tbldims.width / 2) - Math.round(neww / 2);
        newx = newx + tblpos.left;
        dlg.style.left = newx + 'px';
        dlg.style.top = newy + 'px';
        dlg.style.width = neww + 'px';
        dlg.style.height = newh + 'px';
        dlgcontent.style.height = conth + 'px';
        dlgcontent.innerHTML = '';
        dlgcontent.style.background = 'url(' + this.base_url + 'themes/' + this.current_theme + '/img/pb.gif) no-repeat center center';
        dlg.style.display = 'block';
        this.dialog_open = true;
    }
    
    /*
        Hides a content dialog
    */
    this.hideDialog = function()
    {
        var fullscr = document.getElementById('amcal_fullscr');
        fullscr.style.display = 'none';
        document.getElementById('amcal_dlg').style.display = 'none';
        this.dialog_open = false;
        this.autoreload = setTimeout('am_cal.reloadInitialCalendar()', 60000);
    }
    
    /*
        Sets a content dialog HTML
        
        pData - Html to assign to the dialog
    */
    this.setDialogContent = function(pData)
    {
        var dlg = document.getElementById('amcal_dlgcontent');
        dlg.style.background = '#FFFFFF';
        dlg.innerHTML = pData;
    }
    
    /*
        An event, triggered on a special checkbox click
    */
    this.cbEvent = function(pObj, pVarName, pOnValue, pOffValue)
    {
        if (pObj.className == 'amcal_scboff')
        {
            pObj.className = 'amcal_scbon';
            this.setVar(pVarName, pOnValue);
        }
        else
        {
            pObj.className = 'amcal_scboff';
            this.setVar(pVarName, pOffValue);
        }
        
        document.getElementById('amcal_changesbuttons').style.display = 'block';
        clearTimeout(this.autoreload);
    }
    
    /*
        An event, triggered on a special radio button click
    */
    this.rbEvent = function(pObj, pVarName, pVarValue)
    {
        if (pObj.className != 'amcal_scboff')
            return;
        
        var rboxes = document.getElementsByName(pObj.name);
        
        for (var i = 0; i < rboxes.length; i++)
            rboxes[i].className = 'amcal_scboff';
            
        pObj.className = 'amcal_scbon';
        this.setVar(pVarName, pVarValue);
        document.getElementById('amcal_changesbuttons').style.display = 'block';
        clearTimeout(this.autoreload);
    }
    
    /*
        Toggles the settings header on or off
    */
    this.toggleSets = function()
    {
        var obj = document.getElementById('amcal_setsdiv');
        
        if (obj.className == 'amcal_filterswrap')
        {
            this.setVar('showsets', 'no');
            this.saveAndReload();
        }
        else
        {
            this.setVar('showsets', 'yes');
            this.saveAndReload();
        }
    }
    
    /*
        Saves current vars and reloads the page
    */
    this.saveAndReload = function()
    {
        var url = this.base_url + 'calsaver.js.php' + this.getUrlParams();
        this.loadRemoteData(url, 'am_cal.onCalendarLoaded');
    }
    
    /*
        Initializes the language switcher
    */
    this.switchLang = function()
    {
        var obj = document.getElementById('amcal_langsdialog');
        var tblpos = getElementPos('amcal_caltbl');
        obj.style.top = (tblpos.top + 23) + 'px';
        obj.style.left = (tblpos.left + 1) + 'px';
        toggleVis('amcal_langsdialog');
    }
    
    /*
        Initializes the timezone switcher
    */
    this.switchTZ = function()
    {
        var obj = document.getElementById('amcal_timezonesdialog');
        var tblpos = getElementPos('amcal_caltbl');
        var tbldims = getElementDimensions('amcal_caltbl');
        obj.style.top = (tblpos.top + 23) + 'px';
        obj.style.left = (tblpos.left -201 + tbldims.width) + 'px';
        toggleVis('amcal_timezonesdialog');
    }
    
    /*
        Timezone selection event
    */
    this.onSelectTZ = function(pTZ)
    {
        this.setVar('zone', pTZ);
        this.saveAndReload();
    }
    
    /*
        Language selection event
    */
    this.onSelectLang = function(pLang)
    {
        this.setVar('lang', pLang);
        this.saveAndReload();
    }
    
    /*
        Prepares and shows a custom date filter selection dialog
    */
    this.selectCustomDateFilter = function()
    {
        document.getElementById('amcal_inpdrleft').value = this.getVar('dfstart');
        document.getElementById('amcal_inpdrright').value = this.getVar('dfend');
        this.showDlg('amcal_daterangedlg');
    }
    
    /*
        Shows a specified dialog
        
        pDialog - The name of the dialog's div
    */
    this.showDlg = function(pDialog)
    {
        clearTimeout(this.autoreload);
        var dlg = document.getElementById(pDialog);
        var dims = getElementDimensions('amcal_caltbl');
        var tpos = getElementPos('amcal_caltbl');
        var ddims = getElementDimensions(pDialog);
        dlg.style.left = (tpos.left + dims.width / 2 - ddims.width / 2) + 'px';
        dlg.style.top = (tpos.top + 100) + 'px';
        dlg.style.visibility = 'visible';
    }
    
    /*
        Updates the custom date filter range from input fields and hides
        the custom filter input dialog.
    */
    this.updateDFRange = function()
    {
        var dr = document.getElementById('amcal_inpdrright').value;
        var dl = document.getElementById('amcal_inpdrleft').value;
        this.setVar('dfstart', dl);
        this.setVar('dfend', dr);
        document.getElementById('amcal_datefiltercustom').className = 'amcal_scboff';
        this.rbEvent(document.getElementById('amcal_datefiltercustom'), 'dfilter', 'dfcustom');
        this.hideDlg('amcal_daterangedlg');
    }
    
    /*
        Hides a specified dialog
        
        pDialog - The name of the dialog's div
    */
    this.hideDlg = function(pDialog)
    {
        document.getElementById(pDialog).style.visibility = 'hidden';
        this.autoreload = setTimeout('am_cal.reloadInitialCalendar()', 60000);
    }
    
    /*
        Restores default settings (clears cookies)
    */
    this.restoreDefaults = function()
    {
        var url = this.base_url + 'calreset.js.php' + this.getOwnerParams();
        this.loadRemoteData(url, 'am_cal.onCalendarLoaded');
    }
    
    /*
        Loads instructions for ie users
    */
    this.ieInstructions = function()
    {
        var url = this.base_url + 'ieinstructions.js.php?lang=' + this.current_lang;
        var obj = document.getElementById('amcal_iewarning');
        obj.innerHTML = '...';
        this.loadRemoteData(url, 'am_cal.ieInstructionsLoaded');
    }
    
    /*
        Ie instructions load trigger
    */
    this.ieInstructionsLoaded = function(pData)
    {
        var obj = document.getElementById('amcal_iewarning');
        obj.innerHTML = pData.html;
    }

}


// Create a new calendar object and call an initializer function
window.am_cal = new AMCal();
amcal_init();

