/*
 * Copyright (c) 2010-2013 Nektra S.A., Buenos Aires, Argentina.
 * All rights reserved.
 *
 **/

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using mshtml;

namespace CSharpIE
{
    class HTMLDocument2Events2Sink : IDisposable
    {
        public delegate void DocumentCompleteEventHandler(int procId, IHTMLDocument2 doc);

        private int procId;
        private IHTMLDocument2 doc;
        private DocumentCompleteEventHandler docCompletedHandler;

        private int cookie = -1;
        private IConnectionPoint connPoint;
        private IConnectionPointContainer connPointContainer;
        private static Guid IID_HTMLDocumentEvents2 = typeof(HTMLDocumentEvents2).GUID;

        private Handler handler;

        //------------------------------------------------------------

        public HTMLDocument2Events2Sink(int procId, IHTMLDocument2 doc, DocumentCompleteEventHandler h)
        {
            this.procId = procId;
            this.doc = doc;
            docCompletedHandler = h;
            handler = new Handler(this);
            connPointContainer = (IConnectionPointContainer)doc;
            connPointContainer.FindConnectionPoint(ref IID_HTMLDocumentEvents2, out connPoint);
            connPoint.Advise(handler, out cookie);
        }

        ~HTMLDocument2Events2Sink()
        {

        }

        public void Dispose()
        {
            if (cookie != -1)
            {
                connPoint.Unadvise(cookie);
            }
            cookie = -1;
            handler = null;
        }

        public void OnDocReadyStateChanged()
        {
            if (doc.readyState == "complete")
            {
                docCompletedHandler(procId, doc);
            }
        }
    }

    [ComVisible(true), ComImport()]
    [TypeLibType((short)4160)]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
    [Guid("3050f613-98b5-11cf-bb82-00aa00bdce0b")]
    internal interface HTMLDocumentEvents2
    {
        [DispId(-609)]
        void onreadystatechange([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
    }

    internal class Handler : HTMLDocumentEvents2
    {
        private HTMLDocument2Events2Sink parent;

        public Handler(HTMLDocument2Events2Sink parent)
        {
            this.parent = parent;
        }

        public void onreadystatechange(IHTMLEventObj pEvtObj)
        {
            parent.OnDocReadyStateChanged();
        }
    }
}
