// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// TODO(slightlyoff): Add any required LICENSE block changes for MSFT code
// inclusion.

// ole_document_impl.h : IOleDocument implementation
//
// This file is a modified version of the OleDocument.h file, which is
// part of the ActiveDoc MSDN sample. The modifications are largely
// conversions to Google coding guidelines. Below if the original header
// from the file.

// This is a part of the Active Template Library.
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// This source code is only intended as a supplement to the
// Active Template Library Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Active Template Library product.

#ifndef CHROME_FRAME_OLE_DOCUMENT_IMPL_H_
#define CHROME_FRAME_OLE_DOCUMENT_IMPL_H_

// TODO(sanjeevr): Revisit this impl file and cleanup dependencies
#include <atlbase.h>
#include <docobj.h>

#include "base/logging.h"

//////////////////////////////////////////////////////////////////////////////
// IOleDocumentImpl
template <class T>
class ATL_NO_VTABLE IOleDocumentImpl : public IOleDocument {
 public:
  STDMETHOD(CreateView)(IOleInPlaceSite* in_place_site,
                        IStream* stream,
                        DWORD reserved ,
                        IOleDocumentView** new_view) {
    DLOG(INFO) << __FUNCTION__;
    if (new_view == NULL)
      return E_POINTER;
    T* t = static_cast<T*>(this);
    // If we've already created a view then we can't create another as we
    // currently only support the ability to create one view
    if (t->m_spInPlaceSite) {
      return E_FAIL;
    }
    IOleDocumentView* view;
    t->GetUnknown()->QueryInterface(IID_IOleDocumentView,
                                    reinterpret_cast<void**>(&view));
    // If we support IOleDocument we should support IOleDocumentView
    ATLENSURE(view != NULL);
    // If they've given us a site then use it
    if (in_place_site != NULL) {
      view->SetInPlaceSite(in_place_site);
    }
    // If they have given us an IStream pointer then use it to
    // initialize the view
    if (stream != NULL) {
      view->ApplyViewState(stream);
    }
    // Return the view
    *new_view = view;
    return S_OK;
  }

  STDMETHOD(GetDocMiscStatus)(DWORD* status) {
    DLOG(INFO) << __FUNCTION__;
    if (NULL == status) {
      return E_POINTER;
    }
    *status = DOCMISC_NOFILESUPPORT;
    return S_OK;
  }

  STDMETHOD(EnumViews)(IEnumOleDocumentViews** enum_views,
                       IOleDocumentView** view) {
    DLOG(INFO) << __FUNCTION__;
    if (view == NULL)
      return E_POINTER;
    T* t = static_cast<T*>(this);
    // We only support one view
    return t->_InternalQueryInterface(IID_IOleDocumentView,
                                      reinterpret_cast<void**>(view));
  }
};

//////////////////////////////////////////////////////////////////////////////
// IOleDocumentViewImpl

template <class T>
class ATL_NO_VTABLE IOleDocumentViewImpl : public IOleDocumentView {
 public:
  STDMETHOD(SetInPlaceSite)(IOleInPlaceSite* in_place_site) {
    DLOG(INFO) << __FUNCTION__;
    T* t = static_cast<T*>(this);
    if (t->m_spInPlaceSite) {
      // If we already have a site get rid of it
      UIActivate(FALSE);
      HRESULT hr = t->InPlaceDeactivate();
      if (FAILED(hr)) {
        return hr;
      }
      DCHECK(!t->m_bInPlaceActive);
    }
    if (in_place_site != NULL) {
      t->m_spInPlaceSite.Release();
      in_place_site->QueryInterface(
          IID_IOleInPlaceSiteWindowless,
          reinterpret_cast<void **>(&t->m_spInPlaceSite));
      if (!t->m_spInPlaceSite) {
        // TODO(sanjeevr): This is a super-hack because m_spInPlaceSite
        // is an IOleInPlaceSiteWindowless pointer and we are setting
        // an IOleInPlaceSite pointer into it. The problem is that ATL
        // (CComControlBase) uses this in a schizophrenic manner based
        // on the m_bWndLess flag. Ouch, ouch, ouch! Find a way to clean
        // this up.
        // Disclaimer: I did not invent this hack, it exists in the MSDN
        // sample from where this code has been derived and it also exists
        // in ATL itself (look at atlctl.h line 938).
        t->m_spInPlaceSite =
            reinterpret_cast<IOleInPlaceSiteWindowless*>(in_place_site);
      }
    }
    return S_OK;
  }

  STDMETHOD(GetInPlaceSite)(IOleInPlaceSite** in_place_site) {
    DLOG(INFO) << __FUNCTION__;
    if (in_place_site == NULL) {
      return E_POINTER;
    }
    T* t = static_cast<T*>(this);
    return t->m_spInPlaceSite->QueryInterface(
        IID_IOleInPlaceSite,
        reinterpret_cast<LPVOID *>(in_place_site));
  }

  STDMETHOD(GetDocument)(IUnknown** document) {
    DLOG(INFO) << __FUNCTION__;
    if (document == NULL) {
      return E_POINTER;
    }
    T* t = static_cast<T*>(this);
    *document = t->GetUnknown();
    (*document)->AddRef();
    return S_OK;
  }

  STDMETHOD(SetRect)(LPRECT view_rect) {
    static bool is_resizing = false;
    if (is_resizing) {
      return S_OK;
    }
    is_resizing = true;
    DLOG(INFO) << __FUNCTION__ << " " << view_rect->left << "," <<
        view_rect->top << "," << view_rect->right << "," << view_rect->bottom;
    T* t = static_cast<T*>(this);
    t->SetObjectRects(view_rect, view_rect);
    is_resizing = false;
    return S_OK;
  }

  STDMETHOD(GetRect)(LPRECT view_rect) {
    DLOG(INFO) << __FUNCTION__;
    if (view_rect == NULL) {
      return E_POINTER;
    }
    T* t = static_cast<T*>(this);
    *view_rect = t->m_rcPos;
    return S_OK;
  }

  STDMETHOD(SetRectComplex)(LPRECT view_rect,
                            LPRECT hscroll_rect,
                            LPRECT vscroll_rect,
                            LPRECT size_box_rect) {
    DLOG(INFO) << __FUNCTION__ << " not implemented";
    return E_NOTIMPL;
  }

  STDMETHOD(Show)(BOOL show) {
    DLOG(INFO) << __FUNCTION__;
    T* t = static_cast<T*>(this);
    HRESULT hr = S_OK;
    if (show) {
      if (!t->m_bUIActive)
        hr = t->ActiveXDocActivate(OLEIVERB_INPLACEACTIVATE);
    } else {
      hr = t->UIActivate(FALSE);
      ::ShowWindow(t->m_hWnd, SW_HIDE);
    }
    return hr;
  }

  STDMETHOD(UIActivate)(BOOL ui_activate) {
    DLOG(INFO) << __FUNCTION__;
    T* t = static_cast<T*>(this);
    HRESULT hr = S_OK;
    if (ui_activate) {
      // We must know the client site first
      if (t->m_spInPlaceSite == NULL) {
        return E_UNEXPECTED;
      }
      if (!t->m_bUIActive) {
        hr = t->ActiveXDocActivate(OLEIVERB_UIACTIVATE);
      }
    } else {
      t->InPlaceMenuDestroy();
      // t->DestroyToolbar();
      hr = t->UIDeactivate();
    }
    return hr;
  }

  STDMETHOD(Open)() {
    DLOG(INFO) << __FUNCTION__ << " not implemented";
    return E_NOTIMPL;
  }

  STDMETHOD(CloseView)(DWORD reserved) {
    DLOG(INFO) << __FUNCTION__;
    T* t = static_cast<T*>(this);
    t->Show(FALSE);
    t->SetInPlaceSite(NULL);
    return S_OK;
  }

  STDMETHOD(SaveViewState)(LPSTREAM stream) {
    DLOG(INFO) << __FUNCTION__ << " not implemented";
    return E_NOTIMPL;
  }

  STDMETHOD(ApplyViewState)(LPSTREAM stream) {
    DLOG(INFO) << __FUNCTION__ << " not implemented";
    return E_NOTIMPL;
  }

  STDMETHOD(Clone)(IOleInPlaceSite* new_in_place_site,
                   IOleDocumentView** new_view) {
    DLOG(INFO) << __FUNCTION__ << " not implemented";
    return E_NOTIMPL;
  }

  HRESULT ActiveXDocActivate(LONG verb) {
    return E_NOTIMPL;
  }
};

#endif  // CHROME_FRAME_OLE_DOCUMENT_IMPL_H_
