/* common.js */
/*
Common javascript.

This javascript should require no dependency to other javascript library
except:
- Prototype
- LocationAjaxService (for store pages only)
- DWR Engine (for store pages only)
- DWR Util (for store pages only)
*/

// create a name space for TGG public website code
var tgg = {};
tgg.debug = true;

// set document domain
try{
/*
  var domainUrl = window.location.href.match(/(\w+\.)+com\.au(?=\/)/)[0];
  domainUrl = domainUrl.replace(/^www\./,'');
  
  if((document.domain!=domainUrl) && (document.domain.indeOf(domainUrl)>0)){
    document.domain = domainUrl;
  }
*/
  if (true) {
    var domain = 'thegoodguys.com.au';
    if (document.domain != domain) {
      document.domain = domain;
    }
  } 
}catch(err){/* Who cares? */}

if(tgg && tgg.debug){
  try{
    console.debug('Document domain = %s', document.domain);
    /*
    console.debug('Listing all jQuery items');
    
    //console.dir(jQuery);
    for(var s in jQuery){
      console.debug('--> %s', s);
    }
    */
  }catch(err){}
}

/* jQuery no conflict, revert $ to prototype  if necessary*/
if($!=null && $===jQuery){
  jQuery=jQuery.noConflict();
}

/* jQuery extension(s) */
/* ------------------- */
/* provide outerHTML feature for an element */
(function($) {
  $.fn.outerHTML = function(s) {
    return (s)?
           this.before(s).remove():
           $('<p>').append(this.eq(0).clone()).html();
  };
})(jQuery);
/* ------------------- */


// Non-IE indication of document.readyState
// refer to http://msdn.microsoft.com/en-us/library/ms534359(VS.85).aspx
// for possible list of value
if(typeof(document.readyState)=='undefined'){
  document.readyState = 'loading';

  // automatically mark the readyState attibute to 'complete' when DOM is loaded
  Event.observe(document, 'dom:loaded', function(){document.readyState='complete';});
}

/* The following codes will override some DWR properties */
try{
	dwr.engine.__defaultErrorHandler = function(message, ex){
		dwr.engine._debug("Error: " + ex.name + ", " + ex.message, true);
		
		if (message == null || message == "") alert("A server error has occured. More information may be available in the console.");
		// Ignore NS_ERROR_NOT_AVAILABLE if Mozilla is being narky
		else if (message.indexOf("0x80040111") != -1) dwr.engine._debug(message);
		//else alert(message);
		else dwr.engine._debug(message);
	};
	dwr.engine.setErrorHandler(dwr.engine.__defaultErrorHandler);
}catch(err){}

/* Cookie related stuffs */
function getCookie( name ) {
	var start = document.cookie.indexOf( name + "=" );
	var len = start + name.length + 1;
	if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
		return null;
	}
	if ( start == -1 ) return null;
	var end = document.cookie.indexOf( ';', len );
	if ( end == -1 ) end = document.cookie.length;
	return unescape( document.cookie.substring( len, end ) );
}

function setCookie( name, value, expires, path, domain, secure ) {
	var today = new Date();
	today.setTime( today.getTime() );
	if ( expires ) {
		expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );
	document.cookie = name+'='+escape( value ) +
		( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString()
		( ( path ) ? ';path=' + path : '' ) +
		( ( domain ) ? ';domain=' + domain : '' ) +
		( ( secure ) ? ';secure' : '' );
}

function deleteCookie( name, path, domain ) {
	if ( getCookie( name ) ) document.cookie = name + '=' +
			( ( path ) ? ';path=' + path : '') +
			( ( domain ) ? ';domain=' + domain : '' ) +
			';expires=Thu, 01-Jan-1970 00:00:01 GMT';
}

/* Event handler attaching stuffs */
function addEvent( obj, type, fn ) {
	if (obj.addEventListener) {
		obj.addEventListener( type, fn, false );
		EventCache.add(obj, type, fn);
	}
	else if (obj.attachEvent) {
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn] );
		EventCache.add(obj, type, fn);
	}
	else {
		obj["on"+type] = obj["e"+type+fn];
	}
}

var EventCache = function(){
	var listEvents = [];
	return {
		listEvents : listEvents,
		add : function(node, sEventName, fHandler){
			listEvents.push(arguments);
		},
		flush : function(){
			var i, item;
			for(i = listEvents.length - 1; i >= 0; i = i - 1){
				item = listEvents[i];
				if(item[0].removeEventListener){
					item[0].removeEventListener(item[1], item[2], item[3]);
				};
				if(item[1].substring(0, 2) != "on"){
					item[1] = "on" + item[1];
				};
				if(item[0].detachEvent){
					item[0].detachEvent(item[1], item[2]);
				};
				item[0][item[1]] = null;
			};
		}
	};
}();
addEvent(window,'unload',EventCache.flush);

/* Get the value of specified request parameter from current location's query string
 * parameter queryString = 
*/
function getRequestParameter ( parameterName, queryString ) {
   // get the query string from current's location if not supplied
   if(!(queryString!=null && typeof(queryString)!='undefined')){
      queryString = window.top.location.search.substring(1);
   }

   // Add "=" to the parameter name (i.e. parameterName=value)
   var parameterName = parameterName + "=";
   if ( queryString.length > 0 ) {
      // Find the beginning of the string
      begin = queryString.indexOf ( parameterName );
      // If the parameter name is not found, skip it, otherwise return the value
      if ( begin != -1 ) {
         // Add the length (integer) to the beginning
         begin += parameterName.length;
         // Multiple parameters are separated by the "&" sign
         end = queryString.indexOf ( "&" , begin );
      if ( end == -1 ) {
         end = queryString.length
      }
      // Return the string
      return unescape ( queryString.substring ( begin, end ) );
   }
   // Return "null" if no parameter has been found
   return "null";
   }
}

/* Read current storeId from the url and return it. */
var getCurrentStoreId = function(){
	var storeIdInQueryStringRegex = /[?&]storeId=\d+([&#]|$)/i;
	var storeIdInUrlRegex         = /\/store\d+\//i;
	var storeIdRegex              = /\d+/;
	var urlString = window.top.location.href;
	var matchedString = urlString.match(storeIdInQueryStringRegex);
	if(matchedString==null){
		matchedString = urlString.match(storeIdInUrlRegex);
	}
	var storeId = null;
	if(matchedString){
		matchedString = matchedString.toString().match(storeIdRegex);
		try{
			if(matchedString) storeId = parseInt(matchedString.toString());
		} catch(err){}
	}
	
	return storeId;
};

/* The following code is based on StackOverFlow's answer at this URL:
 * http://stackoverflow.com/questions/21294/how-do-you-dynamically-load-a-javascript-file-think-cs-include/242607#242607
 * It requires Prototype to be already included.
 *
 * This code howeever has been modified so that it could expand the url pattern '~j/...'
 * and use straight forward if the page is not fully loaded.
 */
var Script = {
  _loadedScripts: [],
  include: function(script){
    // expand script url if necessary
    if(typeof(script)=='string'){
      var javascriptBaseUrl   = '/tggweb/public/javascript'
      var javascriptBaseRegex = /^~j(?=\/|$)/;

      if(script.match(javascriptBaseRegex)!=null){
        script = script.replace(javascriptBaseRegex, javascriptBaseUrl);
      }
    }

    // include script only once
    if (this._loadedScripts.include(script)){
      return false;
    }

    // use script element insertion if Gecko browser is used
    // and the page is still loading
    if(false /* disable since it does not behave consistently */ && document.readyState=='loading' && Prototype.Browser.Gecko){
      $$("head").first().insert(
        Object.extend(
          new Element("script", {type: "text/javascript", src: script})));
    }else{
      // request file synchronous
      var code = new Ajax.Request(script, {
        asynchronous: false, method: "GET",
        evalJS: false, evalJSON: false
      }).transport.responseText;
      
      // eval code on global level
      try{
        if (Prototype.Browser.IE) {
          window.execScript(code);
        } else if (Prototype.Browser.WebKit){
          $$("head").first().insert(Object.extend(
            new Element("script", {type: "text/javascript"}), {text: code}
          ));
        } else {
          window.eval(code);
        }
      }catch(err){}
    }

    // remember included script
    this._loadedScripts.push(script);

    return true;
  }
};

/* jQuery stuffs */
/* ------------- */
// extend getScript to support cache and non-duplicate
(function() {
    var originalGetScript = jQuery.getScript;

    // expand javascript script url starting with '~j/'
    var expandScriptUrl = function(url) {
        if (typeof (url) == 'string') {
            // expand script url if necessary
            var javascriptBaseUrl = '/tggweb/public/javascript'
            var javascriptBaseRegex = /^~j(?=\/|$)/;

            if (url.match(javascriptBaseRegex) != null) {
                url = url.replace(javascriptBaseRegex, javascriptBaseUrl);
            }
        }

        return url;
    };
    
    // closure function - getScript and cache
    var getScriptCache = function(url, callback) {
        jQuery.ajax({
            type: "GET",
            url: url,
            success: callback,
            dataType: "text",
            cache: true,
            async: (async?true:false)
        });
    };

    // closure function - getScript with no duplicate load
    var _loadedScripts = Script['_loadedScripts'];
    
    var getScriptOnce = function(url, callback, async) {
        var script = url;
        var result = true;

        if (typeof (script) != 'string') {
            result = false;
        } else {
            // include script only once
            if (_loadedScripts.include(script)) {
                result = false;
            }
            
            // use jquery stuffs to load the files
            result = getScriptCache(script, callback, async)
            
            // remember included script
            _loadedScripts.push(script);
        }

        return result;
    };

    // redefine getScript, so that it will be some how
    // an alias for Script.include (experimental) TODO: reconsolidate this code later.
    jQuery.getScript = function(url, callback, cache, async) {
        var result = null;
        async = async? true:false;
        if (typeof (url) == 'string') url = expandScriptUrl(url);
        if (typeof (cache) == 'undefined' && typeof (callback) == 'string') cache = callback;

        if (cache) {
            if (cache == 'once') {
                result = getScriptOnce(url, callback, async);
            } else {
                result = getScriptCache(url, callback, async);
            }
        } else {
            result = originalGetScript(url, callback);
        }
        return result;
    };
    
    // make another alias for getScript with  cache, executed only once, and asynhronously
    
    // similar to getScript, but import script only if it is not yet called, and cache it. It will be executed synchronously
    jQuery.importScript = function(url, callback){
      //jQuery.getScript(url, callback, 'once', true);
      
      url = expandScriptUrl(url);
      
      // include script only once
      if (_loadedScripts.include(url)) {
          result = false;
      }else{
        jQuery.ajax({
          url: url,
          type: 'GET',
          dataType: "text",
          cache: true,
          async: false,
          success: function(responseText, status){
            var code = responseText;
            var dummyDom = document.createElement('P');
            try{
              if (window.execScript) { // IE
                window.execScript(code);
              } else if (!dummyDom.sourceIndex && dummyDom.contains){ // WebKit
                $$("head").first().insert(Object.extend(
                  new Element("script", {type: "text/javascript"}), {text: code}
                ));
              } else {
                window.eval(code);
              }
            }catch(err){}
            
            if(callback && typeof(callback)=='function'){
              callback(res, status);
            }
          }
        });
        
        // remember included script
        _loadedScripts.push(url);
      }
    };
    
})();

/* Handle redirection for pages that does not have storeID */
(function($){
  $.importScript('~j/jquery/jquery.cookie.js');
  
  // get current page url path
  var pathname = window.location.pathname;
  
  var includeRegexes = [
    /^\/portal\/page\/portal\/tggwebportal(\/.*)?$/
  ];
  
  var excludeRegexes = [
    /^\/portal\/page\/portal\/tggwebportal\/?$/,
    /^\/portal\/page\/portal\/tggwebportal\/corporate\/storelocator(\/.*)?$/,
    /^\/portal\/page\/portal\/tggwebportal\/corporate\/nationalstore(\/.*)?$/
  ];
  
  // read storeId from url, if it is available
  var storeId = getCurrentStoreId();
  
  // redirection flag
  var isNeedRedirect = false;
  
  if(storeId!=null){
    // check cookie if we need to redirect to any return url
    var tggReturnUrl = $.cookie('tggReturnUrl') || false;
    
    // quickly delete the return url cookie
    if($.cookie('tggReturnUrl')){
      $.cookie('tggReturnUrl', false, {path:'/'});
      $.cookie('tggReturnUrl', null, {path:'/'});
    }
    
    // redirect to return url + storeId
    if(typeof(tggReturnUrl)=='string'){
      var newUrl = tggReturnUrl;
      if(tggReturnUrl.indexOf('?')>=0){
        newUrl += '&';
      }else{
        newUrl += '?';
      }
      newUrl += 'storeId=' + storeId;
      window.location.href = newUrl;
    }
  }else{
    // check with inclusive regexes
    for(var i=0; i<includeRegexes.length; i++){
      var regex = includeRegexes[i];
      if(pathname .match(regex)){
        isNeedRedirect = true;
        break;
      }
    }
    
    // check with exclusive regexes
    if(isNeedRedirect){
      for(var i=0; i<excludeRegexes.length; i++){
        var regex = excludeRegexes[i];
        if(pathname .match(regex)){
          isNeedRedirect = false;
          break;
        }
      }
    }
  }
  
  // is redirection is required
  if(isNeedRedirect){
    
    // acquire storeId from cookie if any
    storeId = $.cookie('tggStoreHomeStoreId');
    
    // redirect to the page with store Id
    if(storeId){
      url = window.location.href;
      if((window.location.search || '').length==0){
        url += '?storeId=' + storeId;
      }else{
        url += '&storeId='+storeId;
      }
      
      // REDIRECTION
      window.location.href = url;
    } else {
      // if no storeId stored in cookie, redirect to storelocator
      // but before that, store in cookie of which product to go upon visiting a new store home page
      $.cookie('tggReturnUrl', window.location.href, {path:'/'});
      
      // REDIRECTION
      window.location.href = '/portal/page/portal/tggwebportal';
    }
  }
  
})(jQuery);

/* Now include all required scripts */
Script.include('~j/currentStore.js'); /* current store */
Script.include('~j/links.js');        /* handle all link in web pages */

// This script should fix product image weirdness in IE8, and only will be executed in IE8
(function($){
  return; // temporarily disable this hack
  
  var dummyDOM = document.createElement('P');
  if(dummyDOM.applyElement && dummyDOM.hasAttribute){
    $(function(){
      $('div.productImageContainer').each(function(i){
        var imageContained = $('a>img', this);
        imageContained.css('width',  imageContained.width());
        imageContained.css('height', imageContained.height());
      });
    });
  }
  delete(dummyDOM);
})(jQuery);

/* Handle the alignment for badges to meet business users' alignment*/
(function($){
  
  // column selectors
  var columnSelector = 'body>div>table:eq(2)>tbody>tr>td:eq(index)';
  var leftColumnSelector   = columnSelector.replace('index', '0');
  var middleColumnSelector = columnSelector.replace('index', '1');
  var rightColumnSelector  = columnSelector.replace('index', '2');
  
  // reset badges image size to maximum width of 159px
  var maxBadgeWidth = 159;
  var badgesImageSubSelector = '>table>tbody>tr>td table>tbody>tr>td img[src*="/pls/"]';
  var badgesImageSelector = 
    leftColumnSelector+ badgesImageSubSelector + ',' +
    rightColumnSelector+ badgesImageSubSelector;
  
  /* resize badge */
  var resizeBadgeImage = function(){
    var currentWidth = $(this).width();
    if(currentWidth==0) return;
    if(currentWidth>maxBadgeWidth){
      //if(window.execScript) alert('DEBUG MESSAGE (Please ignore!): resizing');
      $(this).css('width', maxBadgeWidth);
    }
  };
  
  // add trigger to resize badges size
  $(function(){
    // temporarily disable badge resizing
    return;
    
    if(!window.execScript){
      $(badgesImageSelector).load(resizeBadgeImage);
    }else{
      var badges = $.makeArray($(badgesImageSelector));
      var resizeBadgeImageIntervalFunction = function(){
        var processedBadgesCount = 0;
        
        for(var i=0; i<badges.length; i++){
          var badge = badges[i];
          
          if(badge!=null){
            
            var currentWidth = $(badge).width();
            if(currentWidth>0){
              // flag as null, so the timer will be removed later
              badges[i]=null;
              
              // resize now
              $(badge).each(resizeBadgeImage);
            }
          }else{
            processedBadgesCount++;
          }
          
        } // end for
        
        // remove interval timer if every badges are already processed
        if(processedBadgesCount>=badges.length){
          clearInterval(badgeResizeInterval);
          //alert("DEBUG MESSAGE: All badge images are now processed.");
        }
      }; // end function
      
      var badgeResizeInterval = setInterval(resizeBadgeImageIntervalFunction,1000);
    }
  });
  
  $(function(){
    
    // reset the padding-left and padding-right for immediate middle column region,
    // and reset the padding-left and padding-right for RHS column,
    $(middleColumnSelector + '>table>tbody>tr>td' + ',' +
        leftColumnSelector + ' table>tbody>tr>td' + ',' +
        rightColumnSelector+ ' table>tbody>tr>td')
      .css('padding-left', 0)
      .css('padding-right',0);
    
    var badgesAlignRegex = /(\?(&*|.*&))(badges_align=(center|left|right|))(?=(&|$))/i;
    var alignmentValueIndex=4;
    var badgesParamIndex=3;
    
    $('tr[align="center"]>td>a[href*="badges_align"]').each(function(i){
      // read the alignment value from the href
      var alignValue = 'center';
      var href = $(this).attr('href');
      var badges_align_param = href.match(badgesAlignRegex);
      if(badges_align_param!=null){
        var readAlignedValue = (badges_align_param[alignmentValueIndex] || 'center').toLowerCase();
        if((['center', 'left', 'right']).indexOf(readAlignedValue)>=0){
          alignValue = readAlignedValue;
        }
      }
      
      // reset badges href
      var newHref = href
             .replace(badges_align_param[badgesParamIndex], '')
             .replace(/\?&+/,'?')
             .replace(/\?$/,'')
             .replace(/&&+/,'&')
             .replace(/&+$/,'');
      $(this).attr('href', newHref);
      
      // align image to specified value
      try{
        $(this)
          .parent('td')
            .parent('tr')
              .removeAttr('align');
        $(this)
          .css({
            'display': 'block',
            //'width': $(this).parent().width(),
            //'height': $(this).children('img').height()+'px',
            'text-align': alignValue
          })
          .next('br').hide();
        ;
      }catch(err){}
      
    });
  });
})(jQuery);
