/*
    TellMeNow v1.0 - TellMeNow.ca Main JavaScript Controller
      - Developed for use with TellMeNow.ca.
      - Script Author
            - Robert J. Secord, B.Sc. <Robert.Secord@edgeip.com>
      - Dependancies:
            - Mootools v1.11 or later.  <www.mootools.net>
      - Tested Browsers:
            - Windows: IE 6+, Firefox 2+, Opera 9+, Netscape 8+
*/

var TellMeNow = new Class(
{
    Implements: [new Options, new Events],

    // -------------------------------------------------------------------------------------------------------------
    // Member Variables
    options:
    {
        BasePath:     '',
        GraphicsPath: '',
        UseSpecialFX: true,

        // Optional Events:
        onPageLoad:  Class.empty,
        onPageReady: Class.empty,

        // Developer Use:
        DebugMode: false    // Alerts on All Client-Side Developer Errors/Warnings within all Custom Controls
    },

    // -------------------------------------------------------------------------------------------------------------
    // Class Constructor (options = JSON Object)
    initialize: function( options )
    {
        this.setOptions( options );

        // Check for Required Variables for Object Instantiation
        if( this.options.GraphicsPath.length < 1 ) return this.ErrorAlert('Object Construction Failed - Invalid GraphicsPath Supplied!');

        // Attach Window Events
        window.addEvents(
        {
            'load':     this.OnLoad.bind(this),
            'domready': this.OnDomReady.bind(this)
        });
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: DOM Ready Event (before OnLoad)
    OnDomReady: function()
    {
        // Lower Opacity for Custom Elements
        //$$('.LowerOpacity').setStyles({'opacity': '0.65'});

        // Fire Page Ready Event
        this.fireEvent('onPageReady', this, 0);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Page Loaded Event
    OnLoad: function()
    {
        // Moo Smooth Scroll
        new SmoothScroll();

        // Standard Page Upgrades
        this.LinkHeaderImage();
        this.BuildUserPassBoxes();
        this.BuildCommentBox();
        this.AlternatingRows();
        this.FixInputHover();
        this.EnableHotKeys();

        // Slide Paper into View
        this.PaperSlide();

        // Survey Questions Sticky State
        this.StickyStates();

        // Fire Page Loaded Event
        this.fireEvent('onPageLoad', this, 0);
    },

    // -------------------------------------------------------------------------------------------------------------
    // External Routine: Open a Popup Window
    PopupWin: function( szURL, oArgs )
    {
        var oOptions = $extend(
        {
            Name:     '',
            Top:      100,    Left:     100,
            Width:    800,    Height:   600,
            Location: 'yes',  Menubar:  'yes',
            Status:   'yes',  Toolbar:  'yes',
            Scroll:   'auto', Resize:   'yes'
        }, oArgs );

        var szOptions = 'top='+oOptions.Top+',left='+oOptions.Left+',width='+oOptions.Width+',height='+oOptions.Height+',location='+oOptions.Location+',menubar='+oOptions.Menubar+',status='+oOptions.Status+',toolbar='+oOptions.Toolbar+',scrollbars='+oOptions.Scroll+',resizable='+oOptions.Resize;
        window.open( szURL, oOptions.Name, szOptions );
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    StickyStates: function()
    {
        var aStickies = $$('.StickyState'), szActiveState = 'Active';
        if( !aStickies ) return;

        // Loop through all StickyState Lists
        aStickies.each(function( oStickyList )
        {
            oStickyList.getElements('a').each(function( oLink )
            {
                oLink.addEvent('click', function( oEvent )
                {
                    oEvent = new Event(oEvent).stop();
                    var oTarget = oEvent.target;

                    // Ensure Target is the Link Element
                    while( oTarget.get('tag') != 'a' ) oTarget = oTarget.getParent();

                    // Get Parent List
                    var oParent = oTarget.getParent();
                    while( !oParent.hasClass('StickyState') ) oParent = oParent.getParent();

                    // Loop through all List Items (Mark Active, Unmark Inactive)
                    oParent.getElements('a').each(function( oStickyLink )
                    {
                        if( oStickyLink == oTarget )
                            oStickyLink.addClass(szActiveState);
                        else
                            if( oStickyLink.hasClass(szActiveState) ) oStickyLink.removeClass(szActiveState);
                    }, this);
                }.bindWithEvent(this));
            }, this);
        }, this);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Alternates Styles for every other Row in Alternating Row Tables
    AlternatingRows: function()
    {
        var aTables = $$('.AlternateRows'), szAltRow = 'AltRow';
        if( !aTables ) return;

        // Get Alternating Tables on Page
        aTables.each(function( oTable )
        {
            // Add Class to Every Other Row
            iRowCounter = 0;
            oTable.getElements('tbody tr').each(function( oRow )
            {
                if( iRowCounter++ % 2 ) oRow.addClass(szAltRow);
            }.bind(this));
        }.bind(this));
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Fix INPUT Hover for IE
    FixInputHover: function()
    {
        if( !Browser.Engine.trident4 ) return;

        $$('.iButton').each(function( el )
        {
            el.addEvent('mouseover', function(){ new Element(this).removeClass('iButton').addClass('iButtonHover'); } );
            el.addEvent('mouseout', function(){ new Element(this).removeClass('iButtonHover').addClass('iButton'); } );
        });

        $$('.Login').each(function( el )
        {
            el.addEvent('mouseover', function(){ new Element(this).removeClass('Login').addClass('LoginHover'); } );
            el.addEvent('mouseout', function(){ new Element(this).removeClass('LoginHover').addClass('Login'); } );
        });

        $$('.MoreOptions').each(function( el )
        {
            el.addEvent('mouseover', function(){ new Element(this).removeClass('MoreOptions').addClass('MoreOptionsHover'); } );
            el.addEvent('mouseout', function(){ new Element(this).removeClass('MoreOptionsHover').addClass('MoreOptions'); } );
        });
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Dynamic content for User/Pass boxes
    BuildUserPassBoxes: function()
    {
        var u = document.getElement('input[id$=txtUserName]');
        var p = document.getElement('input[id$=txtPassword]');
        if( !u || !p ) return;

        if( u )
        {
            u.setProperty('value', u.getProperty('title').trim());
            u.addEvents(
            {
                'focus': function()
                {
                    el = new Element(this);
                    if( el.getProperty('value').trim() == el.getProperty('title').trim() )
                        el.setProperty('value', '');
                },
                'blur': function()
                {
                    el = new Element(this);
                    if( el.getProperty('value').trim() == '' )
                        el.setProperty('value', el.getProperty('title').trim());
                }
            });
        }

        if( p )
        {
            p.setProperty('value', p.getProperty('title').trim());
            p.addEvents(
            {
                'focus': function()
                {
                    el = new Element(this);
                    if( el.getProperty('value').trim() == el.getProperty('title').trim() )
                        el.setProperty('value', '');
                },
                'blur': function()
                {
                    el = new Element(this);
                    if( el.getProperty('value').trim() == '' )
                        el.setProperty('value', el.getProperty('title').trim() );
                }
            });
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: 
    BuildCommentBox: function()
    {
        this.szCommentsValue = '';
        this.elComments = document.getElement('textarea[id$=txtaComments]');
        if( this.elComments )
        {
            this.szCommentsValue = this.elComments.getProperty('value').trim();
            this.elComments.addEvents(
            {
                'focus': function()
                {
                    if( this.elComments.getProperty('value').trim() == this.szCommentsValue )
                        this.elComments.setProperty('value', '');
                }.bind(this),
                'blur': function()
                {
                    if( this.elComments.getProperty('value').trim() == '' )
                        this.elComments.setProperty('value', this.szCommentsValue);
                }.bind(this)
            });
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: 
    EnableHotKeys: function()
    {
        var oHotKeyA = document.getElement('input[id$=lstAnswer_0]'); if( oHotKeyA ) oHotKeyA.setProperty('accesskey', 'a');
        var oHotKeyB = document.getElement('input[id$=lstAnswer_1]'); if( oHotKeyB ) oHotKeyB.setProperty('accesskey', 'b');
        var oHotKeyC = document.getElement('input[id$=lstAnswer_2]'); if( oHotKeyC ) oHotKeyC.setProperty('accesskey', 'c');
        var oHotKeyD = document.getElement('input[id$=lstAnswer_3]'); if( oHotKeyD ) oHotKeyD.setProperty('accesskey', 'd');
        var oHotKeyE = document.getElement('input[id$=lstAnswer_4]'); if( oHotKeyE ) oHotKeyE.setProperty('accesskey', 'e');
        var oHotKeyF = document.getElement('input[id$=lstAnswer_5]'); if( oHotKeyF ) oHotKeyF.setProperty('accesskey', 'f');
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    PaperSlide: function()
    {
        var oSlide = { Paper: $('Slide-Paper'), Links: $('Slide-Paper-Links') };
        if( oSlide.Paper && oSlide.Links )
        {
            new Fx.Morph(oSlide.Paper, {duration: 1000, wait: false})
                .set({'margin-left': (Browser.Engine.trident)?'-740px':'-525px'})
                .start({'margin-left': (Browser.Engine.trident)?'-545px':'-200px'});
                
            new Fx.Morph(oSlide.Links, {duration: 1000, wait: false})
                .set({'margin-left': (Browser.Engine.trident)?'-740px':'-525px'})
                .start({'margin-left': (Browser.Engine.trident)?'-545px':'-200px'});
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    LinkHeaderImage: function()
    {
        var oHeader = document.body.getElement('.Header');
        if( oHeader )
            oHeader.setStyle('cursor', 'pointer')
                   .set('title', 'Return to Home Page')
                   .addEvent('click', function(){location.href = this.options.BasePath + 'Latest.aspx';}.bind(this));
    },

    // -------------------------------------------------------------------------------------------------------------
    // Validation Routines:
    // -------------------------------------------------------------------------------------------------------------

    // -------------------------------------------------------------------------------------------------------------
    // Check the Validity of a URL
    checkURL: function( szURL, oOptions )
    {
        var i, aSubProtocols = ['view-source:','javascript:'];
        var aValidProtocols = ['http','https','ftp','gopher','news','nntp'];

        oOptions = $merge({AbsoluteStart: true, AnchorStart: true, QueryStart: true}, oOptions);

        // Check for Email
        if( szURL.search(/mailto:/gi) > -1 )
        {
            if( !this.checkEmail( szURL.replace(/mailto:/gi, '') ) )
            {
                alert('The Email address you supplied is Invalid!');
                return false;
            }
            else return true;
        }

        // Remove Sub-Protocols (Allowed but not used in Validation)
        for( i = 0; i < aSubProtocols.length; i++ ) szURL = szURL.replace(new RegExp(aSubProtocols[i], 'gi'), '');

        // Check for absense of Protocol and Presence of Sub-domain "www"
        if( szURL.search(/www./gi) == 0 ) szURL = 'http://' + szURL;


        // Break URI into Component Parts
        var oURIParts = this.parseUri( szURL );

        // Check for Valid Protocol
        var bValidURL = false;
        if( oURIParts['protocol'].length )
        {
            for( i = 0; i < aValidProtocols.length; i++ )
                if( oURIParts['protocol'] == aValidProtocols[i] )
                    bValidURL = true;
        }
        else // No Protocol, Check for Valid Path
        {
            if( !oURIParts['host'].length  ) // Absolute/Anchored/Queried Paths have No Host
            {
                if( oOptions.AbsoluteStart && oURIParts['relative'].charAt(0) == '/' ) bValidURL = true;
                if( oOptions.AnchorStart && oURIParts['relative'].charAt(0) == '#' ) bValidURL = true;
                if( oOptions.QueryStart && oURIParts['relative'].charAt(0) == '?' ) bValidURL = true;
            }
        }

        return bValidURL;
    },
    parseUri: function(str)
    {
        var o =
        {
            strictMode: true,
            key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
            q:   { name:   "queryKey", parser: /(?:^|&)([^&=]*)=?([^&]*)/g },
            parser:
            {
                strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
                loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
            }
        },
        m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
        uri = {},
        i   = 14;   // URL Parts

        while (i--) uri[o.key[i]] = m[i] || "";

        uri[o.q.name] = {};
        uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
            if ($1) uri[o.q.name][$1] = $2;
        });
        return uri;
    },

    // -------------------------------------------------------------------------------------------------------------
    // Check the Validity of an Email Address
    checkEmail: function( szEmail )
    {
        if( szEmail.toLowerCase().indexOf(" ") > 0 ) return false;
        if( szEmail.toLowerCase().indexOf("@") != szEmail.toLowerCase().lastIndexOf("@") ) return false;

        //make it in  single line
        var emailPat=/^[a-z0-9]+([_|\-|\.|a-z0-9]+)*\@([a-z0-9]+((_*)(-*)(.*)[a-z0-9]*)*\.(com|edu|biz|org|gov|int|info|mil|net|arpa|name|museum|coop|aero|[a-z][a-z])|(\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]))$/;

        if (!emailPat.test(szEmail.toLowerCase()))
            return false;
        return true;
    },

    // -------------------------------------------------------------------------------------------------------------
    // Replace Accented Characters
    stripVowelAccent: function( szValue )
    {
        var s = szValue;
        var rExps=[ /[\xC0-\xC6]/g, /[\xE0-\xE6]/g,
        /[\xC8-\xCB]/g, /[\xE8-\xEB]/g,
        /[\xCC-\xCF]/g, /[\xEC-\xEF]/g,
        /[\xD2-\xD6]/g, /[\xF2-\xF6]/g,
        /[\xD9-\xDC]/g, /[\xF9-\xFC]/g,
        /[Ç]/g,/[ç]/g,/\s/g,/[^a-zA-ZÇç\xC0-\xFC]/g ];

        var repChar=['A','a','E','e','I','i','O','o','U','u','C','c','',''];

        for(var i=0; i<rExps.length; i++)
            s = s.replace(rExps[i],repChar[i]);
        return s;
    },

    // -------------------------------------------------------------------------------------------------------------
    //
    checkDate: function(listYear, listMonth, listDate)
    {
        if (listYear==null || listYear.selectedIndex==0)    return false;
        if (listMonth==null || listMonth.selectedIndex==0)  return false;
        if (listDate==null || listDate.selectedIndex==0)    return false;

        var year=parseInt(listYear.options[listYear.selectedIndex].value);
        var month=parseInt(listMonth.options[listMonth.selectedIndex].value);
        var date=parseInt(listDate.options[listDate.selectedIndex].value);

        var daysPerMonth=new Array(31,28,31,30,31,30,31,31,30,31,30,31);
        if (this.isLeap(year))   daysPerMonth[1]=29;

        if (date>daysPerMonth[month-1]) return false;
        return true;
    },

    // -------------------------------------------------------------------------------------------------------------
    //
    isLeap: function( iYear )
    {
        var result;
        if (iYear % 4 != 0)  result=false;
        else if (iYear % 100 != 0)   result=true;
        else if (iYear % 400 != 0)   result=false;
        else result=true;
        return result;
    },

    // -------------------------------------------------------------------------------------------------------------
    //
    isChar: function( szValue )
    {
        var chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        var k;
        for (k=0;k<szValue.length;k++)
            if (chars.indexOf(szValue.substring(k,k+1))<0)
                return false;
        return true;
    },

    // -------------------------------------------------------------------------------------------------------------
    //
    isDigit: function( szValue )
    {
        var digits="0123456789";
        var k;
        for (k=0;k<szValue.length;k++)
            if (digits.indexOf(szValue.substring(k,k+1))<0)
                return false;
        return true;
    },

    // -------------------------------------------------------------------------------------------------------------
    //
    isFloat: function( szValue )
    {
        var digits="0123456789.";
        var k;
        for (k=0;k<str.length;k++)
            if (digits.indexOf(szValue.substring(k,k+1))<0)
                return false;
        return true;
    },

    // -------------------------------------------------------------------------------------------------------------
    // Check if a String contains only Spaces
    isSpaces: function( szValue )
    {
       var temp = szValue;
       var obj = / /g;
       while (temp.match(obj)) { temp = temp.replace(obj, ""); }
       if (temp=="") return true;
       return false;
    },

    // -------------------------------------------------------------------------------------------------------------
    //
    isAlphaNumeric: function( szValue )
    {
        var digits="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        var k;
        for (k=0;k<szValue.length;k++)
            if (digits.indexOf(szValue.substring(k,k+1))<0)
                return false;
        return true;
    },



    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Debug-Mode Error Alerts
    ErrorAlert: function( szErrorMsg )
    {
        // Debug Alert Message
        if( this.options.DebugMode )
            alert('[' + this.ClassName + ' ' + this.ClassVersion + '] -- DEV-ERROR --\n\n' + szErrorMsg);
        return false;
    },

    // -------------------------------------------------------------------------------------------------------------
    // Class Name, Version, Author
    ClassName:    'TellMeNow',
    ClassVersion: '1.0',
    ClassAuthor:  'Robert J. Secord, B.Sc.'
});