// Copyright 2011 Software Freedom Conservancy
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Ignoring code analysis warnings for:
// "'argument n' might be '0': this does not adhere to the specification for 
// the function 'IHTMLDocument4::createEventObject'", and "'argument n' might
// be null: this does not adhere to the specification for the function
// 'IHTMLDocument4::createEventObject'", and. 
// IHTMLDocument4::createEventObject() should have its first argument set to 
// NULL to create an empty event object, per documentation at:
// http://msdn.microsoft.com/en-us/library/aa752524(v=vs.85).aspx
#pragma warning (disable: 6309)
#pragma warning (disable: 6387)

#include "Element.h"
#include "Browser.h"
#include "Generated/atoms.h"
#include "interactions.h"
#include "logging.h"

namespace webdriver {

Element::Element(IHTMLElement* element, HWND containing_window_handle) {
  LOG(TRACE) << "Entering Element::Element";

  // NOTE: COM should be initialized on this thread, so we
  // could use CoCreateGuid() and StringFromGUID2() instead.
  UUID guid;
  RPC_WSTR guid_string = NULL;
  RPC_STATUS status = ::UuidCreate(&guid);
  status = ::UuidToString(&guid, &guid_string);

  // RPC_WSTR is currently typedef'd in RpcDce.h (pulled in by rpc.h)
  // as unsigned short*. It needs to be typedef'd as wchar_t* 
  wchar_t* cast_guid_string = reinterpret_cast<wchar_t*>(guid_string);
  this->element_id_ = CW2A(cast_guid_string, CP_UTF8);

  ::RpcStringFree(&guid_string);

  this->element_ = element;
  this->containing_window_handle_ = containing_window_handle;
}

Element::~Element(void) {
}

Json::Value Element::ConvertToJson() {
  LOG(TRACE) << "Entering Element::ConvertToJson";

  Json::Value json_wrapper;
  json_wrapper["ELEMENT"] = this->element_id_;

  return json_wrapper;
}

int Element::IsDisplayed(bool* result) {
  LOG(TRACE) << "Entering Element::IsDisplayed";

  int status_code = SUCCESS;

  // The atom is just the definition of an anonymous
  // function: "function() {...}"; Wrap it in another function so we can
  // invoke it with our arguments without polluting the current namespace.
  std::wstring script_source(L"(function() { return (");
  script_source += atoms::asString(atoms::IS_DISPLAYED);
  script_source += L")})();";

  CComPtr<IHTMLDocument2> doc;
  this->GetContainingDocument(false, &doc);
  // N.B., The second argument to the IsDisplayed atom is "ignoreOpacity".
  Script script_wrapper(doc, script_source, 2);
  script_wrapper.AddArgument(this->element_);
  script_wrapper.AddArgument(true);
  status_code = script_wrapper.Execute();

  if (status_code == SUCCESS) {
    *result = script_wrapper.result().boolVal == VARIANT_TRUE;
  } else {
    LOG(WARN) << "Failed to determine is element displayed";
  }

  return status_code;
}

std::string Element::GetTagName() {
  LOG(TRACE) << "Entering Element::GetTagName";

  CComBSTR tag_name_bstr;
  this->element_->get_tagName(&tag_name_bstr);
  tag_name_bstr.ToLower();
  std::string tag_name = CW2A(tag_name_bstr, CP_UTF8);
  return tag_name;
}

bool Element::IsEnabled() {
  LOG(TRACE) << "Entering Element::IsEnabled";

  bool result(false);

  // The atom is just the definition of an anonymous
  // function: "function() {...}"; Wrap it in another function so we can
  // invoke it with our arguments without polluting the current namespace.
  std::wstring script_source(L"(function() { return (");
  script_source += atoms::asString(atoms::IS_ENABLED);
  script_source += L")})();";

  CComPtr<IHTMLDocument2> doc;
  this->GetContainingDocument(false, &doc);
  Script script_wrapper(doc, script_source, 1);
  script_wrapper.AddArgument(this->element_);
  int status_code = script_wrapper.Execute();

  if (status_code == SUCCESS) {
    result = script_wrapper.result().boolVal == VARIANT_TRUE;
  } else {
    LOG(WARN) << "Failed to determine is element enabled";
  }

  return result;
}

int Element::Click(const ELEMENT_SCROLL_BEHAVIOR scroll_behavior) {
  LOG(TRACE) << "Entering Element::Click";

  LocationInfo location = {};
  int status_code = this->GetLocationOnceScrolledIntoView(scroll_behavior, &location);

  if (status_code == SUCCESS) {
    LocationInfo click_location = GetClickPoint(location);

    // Create a mouse move, mouse down, mouse up OS event
    LRESULT result = mouseMoveTo(this->containing_window_handle_,
                                 /* duration of move in ms = */ 10,
                                 location.x,
                                 location.y,
                                 click_location.x,
                                 click_location.y);
    if (result != SUCCESS) {
      LOG(WARN) << "Unable to move mouse, mouseMoveTo returned non-zero value";
      return static_cast<int>(result);
    }
    
    result = clickAt(this->containing_window_handle_,
                     click_location.x,
                     click_location.y,
                     MOUSEBUTTON_LEFT);
    if (result != SUCCESS) {
      LOG(WARN) << "Unable to click at by mouse, clickAt returned non-zero value";
      return static_cast<int>(result);
    }

    //wait(50);
  } else {
    LOG(WARN) << "Unable to get location of clicked element";
  }

  return status_code;
}

int Element::GetAttributeValue(const std::string& attribute_name,
                               std::string* attribute_value,
                               bool* value_is_null) {
  LOG(TRACE) << "Entering Element::GetAttributeValue";

  std::wstring wide_attribute_name = CA2W(attribute_name.c_str(), CP_UTF8);
  int status_code = SUCCESS;

  // The atom is just the definition of an anonymous
  // function: "function() {...}"; Wrap it in another function so we can
  // invoke it with our arguments without polluting the current namespace.
  std::wstring script_source(L"(function() { return (");
  script_source += atoms::asString(atoms::GET_ATTRIBUTE);
  script_source += L")})();";

  CComPtr<IHTMLDocument2> doc;
  this->GetContainingDocument(false, &doc);
  Script script_wrapper(doc, script_source, 2);
  script_wrapper.AddArgument(this->element_);
  script_wrapper.AddArgument(wide_attribute_name);
  status_code = script_wrapper.Execute();
  
  CComVariant value_variant;
  if (status_code == SUCCESS) {
    *value_is_null = !script_wrapper.ConvertResultToString(attribute_value);
  } else {
    LOG(WARN) << "Failed to determine element attribute";
  }

  return SUCCESS;
}

int Element::GetLocationOnceScrolledIntoView(const ELEMENT_SCROLL_BEHAVIOR scroll,
                                             LocationInfo* location) {
  LOG(TRACE) << "Entering Element::GetLocationOnceScrolledIntoView";

  int status_code = SUCCESS;
  CComPtr<IHTMLDOMNode2> node;
  HRESULT hr = this->element_->QueryInterface(&node);

  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Cannot cast html element to node, QI on IHTMLElement for IHTMLDOMNode2 failed";
    return ENOSUCHELEMENT;
  }

  bool displayed;
  int result = this->IsDisplayed(&displayed);
  if (result != SUCCESS) {
    LOG(WARN) << "Unable to determine element is displayed";
    return result;
  } 

  if (!displayed) {
    LOG(WARN) << "Element is not displayed";
    return EELEMENTNOTDISPLAYED;
  }

  LocationInfo element_location = {};
  std::vector<LocationInfo> frame_locations;
  result = this->GetLocation(&element_location, &frame_locations);
  LocationInfo click_location = this->GetClickPoint(element_location);
  bool document_contains_frames = frame_locations.size() != 0;

  if (result != SUCCESS ||
      !this->IsLocationInViewPort(click_location, document_contains_frames) ||
      this->IsHiddenByOverflow() ||
      !this->IsLocationVisibleInFrames(click_location, frame_locations)) {
    // Scroll the element into view
    LOG(DEBUG) << "Will need to scroll element into view";
    CComVariant scroll_behavior = VARIANT_TRUE;
    if (scroll == BOTTOM) {
      scroll_behavior = VARIANT_FALSE;
    }
    hr = this->element_->scrollIntoView(scroll_behavior);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Cannot scroll element into view, IHTMLElement::scrollIntoView failed";
      return EOBSOLETEELEMENT;
    }

    std::vector<LocationInfo> scrolled_frame_locations;
    result = this->GetLocation(&element_location, &scrolled_frame_locations);
    if (result != SUCCESS) {
      LOG(WARN) << "Unable to get location of scrolled to element";
      return result;
    }

    click_location = this->GetClickPoint(element_location);
    if (!this->IsLocationInViewPort(click_location, document_contains_frames)) {
      LOG(WARN) << "Scrolled element is not in view";
      status_code = EELEMENTCLICKPOINTNOTSCROLLED;
    }
  }

  LOG(DEBUG) << "(x, y, w, h): "
             << element_location.x << ", "
             << element_location.y << ", "
             << element_location.width << ", "
             << element_location.height;

  // At this point, we know the element is displayed according to its
  // style attributes, and we've made a best effort at scrolling it so
  // that it's completely within the viewport. We will always return
  // the coordinates of the element, even if the scrolling is unsuccessful.
  // However, we will still return the "element not displayed" status code
  // if the click point has not been scrolled to the viewport.
  location->x = element_location.x;
  location->y = element_location.y;
  location->width = element_location.width;
  location->height = element_location.height;

  return status_code;
}

bool Element::IsHiddenByOverflow() {
  LOG(TRACE) << "Entering Element::IsHiddenByOverflow";

  bool isOverflow = false;

  // what is more correct: this code or JS dom.bot.isShown.isOverflowHiding ?
  // Use JavaScript for this rather than COM calls to avoid dependency
  // on the IHTMLWindow7 interface, which is IE9-specific.
  std::wstring script_source = L"(function() { return function(){";
  script_source += L"var e = arguments[0];";
  script_source += L"var p = e.parentNode;";
  //Note: This logic duplicates Element::GetClickPoint
  script_source += L"var x = e.offsetLeft + (e.clientWidth / 2);";
  script_source += L"var y = e.offsetTop + (e.clientHeight / 2);";
  script_source += L"var s = window.getComputedStyle ? window.getComputedStyle(p, null) : p.currentStyle;";
  //Note: In the case that the parent has overflow=hidden, and the element is out of sight,
  //this will force the IEDriver to scroll the element in to view.  This is a bug.
  //Note: If we reach the document while walking up the DOM tree, we know we've not
  //encountered an element with the style that would indicate the element is hidden by overflow.
  script_source += L"while (p != null && s != null && s.overflow && s.overflow != 'auto' && s.overflow != 'scroll' && s.overflow != 'hidden') {";
  script_source += L"  p = p.parentNode;";
  script_source += L"  if (p === document) {";
  script_source += L"    return false;";
  script_source += L"  } else {";
  script_source += L"    s = window.getComputedStyle ? window.getComputedStyle(p, null) : p.currentStyle;";
  script_source += L"  }";
  script_source += L"}";
  script_source += L"var containerTop = p.scrollTop;";
  script_source += L"var containerLeft = p.scrollLeft;";
  script_source += L"return p != null && ";
  script_source += L"(x < containerLeft || x > containerLeft + p.clientWidth || ";
  script_source += L"y < containerTop || y > containerTop + p.clientHeight);";
  script_source += L"};})();";

  CComPtr<IHTMLDocument2> doc;
  this->GetContainingDocument(false, &doc);
  Script script_wrapper(doc, script_source, 1);
  script_wrapper.AddArgument(this->element_);
  int status_code = script_wrapper.Execute();
  if (status_code == SUCCESS) {
    isOverflow = script_wrapper.result().boolVal == VARIANT_TRUE;
  } else {
    LOG(WARN) << "Unable to determine is element hidden by overflow";
  }

  return isOverflow;
}

bool Element::IsLocationVisibleInFrames(const LocationInfo location, const std::vector<LocationInfo> frame_locations) {
  std::vector<LocationInfo>::const_iterator iterator = frame_locations.begin();
  for (; iterator != frame_locations.end(); ++iterator) {
    if (location.x < iterator->x || 
        location.y < iterator->y ||
        location.x > iterator->x + iterator->width || 
        location.y > iterator->y + iterator->height) {
      return false;
    }
  }
  return true;
}

bool Element::IsSelected() {
  LOG(TRACE) << "Entering Element::IsSelected";

  bool selected(false);
  // The atom is just the definition of an anonymous
  // function: "function() {...}"; Wrap it in another function so we can
  // invoke it with our arguments without polluting the current namespace.
  std::wstring script_source(L"(function() { return (");
  script_source += atoms::asString(atoms::IS_SELECTED);
  script_source += L")})();";

  CComPtr<IHTMLDocument2> doc;
  this->GetContainingDocument(false, &doc);
  Script script_wrapper(doc, script_source, 1);
  script_wrapper.AddArgument(this->element_);
  int status_code = script_wrapper.Execute();

  if (status_code == SUCCESS && script_wrapper.ResultIsBoolean()) {
    selected = script_wrapper.result().boolVal == VARIANT_TRUE;
  } else {
    LOG(WARN) << "Unable to determine is element selected";
  }

  return selected;
}

int Element::GetLocation(LocationInfo* location, std::vector<LocationInfo>* frame_locations) {
  LOG(TRACE) << "Entering Element::GetLocation";

  bool hasAbsolutePositionReadyToReturn = false;

  CComPtr<IHTMLElement2> element2;
  HRESULT hr = this->element_->QueryInterface(&element2);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to cast element to IHTMLElement2";
    return EOBSOLETEELEMENT;
  }

  // If this element is inline, we need to check whether we should 
  // use getBoundingClientRect() or the first non-zero-sized rect returned
  // by getClientRects(). If the element is not inline, we can use
  // getBoundingClientRect() directly.
  CComPtr<IHTMLRect> rect;
  if (this->IsInline()) {
    CComPtr<IHTMLRectCollection> rects;
    hr = element2->getClientRects(&rects);
    long rect_count;
    rects->get_length(&rect_count);
    if (rect_count > 1) {
      LOG(DEBUG) << "Element is inline with multiple client rects, finding first non-zero sized client rect";
      for (long i = 0; i < rect_count; ++i) {
        CComVariant index(i);
        CComVariant rect_variant;
        hr = rects->item(&index, &rect_variant);
        if (SUCCEEDED(hr) && rect_variant.pdispVal) {
          CComQIPtr<IHTMLRect> qi_rect(rect_variant.pdispVal);
          if (qi_rect) {
            rect = qi_rect;
            if (RectHasNonZeroDimensions(rect)) {
              // IE returns absolute positions in the page, rather than frame- and scroll-bound
              // positions, for clientRects (as opposed to boundingClientRects).
              hasAbsolutePositionReadyToReturn = true;
              break;
            }
          }
        }
      }
    } else {
      LOG(DEBUG) << "Element is inline with one client rect, using IHTMLElement2::getBoundingClientRect";
      hr = element2->getBoundingClientRect(&rect);
    }
  } else {
    LOG(DEBUG) << "Element is a block element, using IHTMLElement2::getBoundingClientRect";
    hr = element2->getBoundingClientRect(&rect);
  }
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Cannot figure out where the element is on screen, client rect retrieval failed";
    return EUNHANDLEDERROR;
  }

  // If the rect of the element has zero width and height, check its
  // children to see if any of them have width and height, in which
  // case, this element will be visible.
  if (!RectHasNonZeroDimensions(rect)) {
    LOG(DEBUG) << "Element has client rect with zero dimension, checking children for non-zero dimension client rects";
    CComPtr<IHTMLDOMNode> node;
    element2->QueryInterface(&node);
    CComPtr<IDispatch> childrenDispatch;
    node->get_childNodes(&childrenDispatch);
    CComQIPtr<IHTMLDOMChildrenCollection> children = childrenDispatch;
    if (!!children) {
      long childrenCount = 0;
      children->get_length(&childrenCount);
      for (long i = 0; i < childrenCount; ++i) {
        CComPtr<IDispatch> childDispatch;
        children->item(i, &childDispatch);
        CComPtr<IHTMLElement> child;
        childDispatch->QueryInterface(&child);
        if (child != NULL) {
          Element childElement(child, this->containing_window_handle_);
          std::vector<LocationInfo> child_frame_locations;
          int result = childElement.GetLocation(location, &child_frame_locations);
          if (result == SUCCESS) {
            return result;
          }
        }
      }
    }

    return EELEMENTNOTDISPLAYED;
  }

  long top = 0, bottom = 0, left = 0, right = 0;

  rect->get_top(&top);
  rect->get_left(&left);
  rect->get_bottom(&bottom);
  rect->get_right(&right);

  long w = right - left;
  long h = bottom - top;

  if (!hasAbsolutePositionReadyToReturn) {
    // On versions of IE prior to 8 on Vista, if the element is out of the 
    // viewport this would seem to return 0,0,0,0. IE 8 returns position in 
    // the DOM regardless of whether it's in the browser viewport.
    long scroll_left, scroll_top = 0;
    element2->get_scrollLeft(&scroll_left);
    element2->get_scrollTop(&scroll_top);
    left += scroll_left;
    top += scroll_top;

    // Only add the frame offset if the element is actually in a frame.
    LocationInfo frame_location = {};
    bool element_is_in_frame = this->GetFrameDetails(&frame_location, frame_locations);
    if (element_is_in_frame) {
      left += frame_location.x;
      top += frame_location.y;
      frame_locations->push_back(frame_location);
    } else {
      LOG(DEBUG) << "Element is not in a frame";
    }
  }

  location->x = left;
  location->y = top;
  location->width = w;
  location->height = h;

  return SUCCESS;
}

bool Element::IsInline() {
  LOG(TRACE) << "Entering Element::IsInline";

  // TODO(jimevans): Clean up this extreme lameness.
  // We should be checking styles here for whether the
  // element is inline or not.
  CComPtr<IHTMLAnchorElement> anchor;
  HRESULT hr = this->element_->QueryInterface(&anchor);
  if (anchor) {
    return true;
  }

  CComPtr<IHTMLSpanElement> span;
  hr = this->element_->QueryInterface(&span);
  if (span) {
    return true;
  }

  return false;
}

bool Element::RectHasNonZeroDimensions(const CComPtr<IHTMLRect> rect) {
  LOG(TRACE) << "Entering Element::RectHasNonZeroDimensions";

  long top = 0, bottom = 0, left = 0, right = 0;

  rect->get_top(&top);
  rect->get_left(&left);
  rect->get_bottom(&bottom);
  rect->get_right(&right);

  long w = right - left;
  long h = bottom - top;

  return w > 0 && h > 0;
}

bool Element::GetFrameDetails(LocationInfo* location, std::vector<LocationInfo>* frame_locations) {
  LOG(TRACE) << "Entering Element::GetFrameDetails";

  CComPtr<IHTMLDocument2> owner_doc;
  int status_code = this->GetContainingDocument(true, &owner_doc);
  if (status_code != SUCCESS) {
    LOG(WARN) << "Unable to get containing document";
    return false;
  }

  CComPtr<IHTMLWindow2> owner_doc_window;
  HRESULT hr = owner_doc->get_parentWindow(&owner_doc_window);
  if (!owner_doc_window) {
    LOG(WARN) << "Unable to get parent window, call to IHTMLDocument2::get_parentWindow failed";
    return false;
  }

  // Get the parent window to the current window, where "current window" is
  // the window containing the parent document of this element. If that parent
  // window exists, and it is not the same as the current window, we assume
  // this element exists inside a frame or iframe. If it is in a frame, get
  // the parent document containing the frame, so we can get the information
  // about the frame or iframe element hosting the document of this element.
  CComPtr<IHTMLWindow2> parent_window;
  hr = owner_doc_window->get_parent(&parent_window);
  if (parent_window && !owner_doc_window.IsEqualObject(parent_window)) {
    LOG(DEBUG) << "Element is in a frame.";
    CComPtr<IHTMLDocument2> parent_doc;
    status_code = this->GetDocumentFromWindow(parent_window, &parent_doc);

    CComPtr<IHTMLFramesCollection2> frames;
    hr = parent_doc->get_frames(&frames);

    long frame_count(0);
    hr = frames->get_length(&frame_count);
    CComVariant index;
    index.vt = VT_I4;
    for (long i = 0; i < frame_count; ++i) {
      // See if the document in each frame is this element's 
      // owner document.
      index.lVal = i;
      CComVariant result;
      hr = frames->item(&index, &result);
      CComQIPtr<IHTMLWindow2> frame_window(result.pdispVal);
      if (!frame_window) {
        // Frame is not an HTML frame.
        continue;
      }

      CComPtr<IHTMLDocument2> frame_doc;
      status_code = this->GetDocumentFromWindow(frame_window, &frame_doc);

      if (frame_doc.IsEqualObject(owner_doc)) {
        // The document in this frame *is* this element's owner
        // document. Get the frameElement property of the document's
        // containing window (which is itself an HTML element, either
        // a frame or an iframe). Then get the x and y coordinates of
        // that frame element.
        // N.B. We must use JavaScript here, as directly using
        // IHTMLWindow4.get_frameElement() returns E_NOINTERFACE under
        // some circumstances.
        LOG(DEBUG) << "Located host frame. Attempting to get hosting element";
        std::wstring script_source = L"(function(){ return function() { return arguments[0].frameElement };})();";
        Script script_wrapper(frame_doc, script_source, 1);
        CComVariant window_variant(frame_window);
        script_wrapper.AddArgument(window_variant);
        status_code = script_wrapper.Execute();
        CComPtr<IHTMLFrameBase> frame_base;
        if (status_code == SUCCESS) {
          hr = script_wrapper.result().pdispVal->QueryInterface<IHTMLFrameBase>(&frame_base);
          if (FAILED(hr)) {
            LOG(WARN) << "Found the frame element, but could not QueryInterface to IHTMLFrameBase.";
          }
        } else {
          // Can't get the frameElement property, likely because the frames are from different
          // domains. So start at the parent document, and use getElementsByTagName to retrieve
          // all of the iframe elements (if there are no iframe elements, get the frame elements)
          // **** BIG HUGE ASSUMPTION!!! ****
          // The index of the frame from the document.frames collection will correspond to the 
          // index into the collection of iframe/frame elements returned by getElementsByTagName.
          LOG(WARN) << "Attempting to get frameElement via JavaScript failed. "
                    << "This usually means the frame is in a different domain than the parent frame. "
                    << "Browser security against cross-site scripting attacks will not allow this. "
                    << "Attempting alternative method.";
          long collection_count = 0;
          CComPtr<IDispatch> element_dispatch;
          CComQIPtr<IHTMLDocument3> doc(parent_doc);
          if (doc) {
            LOG(DEBUG) << "Looking for <iframe> elements in parent document.";
            CComPtr<IHTMLElementCollection> iframe_collection;
            hr = doc->getElementsByTagName(L"iframe", &iframe_collection);
            hr = iframe_collection->get_length(&collection_count);
            if (collection_count != 0) {
              if (collection_count > index.lVal) {
                LOG(DEBUG) << "Found <iframe> elements in parent document, retrieving element" << index.lVal << ".";
                hr = iframe_collection->item(index, index, &element_dispatch);
                hr = element_dispatch->QueryInterface<IHTMLFrameBase>(&frame_base);
              }
            } else {
              LOG(DEBUG) << "No <iframe> elements, looking for <frame> elements in parent document.";
              CComPtr<IHTMLElementCollection> frame_collection;
              hr = doc->getElementsByTagName(L"frame", &frame_collection);
              hr = frame_collection->get_length(&collection_count);
              if (collection_count > index.lVal) {
                LOG(DEBUG) << "Found <frame> elements in parent document, retrieving element" << index.lVal << ".";
                hr = frame_collection->item(index, index, &element_dispatch);
                hr = element_dispatch->QueryInterface<IHTMLFrameBase>(&frame_base);
              }
            }
          } else {
            LOG(WARN) << "QueryInterface of parent document to IHTMLDocument3 failed.";
          }
        }

        if (frame_base) {
          LOG(DEBUG) << "Successfully found frame hosting element";
          LocationInfo frame_doc_info;
          bool doc_dimensions_success = DocumentHost::GetDocumentDimensions(
              frame_doc,
              &frame_doc_info);

          // Wrap the element so we can find its location. Note that
          // GetLocation() may recursively call into this method.
          CComQIPtr<IHTMLElement> frame_element(frame_base);
          Element element_wrapper(frame_element, this->containing_window_handle_);
          LocationInfo frame_location = {};
          status_code = element_wrapper.GetLocation(&frame_location,
                                                    frame_locations);
          if (status_code == SUCCESS) {
            // Take into account the presence of scrollbars in the frame.
            long frame_element_width = frame_location.width;
            long frame_element_height = frame_location.height;
            if (doc_dimensions_success) {
              if (frame_doc_info.height > frame_element_height) {
                int horizontal_scrollbar_height = ::GetSystemMetrics(SM_CYHSCROLL);
                frame_element_height -= horizontal_scrollbar_height;
              }
              if (frame_doc_info.width > frame_element_width) {
                int vertical_scrollbar_width = ::GetSystemMetrics(SM_CXVSCROLL);
                frame_element_width -= vertical_scrollbar_width;
              }
            }
            location->x = frame_location.x;
            location->y = frame_location.y;
            location->width = frame_element_width;
            location->height = frame_element_height;
          }
          return true;
        }
      }
    }
  }

  // If we reach here, the element isn't in a frame/iframe.
  return false;
}

LocationInfo Element::GetClickPoint(const LocationInfo location) {
  LOG(TRACE) << "Entering Element::GetClickPoint";

  LocationInfo click_location = {};
  //Note: This logic is duplicated in javascript in Element::IsHiddenByOverflow
  click_location.x = location.x + (location.width / 2);
  click_location.y = location.y + (location.height / 2);
  return click_location;
}

bool Element::IsLocationInViewPort(const LocationInfo location, const bool document_contains_frames) {
  LOG(TRACE) << "Entering Element::IsLocationInViewPort";

  WINDOWINFO window_info;
  if (!::GetWindowInfo(this->containing_window_handle_, &window_info)) {
    LOG(WARN) << "Cannot determine size of window, call to GetWindowInfo API failed";
    return false;
  }

  long window_width = window_info.rcClient.right - window_info.rcClient.left;
  long window_height = window_info.rcClient.bottom - window_info.rcClient.top;

  if (!document_contains_frames) {
    // ASSUMPTION! IE **always** draws a vertical scroll bar, even if it's not
    // required. This means the viewport width is always smaller than the window
    // width by at least the width of the vertical scroll bar.
    int vertical_scrollbar_width = ::GetSystemMetrics(SM_CXVSCROLL);
    window_width -= vertical_scrollbar_width;

    // Horizontal scrollbar will only appear if the document is wider than the
    // viewport.
    CComPtr<IHTMLDocument2> doc;
    this->GetContainingDocument(false, &doc);
    LocationInfo document_info;
    DocumentHost::GetDocumentDimensions(doc, &document_info);
    if (document_info.width > window_width) {
      int horizontal_scrollbar_height = ::GetSystemMetrics(SM_CYHSCROLL);
      window_height -= horizontal_scrollbar_height;
    }
  }

  // Hurrah! Now we know what the visible area of the viewport is
  // Is the element visible in the X axis?
  // N.B. There is an n-pixel sized area next to the client area border
  // where clicks are interpreted as a click on the window border, not
  // within the client area. We are assuming n == 2, but that's strictly
  // a wild guess, not based on any research.
  if (location.x < 0 || location.x >= window_width - 2) {
    LOG(WARN) << "X coordinate is out of element area";
    return false;
  }

  // And in the Y?
  if (location.y < 0 || location.y >= window_height - 2) {
    LOG(WARN) << "Y coordinate is out of element area";
    return false;
  }

  return true;
}

int Element::GetContainingDocument(const bool use_dom_node,
                                   IHTMLDocument2** doc) {
  LOG(TRACE) << "Entering Element::GetContainingDocument";

  HRESULT hr = S_OK;
  CComPtr<IDispatch> dispatch_doc;

  if (use_dom_node) {
    CComPtr<IHTMLDOMNode2> node;
    hr = this->element_->QueryInterface(&node);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to cast element to IHTMLDomNode2";
      return ENOSUCHDOCUMENT;
    }

    hr = node->get_ownerDocument(&dispatch_doc);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to locate owning document, call to IHTMLDOMNode2::get_ownerDocument failed";
      return ENOSUCHDOCUMENT;
    }
  } else {
    hr = this->element_->get_document(&dispatch_doc);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to locate document property, call to IHTMLELement::get_document failed";
      return ENOSUCHDOCUMENT;
    }

  }

  try {
    hr = dispatch_doc.QueryInterface<IHTMLDocument2>(doc);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Found document but it's not the expected type (IHTMLDocument2)";
      return ENOSUCHDOCUMENT;
    }
  } catch(...) {
    LOG(WARN) << "Found document but it's not the expected type (IHTMLDocument2)";
    return ENOSUCHDOCUMENT;
  }

  return SUCCESS;
}

int Element::GetDocumentFromWindow(IHTMLWindow2* parent_window,
                                   IHTMLDocument2** parent_doc) {
  LOG(TRACE) << "Entering Element::GetParentDocument";

  HRESULT hr = parent_window->get_document(parent_doc);
  if (FAILED(hr)) {
    if (hr == E_ACCESSDENIED) {
      // Cross-domain documents may throw Access Denied. If so,
      // get the document through the IWebBrowser2 interface.
      CComPtr<IWebBrowser2> window_browser;
      CComQIPtr<IServiceProvider> service_provider(parent_window);
      hr = service_provider->QueryService(IID_IWebBrowserApp, &window_browser);
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Unable to get browser, call to IServiceProvider::QueryService failed for IID_IWebBrowserApp";
        return ENOSUCHDOCUMENT;
      }
      CComQIPtr<IDispatch> parent_doc_dispatch;
      hr = window_browser->get_Document(&parent_doc_dispatch);
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Unable to get document, call to IWebBrowser2::get_Document failed";
        return ENOSUCHDOCUMENT;
      }
      try {
        hr = parent_doc_dispatch->QueryInterface<IHTMLDocument2>(parent_doc);
        if (FAILED(hr)) {
          LOGHR(WARN, hr) << "Unable to get document, QueryInterface for IHTMLDocument2 failed";
          return ENOSUCHDOCUMENT;
        }
      } catch(...) {
        LOG(WARN) << "Unable to get document, exception thrown attempting to QueryInterface for IHTMLDocument2";
        return ENOSUCHDOCUMENT;
      }
    } else {
      LOGHR(WARN, hr) << "Unable to get document, IHTMLWindow2::get_document failed with error code other than E_ACCESSDENIED";
      return ENOSUCHDOCUMENT;
    }
  }
  return SUCCESS;
}

int Element::ExecuteAsyncAtom(const std::wstring& sync_event_name, ASYNCEXECPROC execute_proc, std::string* error_msg) {
    CComPtr<IHTMLDocument2> doc;
    this->GetContainingDocument(false, &doc);

    // Marshal the document and the element to click to streams for use in another thread.
    LOG(DEBUG) << "Marshaling document to stream to send to new thread";
    LPSTREAM stream;
    HRESULT hr = ::CoMarshalInterThreadInterfaceInStream(IID_IHTMLDocument2, doc, &stream);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "CoMarshalInterfaceThreadInStream() for document failed";
      *error_msg = "Couldn't marshal the IHTMLDocument2 interface to a stream. This is an internal COM error.";
      return EUNEXPECTEDJSERROR;
    }

    // We need exclusive access to this event. If it's already created,
    // OpenEvent returns non-NULL, so we need to wait a bit and retry
    // until OpenEvent returns NULL.
    int retry_counter = 50;
    HANDLE event_handle = ::OpenEvent(SYNCHRONIZE, FALSE, sync_event_name.c_str());
    if (event_handle != NULL && --retry_counter > 0) {
      ::CloseHandle(event_handle);
      ::Sleep(50);
      event_handle = ::OpenEvent(SYNCHRONIZE, FALSE, sync_event_name.c_str());
    }

    // Failure condition here.
    if (event_handle != NULL) {
      ::CloseHandle(event_handle);
      LOG(WARN) << "OpenEvent() returned non-NULL, event already exists.";
      *error_msg = "Couldn't create an event for synchronizing the creation of the thread. This generally means that you were trying to click on an option in two different instances.";
      return EUNEXPECTEDJSERROR;
    }

    LOG(DEBUG) << "Creating synchronization event for new thread";
    event_handle = ::CreateEvent(NULL, TRUE, FALSE, sync_event_name.c_str());
    if (event_handle == NULL) {
      LOG(WARN) << "CreateEvent() failed.";
      *error_msg = "Couldn't create an event for synchronizing the creation of the thread. This is an internal failure at the Windows OS level, and is generally not due to an error in the IE driver.";
      return EUNEXPECTEDJSERROR;
    }

    // Start the thread and wait up to 1 second to be signaled that it is ready
    // to receive messages, then close the event handle.
    LOG(DEBUG) << "Starting new thread";
    unsigned int thread_id = 0;
    HANDLE thread_handle = reinterpret_cast<HANDLE>(_beginthreadex(NULL,
                                                    0,
                                                    execute_proc,
                                                    (void *)stream,
                                                    0,
                                                    &thread_id));
    LOG(DEBUG) << "Waiting for new thread to be ready for messages";
    DWORD event_wait_result = ::WaitForSingleObject(event_handle, 5000);
    if (event_wait_result != WAIT_OBJECT_0) {
      LOG(WARN) << "Waiting for event to be signaled returned unexpected value: " << event_wait_result;
    }
    ::CloseHandle(event_handle);

    if (thread_handle == NULL) {
      LOG(WARN) << "_beginthreadex() failed.";
      *error_msg = "Couldn't create the thread for executing JavaScript asynchronously.";
      return EUNEXPECTEDJSERROR;
    }

    // This is why we shouldn't do this all the time. We have no way to
    // verify the success or failure of the called function, so we have to
    // assume we just succeeded.
    LOG(DEBUG) << "Marshaling element to stream to send to thread";
    int status_code = SUCCESS;
    LPSTREAM element_stream;
    hr = ::CoMarshalInterThreadInterfaceInStream(IID_IDispatch, this->element_, &element_stream);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "CoMarshalInterfaceThreadInStream() for element failed";
      *error_msg = "Couldn't marshal the IHTMLElement interface to a stream. This is an internal COM error.";
      status_code = EUNEXPECTEDJSERROR;
    } else {
      // Post the message to execute the atom to the worker thread.
      // Try to let the thread complete within a short amount of time
      // to have a hope of synchronization.
      LOG(DEBUG) << "Posting thread message";
      DWORD post_message_result = ::PostThreadMessage(thread_id, WD_EXECUTE_ASYNC_SCRIPT, NULL, reinterpret_cast<LPARAM>(&element_stream));
      DWORD wait_result = ::WaitForSingleObject(thread_handle, 100);
      if (wait_result == WAIT_OBJECT_0) {
        LOG(DEBUG) << "Thread exited successfully";
      } else if (wait_result == WAIT_TIMEOUT) {
        LOG(DEBUG) << "Thread still running. This does not necesarily mean an error condition. There may be a valid alert displayed.";
      } else {
        LOG(WARN) << "WaitForSingleObject returned an unexpected value: " << wait_result;
      }
    }
    ::CloseHandle(thread_handle);
    return status_code;
}

bool Element::IsAttachedToDom() {
  // Verify that the element is still valid by walking up the
  // DOM tree until we find no parent or the html tag
  if (this->element_) {
    CComPtr<IHTMLElement> parent(this->element_);
    while (parent) {
      CComQIPtr<IHTMLHtmlElement> html(parent);
      if (html) {
        return true;
      }

      CComPtr<IHTMLElement> next;
      HRESULT hr = parent->get_parentElement(&next);
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Unable to get parent element, call to IHTMLElement::get_parentElement failed";
      }

      if (next == NULL) {
        BSTR tag;
        hr = parent->get_tagName(&tag);
        if (FAILED(hr)) {
          LOG(TRACE) << "Found null parent of element and couldn't get tag name";
        } else {
          LOG(TRACE) << "Found null parent of element with tag " << _bstr_t(tag);
        }
      }
      parent = next;
    }
  }
  return false;
}

bool Element::HasOnlySingleTextNodeChild() {
  CComPtr<IHTMLDOMNode> element_node;
  HRESULT hr = this->element_.QueryInterface<IHTMLDOMNode>(&element_node);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "QueryInterface for IHTMLDOMNode on element failed.";
    return false;
  }

  CComPtr<IDispatch> child_nodes_dispatch;
  hr = element_node->get_childNodes(&child_nodes_dispatch);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Call to get_childNodes on element failed.";
    return false;
  }

  CComPtr<IHTMLDOMChildrenCollection> child_nodes;
  hr = child_nodes_dispatch.QueryInterface<IHTMLDOMChildrenCollection>(&child_nodes);

  long length = 0;
  hr = child_nodes->get_length(&length);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Call to get_length on child nodes collection failed.";
    return false;
  }

  if (length > 1) {
    CComPtr<IDispatch> child_dispatch;
    hr = child_nodes->item(0, &child_dispatch);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Call to item(0) on child nodes collection failed.";
      return false;
    }

    CComPtr<IHTMLDOMNode> child_node;
    hr = child_dispatch.QueryInterface<IHTMLDOMNode>(&child_node);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "QueryInterface for IHTMLDOMNode on child node failed.";
      return false;
    }

    long node_type = 0;
    hr = child_node->get_nodeType(&node_type);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Call to get_nodeType on child node failed.";
      return false;
    }

    if (node_type == 3) {
      return true;
    }
  }
  return false;
}

bool Element::GetTextBoundaries(LocationInfo* text_info) {
  CComPtr<IHTMLDocument2> doc;
  this->GetContainingDocument(false, &doc);
  CComPtr<IHTMLElement> body_element;
  HRESULT hr = doc->get_body(&body_element);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Call to get_body on document failed.";
    return false;
  }

  CComPtr<IHTMLBodyElement> body;
  hr = body_element.QueryInterface<IHTMLBodyElement>(&body);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "QueryInterface for IHTMLBodyElement on body element failed.";
    return false;
  }

  CComPtr<IHTMLTxtRange> range;
  hr = body->createTextRange(&range);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Call to createTextRange on body failed.";
    return false;
  }

  hr = range->moveToElementText(this->element_);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Call to moveToElementText on range failed.";
    return false;
  }

  CComPtr<IHTMLTextRangeMetrics> range_metrics;
  hr = range.QueryInterface<IHTMLTextRangeMetrics>(&range_metrics);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "QueryInterface for IHTMLTextRangeMetrics on range failed.";
    return false;
  }

  long height = 0;
  hr = range_metrics->get_boundingHeight(&height);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Call to get_boundingHeight on range metrics failed.";
    return false;
  }

  long width = 0;
  hr = range_metrics->get_boundingWidth(&width);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Call to get_boundingWidth on range metrics failed.";
    return false;
  }

  text_info->height = height;
  text_info->width = width;
  return true;
}

} // namespace webdriver