String.prototype.startsWith = function(str)
{
    return ( this.indexOf ( str ) === 0 );
}

String.prototype.endsWith = function(str)
{
    return ( this.substr( -1 ) === str );
}

function fss_pageLoader ( targetId )
{
    this.targetElement  = document.getElementById( targetId );
    this.indexedJsFiles = new Array();
    
    this.debugText      = "";
    this.init_adjustLinks( );
};

fss_pageLoader.prototype.loadPage = function ( url, isRedirect, historyCall, ev )
{    
    var uri = this.parseUri( url );

    if( !url.startsWith( "#" ) && !url.match( "paypalProcess/initRedirect" ) && ( uri.domain == window.location.hostname || uri.domain == "" ) )
    {  
        if( ev )
            this.stopEvent( ev );
        
        if( uri.path != window.location.pathname || historyCall )
        {
            if( !historyCall && !this.isIE( ) && window.history.pushState !== "undefined" )
            {
                window.history.pushState( { page: uri.path }, "Hadden Sayers Official Website", uri.path );
            }
        }
        
        if( !isRedirect )
            this.showProgressScreen( );
        
        var request  = new window.fss_pageLoader_ajax( url );
        var pointer  = this;
        request.ajaxRequest( { ajax: "true" }, function( xmlHttpObject ){ pointer.callbackonfinish( xmlHttpObject, uri ); })
        
        return false;
    }
    else
    {
        return true;
    }
};

window.fss_pageLoader.prototype.postForm = function ( form, ev )
{
    var url    = form.action;
    var method = form.method;
    var uri    = this.parseUri( form.action );

    if( !url.startsWith( "#" ) && !url.match( "paypal" ) && ( uri.domain == window.location.hostname || uri.domain == "" ) )
    {  
        if( ev )
            pointer.stopEvent( ev );
        
        this.showProgressScreen( );
        
        if( this.isIE( ) )
            window.location.hash = this.currentURL = uri.path;
        
        var form_data       = this.get_form_data( form );
        
        if( "fss_ajax_fields" in form_data && "fss_ajax_values" in form_data )
        {
            form_data.fss_ajax_fields.push( "ajax" );
            form_data.fss_ajax_values.push( "true" );
        }
        else
        {
            form_data.ajax  = "true";
        }
            
        
        if( uri.path != window.location.pathname )
        {
            if( !this.isIE( ) && window.history.pushState !== "undefined" )
                window.history.pushState( { page: uri.path }, document.title, uri.path );
        }
        
        var request         = new window.fss_pageLoader_ajax( url );
        var pointer         = this;
        var callback_finish = function( xmlHttpObject ){ pointer.callbackonfinish( xmlHttpObject, uri ); };
        
        request.ajaxRequest( form_data, callback_finish, null, null, method );  
        
        return false;
    }
    else
    {
        return true;
    }
}

fss_pageLoader.prototype.callbackonfinish = function( xmlHttpObject, uri )
{
    if( xmlHttpObject.responseText.startsWith( "301" ) )
    {
        var redirectUrl = xmlHttpObject.responseText.substr( 3 );
        this.loadPage( redirectUrl, true );
    }
    else
    {
        if( _gaq )
        {
            _gaq.push( ['_setDomainName', uri.domain ] );
            _gaq.push( ['_trackPageview', uri.path ] );
        }
        
        var newElement               = document.createElement( "div" );
        newElement.innerHTML         = xmlHttpObject.responseText;

        var scriptTags               = newElement.getElementsByTagName( 'script' );
        
        var jsScriptArr              = new Array();
        var jsScriptSrcArr           = new Array();
        
        for( var i = 0; i < scriptTags.length; i++ )
        {
            if( scriptTags[i].innerHTML.length > 0 )
            {
                jsScriptArr.push( scriptTags[i].innerHTML );
            }
            else if ( scriptTags[i].src.length > 0  )
            {
                jsScriptSrcArr.push( scriptTags[i].src );
            }
        }
        
        for( var i = 0; i < scriptTags.length; i++ )
        {
            scriptTags[i].parentNode.removeChild( scriptTags[i] );
        }
        
        if( this.isIE( 7 ) || this.isIE( 8 ) )
        {
        
            var sourceElementHTML = xmlHttpObject.responseText;
                sourceElementHTML = sourceElementHTML.replace( /<script\b[^>]*>(.*?)<\/script>/gi, "" );
                sourceElementHTML = sourceElementHTML.replace( /<response>/i, "" ).replace( /<\/response>/i, "" );
                sourceElementHTML = sourceElementHTML.replace( /<output>/i, "" ).replace( /<\/output>/i, "" );
                
            this.removeChildrenRecursive( newElement );
            this.removeChildrenRecursive( this.targetElement );  
                     
            this.nodeCloneRecusive( sourceElementHTML, this.targetElement );
            
            //alert(this.debugText);
            
            for( var x = 0; x < jsScriptSrcArr.length; x++ )
            {
                var script_e           = document.createElement( "script" );
                    script_e.type      = "text/javascript";
                    script_e.src       = jsScriptSrcArr[x];
                
                this.targetElement.appendChild( script_e );
            }
            
            for( var x = 0; x < jsScriptArr.length; x++ )
            {
                if( jsScriptArr[x].length > 0 )
                    eval( jsScriptArr[x] );
            }
        }
        else
        {
            var outputArr                = newElement.getElementsByTagName( 'output' );
            this.targetElement.innerHTML = outputArr[0].innerHTML;
            outputArr[0].innerHTML       = "";
            
            for( var x = 0; x < jsScriptSrcArr.length; x++ )
            {
                var script_e           = document.createElement( "script" );
                    script_e.type      = "text/javascript";
                    script_e.src       = jsScriptSrcArr[x];
                
                this.targetElement.appendChild( script_e );
            }
            
            for( var x = 0; x < jsScriptArr.length; x++ )
            {
                eval( jsScriptArr[x] );
            }
        }
        
        this.init_adjustLinks( );
            
        newElement.innerHTML = "";
        newElement           = null;
    }
};

fss_pageLoader.prototype.showProgressScreen = function( )
{
    if( this.targetElement.children.length > 0 )
    {
        this.targetElement.firstChild.style.position = "relative";
        
        var progressElement = document.createElement( "div" );
            progressElement.style.position = "absolute";
            progressElement.style.top = "0";
            progressElement.style.left = "0";
            progressElement.style.width = this.targetElement.firstChild.offsetWidth + "px";
            progressElement.style.height = this.targetElement.firstChild.offsetHeight + "px";
            progressElement.style.backgroundColor = "#FFFFC0";
            progressElement.style.zIndex = "1000";
            
            this.setOpacity( progressElement, 30 );
            
        this.targetElement.firstChild.appendChild( progressElement );
    }
}

fss_pageLoader.prototype.isJavascriptUsed = function ( srcUrl )
{
    var output = false;
    
    for( var x = 0; x < this.indexedJsFiles.length; x++ )
    {
        if( this.indexedJsFiles[x] == srcUrl )
        {
            output = true;
            break;
        }
    }
    
    return output;
}

window.fss_pageLoader.prototype.get_form_data = function  ( form ) 
{
    var element_types = [ "TEXT", "TEXTAREA", "PASSWORD", "BUTTON", "RESET", "SUBMIT", "FILE", "IMAGE", "HIDDEN", "CHECKBOX", "RADIO", "SELECT" ]; 

    var fields_arr    = [];
    var values_arr    = [];
    
    function in_array( needle,  haystack )
    {
        var output = false;
        
        for( var x = 0; x < haystack.length; x++ )
        {
            if( haystack[ x ] == needle )
            {
                output = true;
                break;
            }
        }
        
        return output;
    }

    for ( var i = 0; i < form.elements.length; i++ ) 
    {

        var element      = form.elements[i];
        
        if ( in_array ( element.tagName.toUpperCase( ), element_types ) ) 
        {    
            fields_arr.push( element.name );       
            values_arr.push( element.value );
        }
        else if( element.tagName.toUpperCase( ) == "INPUT" && in_array( element.type.toUpperCase( ), element_types ) )
        {               
            if( ( element.type.toUpperCase( ) == "CHECKBOX" || element.type.toUpperCase( ) == "RADIO" ) )
            {
                if( element.checked )
                {
                    fields_arr.push( element.name );       
                    values_arr.push( element.value );
                }
            }
            else
            {
                fields_arr.push( element.name );       
                values_arr.push( element.value );
            }
        }
        
        var query_data    = { fss_ajax_fields: fields_arr, fss_ajax_values: values_arr };

    }

    return query_data;
}

fss_pageLoader.prototype.nodeCloneRecusive = function ( sourceElementHTML, targetNode )
{
    var div = document.createElement( "div" );
    targetNode.appendChild( div );
    
    div.innerHTML = sourceElementHTML.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}

fss_pageLoader.prototype.removeChildrenRecursive = function ( parent )
{
    var toRemove = new Array();
    
    for( var x = 0; x < parent.children.length; x++ )
    {
        toRemove.push( parent.children[x] );
    }
    
    for( var x = 0; x < toRemove.length; x++ )
    {
        parent.removeChild( toRemove[x]  );
    }
}

fss_pageLoader.prototype.parseUri = function ( sourceUri )
{
    var uriPartNames = ["source","protocol","authority","domain","port","path","directoryPath","fileName","query","anchor"];
    var uriParts = new RegExp("^(?:([^:/?#.]+):)?(?://)?(([^:/?#]*)(?::(\\d*))?)?((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[\\?#]|$)))*/?)?([^?#/]*))?(?:\\?([^#]*))?(?:#(.*))?").exec( sourceUri );
    var uri = {};
    
    for(var i = 0; i < 10; i++){
        uri[uriPartNames[i]] = ( uriParts[ i ] ? uriParts[ i ] : "");
    }

    if(uri.directoryPath.length > 0){
        uri.directoryPath = uri.directoryPath.replace(/\/?$/, "/");
    }
    
    return uri;
}

window.fss_pageLoader.prototype.isIE = function( verison, isMax )
{
    var agentName = navigator.appVersion.toLowerCase( ); 
    
    if( verison )
    {
        if( isMax )
        {
            var output = false;
            
            for ( var x = 5; x <= verison; x++ )
            {
                if( agentName.indexOf("msie " + x + ".") != -1 )
                {
                    output = true;
                    break;
                }
            }
            
            return output;
        }
        else
        {
            return agentName.indexOf("msie " + verison + ".") != -1;
        }
    }
    else
        return agentName.indexOf("msie") != -1;
}

fss_pageLoader.prototype.setOpacity = function( element, opacity ) 
{
    if ( element.style ) 
    {
        element.style.top      = 0;
        element.style.zIndex   = opacity;

        if ( element.style.MozOpacity != null )   
            element.style.MozOpacity = ( opacity / 100 );            /* Mozilla */   
            
        else if ( element.style.KhtmlOpacity != null ) 
            element.style.KhtmlOpacity = ( opacity / 100 );          /* Khtml */ 
        
        else if ( element.style.opacity != null ) 
            element.style.opacity = ( opacity / 100 );               /* CSS3 */ 
                                                                       
        else if ( element.style.filter != null )
        {   
            if( this.IE_alphaSafe )
            {
                element.style.display = opacity <= 50 ? "none" : "block";
            }
            else
            {  
                 if(opacity == 0)
                    opacity = 1;
                      
                element.style.filter = "alpha(opacity=" + opacity + ")";
            }
        }           
    }
}

window.fss_pageLoader.prototype.stopEvent = function ( event ) 
{
    event.preventDefault();
    event.stopPropagation();
    event.stopped = true;
    
    return false;
}
  
window.fss_pageLoader.prototype.init_adjustLinks = function ( )
{
    var links   = document.links; 
    var pointer = this;
    
    for ( var x = 0; x < links.length; x++ )
    {
        var link = links[x];
        
        if( link.href.length > 0)
        {
            var firstChar = link.href.substr( 0, 1 );
            
            if( !link.href.startsWith( "#" ) && !link.href.endsWith( "#" ) && !link.href.startsWith( "javascript" ) && link.target != "_blank" )
            {
                if( !link.onclick_original_isset )
                {
                    link.onclick_original_isset = true;
                    
                    if( !this.isIE( 8, true ) )
                        link.addEventListener( "click", function( ev ){ return pointer.loadPage( this.href, false, false, ev ); }, false );
                    else
                        link.onclick = function( ev ){ return pointer.loadPage( this.href ); }
                }
            }
        }
    }   
    
    var form_elements = document.forms;
    
    for ( var x = 0; x < form_elements.length; x++ ) 
    {
        var form_element = form_elements[x];
        
        if( !this.isIE( 8, true ) )
        {
            form_element.addEventListener( "submit", function( ev ){ pointer.postForm( this, ev ); }, false );
        }
        else
        {
            form_element.onsubmit = function( ){ 
                
                event.returnValue = false; 
                pointer.postForm( this ); 
                return false; 
            };
        }
            
    }
}

function init_urlMonitor( targetId )
{
    var pageLoader = new fss_pageLoader( targetId );
    window.onpopstate = function( ev ) { pageLoader.loadPage( ev.state.page, false, true ); };

    return pageLoader;
}


// ============================ Ajax Class ============================ //

// Copyright Paul Tesar 2008 
// paultesar@gmail.com

// ============== Main function / Fonction Principal / Hlavni funkce ============== // 

window.fss_pageLoader_ajax = function( serverScript )
{
    this.xmlHttp;
    this.serverScript = serverScript;
    this.isWorking    = this.xmlHttpObjectInit();  
}

window.fss_pageLoader_ajax.prototype.check = function (xmlHttpObj)
{     
     var output      = xmlHttpObj.responseText; 
     
     if(output == "OK")
     {
        this.isWorking    = true;
     }
     else
     {
        this.isWorking    = false;
     }
}
 
window.fss_pageLoader_ajax.prototype.ajaxRequest = function ( postVarsArr, callbackOnFinish, callbackOnProgress, callbackOnError, method )
{

   var pointer      = this;
   var xmlHttpObj   = this.xmlHttp;

   if(this.isWorking)
   {       
       if((xmlHttpObj.readyState > 0))
       {
           setTimeout( function(){ pointer.ajaxRequest(postVarsArr,callbackOnFinish,callbackOnProgress,callbackOnError, method );  }, 100 );
       }
       else
       {
           if( !method )
               method = "GET"; 
               
           method = method.toUpperCase( );

           var params_strings    = "jsSid=" + Math.random();

           if( "fss_ajax_fields" in postVarsArr && "fss_ajax_values" in postVarsArr )
           {
               for( var x = 0; x < postVarsArr.fss_ajax_fields.length; x++ )
               {
                  params_strings += "&" + postVarsArr.fss_ajax_fields[x] + "=" + encodeURIComponent( postVarsArr.fss_ajax_values[x] );
               }
           }
           else
           {
               for( var postVariable in postVarsArr )
               {
                  params_strings += "&" + postVariable + "=" + encodeURIComponent( postVarsArr[postVariable] );
               }
           }
           
           if( method == "POST" )
           {
               xmlHttpObj.onreadystatechange = function(){ pointer.readyStateChangeHandler( xmlHttpObj,callbackOnFinish,callbackOnProgress,callbackOnError ); };
               xmlHttpObj.open( method, this.serverScript, true );
           
               xmlHttpObj.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
               xmlHttpObj.setRequestHeader( "Content-length", params_strings.length );
               xmlHttpObj.setRequestHeader( "Connection", "close" );
           
               xmlHttpObj.send( params_strings );
           }
           else
           {               
               xmlHttpObj.onreadystatechange = function(){ pointer.readyStateChangeHandler( xmlHttpObj,callbackOnFinish,callbackOnProgress,callbackOnError ); };
               xmlHttpObj.open( method, ( this.serverScript + "?" + params_strings ), true );
               
               xmlHttpObj.send( null );
           }
       }
   }
   else if(this.isFunction(callbackOnError))
   {
       callbackOnError(xmlHttpObj);
   }
   
}

window.fss_pageLoader_ajax.prototype.readyStateChangeHandler = function(xmlHttpObj,callbackOnFinish,callbackOnProgress,callbackOnError)
{ 
    var readyState = xmlHttpObj.readyState;
        
    if ( (readyState == 4) && (this.isFunction(callbackOnFinish)) )
    { 
        callbackOnFinish(xmlHttpObj);
        this.xmlHttp.abort();
    }
    else if( (readyState == 3) && (this.isFunction(callbackOnProgress)) )
    {
        callbackOnProgress(xmlHttpObj);
    }
    else if( readyState == 2 )
    {
        try
        {
            var httpStatus = xmlHttpObj.status;

            if(httpStatus != 200  && this.isFunction(callbackOnError))
            {
                callbackOnError(xmlHttpObj);
                this.xmlHttp.abort();
            }
        }
        catch( e )
        {

        }
    }    
}

window.fss_pageLoader_ajax.prototype.xmlHttpObjectInit = function()
{
    var object = null;
    
    try         // Firefox, Opera 8.0+, Safari   
    {
        object = new XMLHttpRequest();    
    }
    catch (e)   // Internet Explorer 
    {
        try
        {
            object = new ActiveXObject("Msxml2.XMLHTTP");    
        }
        catch(e)
        {
            object = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    
    if(object)
    {
        this.xmlHttp = object; 
        return true;
    }
    else
    {
        return false;
    }  
}

window.fss_pageLoader_ajax.prototype.isFunction = function(obj)
{      
     if(typeof(obj) == 'function')
     {
        return true;
     }
     else
     {
        return false;
     }
}

window.fss_pageLoader_ajax.prototype.processAjaxOutput = function( xmlHttpObj, attributes )
{
    
    var output      = new Array();

    if(!attributes)
    {
        attributes  = ["id","value"]

    }

    if(xmlHttpObj.responseXML)
    {                                                      
        var res  = xmlHttpObj.responseXML.getElementsByTagName('results');
        var res1 = res  ? res[0] : null;
        var rows = res1 ? res1.childNodes : null;
        
        if(rows)
        {
            var count = 0;
            
            for (var i = 0; i < rows.length; i++)
            {
                var row = rows[i];
                
                if (row)
                {    
                    var dataArr = new Array();

                    for(x in attributes)
                    {
                       
                       var attribute          = attributes[x];
                       var val                = row.getAttribute(attribute);
                           dataArr[attribute] = val
                    }
                    
                    output.push(dataArr);
                    count++; 
                }
            }
        }
    }
    
    return output;
}
