if (!window.BuildOut) {
  var BuildOut = (function () {
    var plugins = [];
    var modalIframe = null;
    var acceptedParams = {
      "auction": "initialAuction",
      "brandingId": "brandingId",
      "business": "initialBusiness",
      "c": "c",
      "city": "initialCity",
      "closed": "closed",
      "companyId": "companyId",
      "companyOffice": "companyOffices[]",
      "customParams": "customParams",
      "document": "document",
      "ebref": "ebref",
      "investment": "initialInvestment",
      "lat": "lat",
      "lng": "lng",
      "loadVault": "loadVault",
      "officeId": "officeId",
      "officeLocations": "initialOfficeLocations",
      "photoId": "photoId",
      "propertyType": "propertyType",
      "propertyTypes": "initialPropertyTypes",
      "propertyUses": "initialPropertyUses",
      "saleOrLease": "saleOrLease",
      "searchText": "initialSearchText",
      "sortOrder": "initialSortOrder",
      "specialties": "initialSpecialties",
      "state": "initialState",
      "status": "status",
      "tab": "tab",
      "zoom": "zoom"
    };
    var isIosDevice = typeof window !== 'undefined' &&
                      window.navigator &&
                      window.navigator.platform &&
                      /iP(ad|hone|od)/.test(window.navigator.platform);

    function getParams(url) {
      var params = {};
      var parser = document.createElement('a');
      parser.href = url;
      var query = parser.search.substring(1);
      var vars = query.split('&');
      for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        params[pair[0]] = decodeURIComponent(pair[1]);
      }
      return params;
    }

    var allParams = getParams(window.location.href);

    function getParam(name) {
      name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
      return allParams[name];
    }

    function merge(obj1, obj2) {
      var newObj = {};
      for (var attrname in obj1) { newObj[attrname] = obj1[attrname]; }
      for (var attrname in obj2) { newObj[attrname] = obj2[attrname]; }
      return newObj;
    }

    function paramsFromUrl() {
      var params = {};
      for (var param in allParams) {
        var transformedKey = acceptedParams[param];
        if (transformedKey) {
          params[transformedKey] = allParams[param];
        } else {
          params[param] = allParams[param];
        }
      }
      return params;
    }

    function paramsFromOptions(options) {
      
      var params = {};
      for (var param in acceptedParams) {
        var value = options[param];
        if (value) {
          params[acceptedParams[param]] = value;
        }
      }
      return params;
    }

    function customParamsFromUrl() {
      var params = {};

      var allParamStrings = window.location.search.replace(/^\??/, "").split("&");
      for (var i = 0; i < allParamStrings.length; i++) {
        if (allParamStrings[i].match(/^custom/)) {
          var paramArray = allParamStrings[i].split("=");
          params[paramArray[0]] = paramArray[1];
        }
      }

      return params;
    }

    function paramHashToUrl(hash) {
      var paramArray = [];
      for (var param in hash) {
        paramArray.push(param + "=" + encodeURIComponent(hash[param]));
      }
      return paramArray.join("&");
    }

    function embed(options) {
      var token, companyId;

      if (options.token) {
        token = options.token;
        companyId = options.companyId;
      } else {
        token = options.companyId;
      }

      var target = document.getElementById(options.target),
          width = options.width || "100%",
          height = options.height || "auto",
          inventoryParentUrl = options.inventoryParentUrl,
          autoHeight = false,
          plugin = options.plugin;  // 'inventory', 'brokers', 'offices'


      if (height === "auto") {
        autoHeight = true;
        height = 400;
      }

      var style = document.createElement("STYLE");
      document.getElementsByTagName("head")[0].appendChild(style);
      setTimeout(function () {
        style.innerHTML = "#" + options.target + " iframe { border: none }";
      }, 0);


      var iframeScrolling;
      var propertyId = options.propertyId || getParam("propertyId");

      var brokerId = options.brokerId || getParam("brokerId");
      var rootUrl, pluginUrl;

      options.domain = "https://buildout.com/";
      if(options.forceDomain) {
        options.domain = options.forceDomain;
      }

      // We use the hostname so that we can load the buildout bridge without encountering SOP violation due to subdomains (e.g. www)
      rootUrl = options.domain + "plugins/" + token + "/" + document.location.hostname + "/";
      if (plugin == "inventory") {
        pluginUrl = rootUrl + "inventory/";
        if (propertyId) {
          pluginUrl += propertyId;
        }
      } else if (plugin == "brokers") {
        if (brokerId) {
          pluginUrl = rootUrl + "brokers/" + brokerId;
        } else {
          pluginUrl = rootUrl + "brokers/";
        }
      } else if (plugin == "offices") {
        pluginUrl = rootUrl + "offices/";
      } else if (plugin == "featured") {
        iframeScrolling = 'no';
        pluginUrl = rootUrl + "featured/";
      } else {
        alert("Plugin '" + plugin + "' not supported");
      }

      var pluginId = plugins.length;
      var pluginParams = { "pluginId": pluginId, "iframe": "true" };

      if (!options.standalone) {
        pluginParams.embedded = "true";
      }

      if (companyId) {
        pluginParams.companyId = companyId;
      }
      if (inventoryParentUrl) {
        pluginParams.inventoryParentUrl = inventoryParentUrl;
      }

      if (brokerId) {
        pluginParams.brokerId = brokerId;
      }

      if (height === "100%") {
        pluginParams.constrainHeight = "true";
      }

      var cacheSearch = options.cacheSearch == null ? true : options.cacheSearch;
      pluginParams.cacheSearch = cacheSearch;

      console.log(options);
      
      pluginParams = merge(pluginParams, paramsFromOptions(options));
      pluginParams = merge(pluginParams, paramsFromUrl());
      pluginParams = merge(pluginParams, customParamsFromUrl());

      var pluginSearchString = paramHashToUrl(pluginParams);

      if (pluginSearchString.length > 0) {
        pluginUrl += ("?" + pluginSearchString);
      }

      var bot = /bot|googlebot|crawler|spider|robot|crawling/i.test(navigator.userAgent);
      if (bot && (plugin == "inventory" || plugin == "brokers")) {
        window.buildoutEmbed = function (r) {
          target.innerHTML = r.content;
        };
        var script = document.createElement('script');
        script.src = pluginUrl;
        document.getElementsByTagName('head')[0].appendChild(script);
      } else {
        var iframe = document.createElement("IFRAME");
        if (iframeScrolling) {
          iframe.scrolling = iframeScrolling;
        }
        iframe.src = pluginUrl;
        iframe.height = height;
        iframe.frameBorder = "none";
        iframe.allowTransparency = true;
        iframe.setAttribute("noresize", "noresize");

        if (plugin === "featured") {
          iframe.width = "1px";
          iframe.style.cssText = "min-width: " + width;
        } else {
          iframe.width = width;
        }

        target.appendChild(iframe);

        plugin = {
          iframe: iframe,
          autoHeight: autoHeight,
          height: height,
          id: pluginId,
          setHeight: function(newHeight) {
            if(this.height !== "100%") {
              this.iframe.height = newHeight;
            }
          }
        };

        plugins.push(plugin);

        window.addEventListener('message', function (event) {
          var modalContentWindow = modalIframe && modalIframe.contentWindow;
          if (
            (event.origin.split('//')[1] + "/") !== options.domain.split('//')[1] ||
            (event.source !== iframe.contentWindow && event.source !== modalContentWindow)
          ) {
            return;
          }
          var eventName = event.data[0];
          var data = event.data[1];

          switch (eventName) {
            case 'setHeight':
              if(!modalIframe)
                plugin.setHeight(data + "px");
              break;
            case 'scrollToTop':
              if(data) {
                newY = window.pageYOffset + iframe.getBoundingClientRect().top + data;
                window.scrollTo(0, newY);
              } else {
                iframe.scrollIntoView(true);
              }
              break;
            case 'modal':
              renderModal(data, options);
              break;
            case 'modalHide':
              hideModal(options);
              break;
            case 'resizeModal':
              resizeModal(data + "px");
              break;
            case 'pluginReload':
              iframe.contentWindow.postMessage(["reload"], "*");
              break;
            case 'noCookies':
              iframeNoCookiesHandler(options.domain);
              break;
          }
        }, false);
      }
    }

    function cookieHackApplied() {
      return window.location.href.includes("enableCookie=true");
    }

    function iframeNoCookiesHandler(domain) {
      if (!cookieHackApplied()) {
        var locationParam = "?location=" + encodeURIComponent(window.location);
        var locationUrl = domain + "plugins/inventory/allow_cookies" + locationParam;
        window.location.href = locationUrl;
      }
    }

    function handleResize(newHeight, pluginId) {
      pluginId = pluginId == "null" ? 0 : (pluginId || 0);
      for (var i = 0; i < plugins.length; i++) {
        if (plugins[i].autoHeight && plugins[i].id == pluginId) {
          plugins[i].setHeight(newHeight);
        }
      }
    }

    var container;

    function hideModal(options) {
      if (container) {
        container.style.opacity = 0;

        if (isIosDevice) {
          document.getElementById(options.target).style.cssText = "";
        }

        setTimeout(function() {
          container.parentNode.removeChild(container);
          container = null;
          modalIframe = null;
        }, 400);
      }
    }

    function resizeModal(newHeight) {
      if(container) {
        var innerContainer = document.getElementById("buildout-modal-iframe-container");
        innerContainer.style.height = newHeight;
      }
    }

    function renderModal(url, options) {
      container = document.createElement("div");
      var containerCssText = "left: 0; top: 0; width: 100%; opacity: 0; " +
          "transition: opacity 0.4s, top 0.4s; z-index: 31999;";
      var iframeContainerIosStyles;

      if (isIosDevice) {
        var target = document.getElementById(options.target);
        target.style.cssText = "position: fixed; width: 100%; height: 100%; overflow-y: hidden;";
        window.scrollTo(0, 0);

        containerCssText += "position: absolute; height: 200%;";
        iframeContainerIosStyles = "height: 200%; overflow-y: auto; ";
      } else {
        containerCssText += "position: fixed; height: 100%;";
      }

      var iframeContainerResponsiveStyles = [
        "#buildout-modal-iframe-container { width: auto; margin-left: 10px; margin-right: 10px; }",
        "#buildout-modal-iframe-outer-container { padding-top: 100px; }",
        "@media screen and (max-width: 767px) { #buildout-modal-iframe-outer-container { padding-top: 10px; } }",
        "@media screen and (max-width: 767px) { #buildout-modal-iframe-container { overflow-x: hidden; " +
          "overflow-y: scroll; -webkit-overflow-scrolling: touch; max-height: 98%; } }",
        "@media screen and (min-width: 768px) { #buildout-modal-iframe-container { width: 600px; " +
          "margin-left: auto; margin-right: auto; } }",
        "@media screen and (min-width: 992px) { #buildout-modal-iframe-container { width: 900px; } }"
      ];

      var iframeContainerStyles = "#buildout-modal-iframe-container {" +
        "background-color: white; margin-top: -30px; border-radius: 5px;" +
        "position: relative; transition: height 0.4s, margin-top 0.4s;" +
        iframeContainerIosStyles +
      "}";

      container.style.cssText = containerCssText;
      container.innerHTML = "<style>" +
          iframeContainerStyles + "\n" +
          iframeContainerResponsiveStyles.join(" ") + "\n" +
          "#buildout-modal { width: 100%; border: 0; height: 100% }" + "\n" +
        "</style>" +
        "<div style='position: absolute; left: 0; top: 0; width: 100%; height: 100%; " +
          "background-color: rgba(0, 0, 0, 0.4);'></div>" +
        "<div id='buildout-modal-iframe-outer-container' style='max-height: 98%; overflow-y: auto; " +
          "box-sizing: border-box;'>" +
        "<div id='buildout-modal-iframe-container'>" +
        "<iframe id='buildout-modal' src='" + url + "' /></div></div>";

      document.body.appendChild(container);

      container.onclick = hideModal;

      modalIframe = document.getElementById("buildout-modal");

      setTimeout(function() {
        container.style.opacity = 1;
        document.getElementById("buildout-modal-iframe-container").style.marginTop = "0";
      }, 50);
    }

    function sendPluginMessage(message) {
      for (var i = 0; i < plugins.length; i++) {
        plugins[i].iframe.contentWindow.postMessage(message, "*");
      }
    }

    var messageHandlers = [];

    function receiveMessage(message) {
      var m = message.match(/(\w+):(.*),\d+$/);
      if (m) {
        for (var i = 0; i < messageHandlers.length; i++) {
          messageHandlers[i](m[1], unescape(m[2]));
        }
      } else {
        var newHeight = message.split(",")[0];
        var pluginId = message.split(",")[1];
        handleResize(newHeight, pluginId);
      }
    }

    function registerMessageHandler(handler) {
      messageHandlers.push(handler);
    }

    return {
      embed: embed,
      receiveMessage: receiveMessage,
      registerMessageHandler: registerMessageHandler,
      sendPluginMessage: sendPluginMessage
    };
  })();
}