var syU  = (function ($, scope) {
  window.dataLayer = window.dataLayer || [];

  function getSiteDetails(cb) {
    var host = window.location.host.split('.');
    whenAvailable("_", function() {
      var env;
      var site = _.find(host, function(val) {
        return val !== 'www' && val !== 'com' && val !== 'demo'
      })

      if (/sites/.test(site)) {
        //pod?
        env = site.replace("sites", "partner");
        site = 'kittydemo';
      } else if (/release/.test(site)) {
        var split = site.split('-');
        env = 'manage-release';
        site = split[0];
      } else {
        env = 'prod';
      }

      cb({
        site: site,
        env: env
      })
    });
  }

  function whenAvailable(name, callback) {
    var interval = 100; // ms
    var attempts = 0;
    var maxAttempts = 50;
    window.setTimeout(function() {
        if (window[name]) {
            callback(name);
        } else {
            attempts < maxAttempts && window.setTimeout(arguments.callee, interval);
            attempts++;
        }
    }, interval);
  }

  function pushDataLayerEvent(name) {
    dataLayer.push({
      event: name+"Ready"
    });
  }

  whenAvailable("SymphonyAPI", function(name) {
    pushDataLayerEvent(name);
    SymphonyAPI(["page", "cart", "product",  function(p, c, p2) {  
      p && dataLayer.push({ "event": p.type });
      window.cart = c;
      window.product = p2;
    }])
  });
  
  /order\//.test(window.location.href) && whenAvailable("order", pushDataLayerEvent);
  whenAvailable("angular", pushDataLayerEvent);
  whenAvailable("$", pushDataLayerEvent);

  var tid = setInterval( function () {
    if ( document.readyState !== 'complete' ) return;
    clearInterval( tid );       
    dataLayer.push({ "event": "pageLoaded" });
  }, 100 );


  (function ($, window) {
     
    var intervals = {};
    var removeListener = function(selector) {
     
      if (intervals[selector]) {
        
        window.clearInterval(intervals[selector]);
        intervals[selector] = null;
      }
    };
    var found = 'waitUntilExists.found';
     
    /**
     * @function
     * @property {object} jQuery plugin which runs handler function once specified
     *           element is inserted into the DOM
     * @param {function|string} handler 
     *            A function to execute at the time when the element is inserted or 
     *            string "remove" to remove the listener from the given selector
     * @param {bool} shouldRunHandlerOnce 
     *            Optional: if true, handler is unbound after its first invocation
     * @example jQuery(selector).waitUntilExists(function);
     */
     
    $.fn.waitUntilExists = function(handler, shouldRunHandlerOnce, isChild) {
     
      var selector = this.selector;
      var $this = $(selector);
      var $elements = $this.not(function() { return $(this).data(found); });
      
      if (handler === 'remove') {
        
        // Hijack and remove interval immediately if the code requests
        removeListener(selector);
      }
      else {
     
        // Run the handler on all found elements and mark as found
        $elements.each(handler).data(found, true);
        
        if (shouldRunHandlerOnce && $this.length) {
          
          // Element was found, implying the handler already ran for all 
          // matched elements
          removeListener(selector);
        }
        else if (!isChild) {
          
          // If this is a recurring search or if the target has not yet been 
          // found, create an interval to continue searching for the target
          intervals[selector] = window.setInterval(function () {
            
            $this.waitUntilExists(handler, shouldRunHandlerOnce, true);
          }, 500);
        }
      }
      
      return $this;
    };
     
    }(jQuery, window));



  function checkReadyState(callback, attempts, condition, timeout) {
       //private function for checking for ready state
       
    (function checkCondition() {
      // console.log(condition());
      if (condition()) {
        callback(null, true);
      } else if (attempts > 0) {
          --attempts;
        setTimeout(checkCondition, (timeout || 500));
      } else if (attempts <= 0 ) {
        callback(true, null);
      }
    })();
  }

  return {
    getSiteDetails: getSiteDetails,
    whenAvailable: whenAvailable,
    checkReadyState: checkReadyState,

    getCookie: function(name) {
      var nameEQ = name + "=";
      var ca = document.cookie.split(';');
      for(var i=0;i < ca.length;i++) {
          var c = ca[i];
          while (c.charAt(0)==' ') c = c.substring(1,c.length);
          if (c.indexOf(nameEQ) == 0) {
            return c.substring(nameEQ.length,c.length);
          } 
      }
    },

    dropCookie: function(name,days,value) {
      if (days) {
          var date = new Date();
          date.setTime(date.getTime()+(days*24*60*60*1000));
          var expires = "; expires="+date.toGMTString();
      }
      else var expires = "";
      document.cookie = name+"="+value+expires+"; path=/";
    },

    getUrlParameter: function (url, sParam) {
        var sPageURL = url.split('?')[1];
        if (sPageURL) {
          var sURLVariables = sPageURL.split('&');
          for (var i = 0; i < sURLVariables.length; i++) 
          {
              var sParameterName = sURLVariables[i].split('=');
              if (sParameterName[0] == sParam) 
              {
                  return sParameterName[1];
              }
          }
        }
    },

    safeApply: function ($scope, applyFn) {
      if(!$scope.$$phase) $scope.$apply(applyFn);
      else applyFn();
    },

    openInNewTab: function (url) {
      var win = window.open(url, '_blank');
      win.focus();
    },

    replaceAll:  function (find, replace, str) {
      return str.replace(new RegExp(find, 'g'), replace);
    },

    commaSeparateNumber: function (val){
      while (/(\d+)(\d{3})/.test(val.toString())){
        val = val.toString().replace(/(\d+)(\d{3})/, '$1'+','+'$2');
      }
      return val;
    },
    watchUser: function(callback) {

      var ctrlSelector = "[ng-controller=AppCtrl]";
      function condition() { 
        return (window.angular && window.angular.element(ctrlSelector) && window.angular.element(ctrlSelector).scope()); 
      }

      checkReadyState(function(error, result) {
        
        if (result) {
          var scope = window.angular.element(ctrlSelector).scope();

            scope.$watch('currentUser', function() {
                    callback(scope.currentUser);
            });
        }

      }, 50, condition, null);
  
    }


  };

})(jQuery);