/*
 * $Id: IEWarning.js,v 1.4 2005/09/24 21:13:49 k Exp $
 * Copyright (C) 2005 Klaus Reimer <k@ailis.de>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to permit
 * persons to whom the Software is furnished to do so, subject to the
 * following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 */


/**
 * IEWarning. Displays a nice warning if user uses an Internet Explorer.
 * The warning says that the browser is too old and it links to
 * mozilla.org.
 *
 * Usage is very easy. Just put this script and the two images somewhere in
 * your web, load the script into your HTML page and then create an instance
 * of the IEWarning class and pass the path to the two images to the
 * constructor. You should do this in the onload event of the body so the
 * script is executed after your page is fully loaded. Example:
 *
 *   <head>
 *     <script type="text/javascript" src="scripts/IEWarning.js"></script>
 *   </head>
 *   <body onload="new IEWarning('scripts')">
 *     ...
 *
 * @param imageDir
 *            The path to the image directory
 * @param force
 *            Optional parameter. Set to true to force skipping the
 *            check for Internet Explorer
 * @author Klaus Reimer (k@ailis.de)
 * @version $Revision: 1.4 $
 */
  
function IEWarning(imageDir, force)
{
    // Do nothing if browser is not an internet explorer
    if (!force && navigator.appName != "Microsoft Internet Explorer") return;
    
    // Do nothing if user has closed the warning
    if (this.getCookie("IEWarningClosed")) return;
    
    // Store image directory
    this.imageDir = imageDir;

    // Build HTML for the warning
    this.buildHTML();
    
    // Initialize internal variables
    this.clicked = false;
    
    // Start the timer if the warning is shown for the first time
    if (!this.getCookie("IEWarningFirst"))
    {
        setTimeout("IEWarning.scrollToView('" + this.html.id + "')", 1000);
    }
    else
    {
        // Not the first time? Then display the warning immediately without
        // scrolling
        this.html.style.height = "22px";
    }
}


/** The warning text */
IEWarning.message = new Object();
IEWarning.message["c"] = "Internet Explorer has detected that it's rendering engine is too old for the internet. Please click here to upgrade it...";
IEWarning.message["de"] = "Internet Explorer hat erkannt, dass die Rendering-Engine zu alt f\u00fcr das Internet ist. Klicken Sie hier, um diese zu aktualisieren...";

/** The link url */
IEWarning.linkURL = "http://www.mozilla.com/";


/**
 * Static run method to easily run an instance of the class
 *
 * @param imageDir
 *            The path to the image directory
 * @param force
 *            Optional parameter. Set to true to force skipping the
 *            check for Internet Explorer
 */

IEWarning.run = function(imageDir, force)
{
    new IEWarning(imageDir, force);
};


/**
 * Timer function. Handles the nice Into-view-scrolling of the warning
 *
 * @param id
 *            The id of the main HTML element
 */

IEWarning.scrollToView = function(id)
{
    var html;
    var height;
    
    // Get HTML element and determine the height
    html = document.getElementById(id);
    height = parseInt(html.style.height) || 0;
    
    // Increase height;
    height = Math.min(22, height + 2);
    html.style.height = height + "px";
    
    // If control is not high enough then trigger timer again
    if (height < 22)
    {
        setTimeout("IEWarning.scrollToView('" + id + "')", 25);
    }
    else
    {
        // Element is finished? Set a cookie to remember this
        html.control.setCookie("IEWarningFirst", true, null, "/");
    }
};


/**
 * Builds the HTML code for the IE warning
 */
 
IEWarning.prototype.buildHTML = function()
{
    var panel;
    var body;
    var text;
    var message;
    
    // Create main html element
    this.html = document.createElement("div");
    this.html.id = "IEWarning";
    this.html.control = this;
    this.html.style.position = "relative";
    this.html.style.height = "0px";
    this.html.style.overflow = "hidden";
    this.html.onmouseover = this.handleMouseover;
    this.html.onmouseout = this.handleMouseout;
    this.html.onmousedown = this.handleMousedown;
    this.html.onmouseup = this.handleMouseup;
    this.html.onmousemove = this.handleMousemove;
    this.html.onclick = this.handleClick;
    this.html.style.backgroundColor = "#ffffe1";
    
    // Create the panel which holds all the visible stuff
    panel = document.createElement("div");
    panel.control = this;
    panel.style.position = "absolute";
    panel.style.width = "100%";
    panel.style.bottom = "0";
    panel.style.height = "22px";
    panel.style.borderBottom = "1px solid #85878c";
    panel.style.background = "url(" + this.imageDir 
        + "/firefox.png) no-repeat 2px 3px";
    this.html.appendChild(panel);      
    
    // Create the text element
    text = document.createElement("div");
    text.control = this;
    text.style.color = "#000";
    text.style.borderBottom = "1px solid #a7a6aa";
    text.style.height = "17px";
    text.style.fontFamily = "tahoma, sans-serif";
    text.style.fontSize = "11px";
    text.style.padding = "4px 0 0 22px";
    text.style.textDecoration = "none";
    text.style.cursor = "default";
    text.style.background = "url(" + this.imageDir 
        + "/close.png) no-repeat right top";
    message = IEWarning.message[this.getBrowserLanguage()]
        || IEWarning.message["c"];
    text.appendChild(document.createTextNode(message));
    text.onmousedown = this.ignoreEvent;
    text.onmousemove = this.ignoreEvent;
    panel.appendChild(text);
    
    // Put HTML code at the beginning of the page
    body = document.getElementsByTagName("body")[0];
    body.insertBefore(this.html, body.firstChild);
};


/**
 * Handles mouseover event to visualize the hover effect
 */

IEWarning.prototype.handleMouseover = function(evt)
{
    var text;
    
    // Redirect event to control
    if (this.control) return this.control.handleMouseover(evt ? evt : event);
    
    // Visualize hover effect
    this.html.style.backgroundColor = "#335ea8";
    text = this.html.firstChild.firstChild;
    text.style.backgroundPosition = "right bottom";
    text.style.color = "#fff";
};


/**
 * Handles mouseout event to reset the hover effect
 */

IEWarning.prototype.handleMouseout = function(evt)
{
    var text;
    
    // Redirect event to control
    if (this.control) return this.control.handleMouseout(evt ? evt : event);
    
    // Visualize hover effect
    this.html.style.backgroundColor = "#ffffe1";
    text = this.html.firstChild.firstChild;
    text.style.backgroundPosition = "right top";
    text.style.color = "#000";

    // Remember that user has stopped clicking
    this.clicked = false;
};


/**
 * Handles mousedown event to visualize the click effect on close button
 */

IEWarning.prototype.handleMousedown = function(evt)
{
    var text;
    
    // Redirect event to control
    if (this.control) return this.control.handleMousedown(evt ? evt : event);
    
    // Get x click position
    x = evt.layerX || evt.offsetX || 0;
    
    // Get the width of the warning bar
    width = this.html.offsetWidth;
    
    // Visualize click effect if user clicked on close button
    if (x > width - 14)
    {
        text = this.html.firstChild.firstChild;
        text.style.backgroundPosition = (width - 13) + "px -20px";
    }
    
    // Remember that user has clicked
    this.clicked = true;
};


/**
 * Handles mouseup event to visualize the de-click effect on close button
 */

IEWarning.prototype.handleMouseup = function(evt)
{
    var text;
    
    // Redirect event to control
    if (this.control) return this.control.handleMouseup(evt ? evt : event);

    // Put button back to normal position    
    text = this.html.firstChild.firstChild;
    text.style.backgroundPosition = "right bottom";

    // Remember that user has stopped clicking
    this.clicked = false;
};


/**
 * Handles mousemove event to click and de-click close button if user moves
 * the mouse around.
 */

IEWarning.prototype.handleMousemove = function(evt)
{
    var text;
    
    // Redirect event to control
    if (this.control) return this.control.handleMousemove(evt ? evt : event);
    
    // Do nothing if user has not clicked
    if (!this.clicked) return;

    // Get x click position
    x = evt.layerX || evt.offsetX || 0;
    
    // Get the width of the warning bar
    width = this.html.offsetWidth;
    
    // Check if mouse cursor is over the close button or not
    if (x <= width - 14)
    {
        // Put button back to normal position
        text = this.html.firstChild.firstChild;
        text.style.backgroundPosition = "right bottom";
    }
    else
    {
        // Put button to clicked state
        text = this.html.firstChild.firstChild;
        text.style.backgroundPosition = (width - 13) + "px -20px";
    }
};


/**
 * Handles click event to perform actions if user clicks on the warning or
 * the close button.
 */

IEWarning.prototype.handleClick = function(evt)
{
    var panel;
    var x;
    var width;
    
    // Redirect event to control
    if (this.control) return this.control.handleClick(evt ? evt : event);

    // Get x click position
    x = evt.layerX || evt.offsetX || 0;
    
    // Get the width of the warning bar
    width = this.html.offsetWidth;
    
    // Remove the warning if user clicked on the close button
    if (x > width - 14)
    {
        this.html.parentNode.removeChild(this.html);
        
        // Remember that the user don't want this warning anymore (at least
        // for the current session)
        this.setCookie("IEWarningClosed", true);
        return;
    }
    
    // Go to link url
    location.href = IEWarning.linkURL;
};


/**
 * Dummy event handler. Just ignores an event and prevents further event
 * propagation. Used to disable text selection on the warning text
 */
 
IEWarning.prototype.ignoreEvent = function(evt)
{
    return false;
};
    

/**
 * Sets a cookie. An argument defaults when it is assigned null as a 
 * placeholder. A null placeholder is not required for trailing omitted 
 * arguments.
 *
 * @param name
 *            Name of the cookie
 * @param value
 *            Value of the cookie
 * @param expires
 *            Expiration date of the cookie 
 *            (Optional. Defaults to end of current session)
 * @param path
 *            Path for which the cookie is valid
 *            (Optional. Defaults to path of calling document)
 * @param domain
 *            Domain for which the cookie is valid
 *            (Optional. Defaults to domain of calling document)
 * @param secure
 *            Boolean value indicating if the cookie transmission requires
 *            a secure transmission
 *            (Optional. Defaults to false)
 */

IEWarning.prototype.setCookie = function(name, value, expires, path, domain, 
    secure)
{
    document.cookie = name + "=" + escape(value) +
       ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
};


/**
 * Returns the value for the cookie with the specified name
 *
 * @param name
 *            Name of the desired cookie
 * @return String containing value of specified cookie or null
 *         if cookie does not exist
 *
 */

IEWarning.prototype.getCookie = function(name)
{
    var end;
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
  
    if (begin == -1) 
    {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    }
    else begin += 2;
    end = document.cookie.indexOf(";", begin);
    if (end == -1) end = dc.length;
    return unescape(dc.substring(begin + prefix.length, end));
};


/**
 * Deletes a cookie. Path and domain default if assigned null or omitted 
 * if no explicit argument proceeds
 *
 * @param name
 *            Name of the cookie
 * @param path
 *            Path of the cookie (must be same as path used to create cookie)
 *            (Optional. Defaults to path of calling document)
 * @param domain
 *            Domain of the cookie (must be same as domain used to create 
 *            cookie) (Optional. Defaults to domain of calling document)
 */

IEWarning.prototype.deleteCookie = function(name, path, domain)
{
    if (getCookie(name))
    {
        document.cookie = name + "=" +
            ((path) ? "; path=" + path : "") +
            ((domain) ? "; domain=" + domain : "") +
            "; expires=Thu, 01-Jan-70 00:00:01 GMT";
    }
};


/**
 * Returns the browser language. Example: "en" for an english browser
 * or "de" for a german browser
 *
 * @return The browser language as a lower case 2-character language
 *         specifier.
 */

IEWarning.prototype.getBrowserLanguage = function()
{
    return (navigator.language || navigator.userLanguage).substr(0, 2);
};
