﻿/*
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you 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. 
 */
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Phone.Controls;
using System.Windows.Input;
using System.Diagnostics;
using System.Windows.Media;
using System;
using System.Collections.Generic;

namespace WPCordovaClassLib
{

    /// <summary>
    /// Suppresses pinch zoom and optionally scrolling of the WebBrowser control
    /// </summary>
    public class BrowserMouseHelper
    {

        /**
         * 
         * Full Script below, in use it is minified.
        */
        /*
        private static string mouseScript =
        @"(function(win,doc){
            var mPro = MouseEvent.prototype;
            var def = Object.defineProperty;
            def( mPro, 'pageX', {
               configurable: true,
               get: function(){ return this.clientX }
            });
            def( mPro, 'pageY', {
               configurable: true,
               get: function(){ return this.clientY }
            });

            win.onNativeMouseEvent = function(type,x,y){
                try {
                    var xMod = screen.logicalXDPI / screen.deviceXDPI;
                    var yMod = screen.logicalYDPI / screen.deviceYDPI;
                    var evt = doc.createEvent('MouseEvents');
                    var xPos =  doc.body.scrollLeft + Math.round(xMod * x);
                    var yPos =  doc.body.scrollTop + Math.round(yMod * y);
                    var element = doc.elementFromPoint(xPos,yPos);
                    
                    evt.initMouseEvent(type, true, true, win, 1, xPos, yPos, xPos, yPos, false, false, false, false, 0, element);
                    evt.timeStamp = +new Date;
                    evt.isCordovaEvent = true;
                    
                    var canceled = element ? !element.dispatchEvent(evt) : !doc.dispatchEvent(evt);
                    return canceled ? 'true' : 'false';
                }
                catch(e) { return e;}
            }
        })(window,document);";
        */

        private static string MinifiedMouseScript = "(function(g,a){var c=MouseEvent.prototype,d=Object.defineProperty;d(c,'pageX',{configurable:!0,get:function(){return this.clientX}});d(c,'pageY',{configurable:!0,get:function(){return this.clientY}});g.onNativeMouseEvent=function(c,d,i)"
        + "{try{var j=screen.logicalXDPI/screen.deviceXDPI,k=screen.logicalYDPI/screen.deviceYDPI,b=a.createEvent('MouseEvents'),e=a.body.scrollLeft+Math.round(j*d),f=a.body.scrollTop+Math.round(k*i),h=a.elementFromPoint(e,f);b.initMouseEvent(c,!0,!0,g,1,e,f,e,f,!1,!1,!1,!1,0,"
        + "h);b.timeStamp=+new Date;b.isCordovaEvent=!0;return(h?!h.dispatchEvent(b):!a.dispatchEvent(b))?'true':'false'}catch(l){return l}}})(window,document);";


        private WebBrowser _browser;

        /// <summary>
        /// Gets or sets whether to suppress the scrolling of
        /// the WebBrowser control;
        /// </summary>
        public bool ScrollDisabled { get; set; }

        private bool userScalable = true;
        private double maxScale = 2.0;
        private double minScale = 0.5;
        protected Border border;
        private bool firstMouseMove = false;

        /// <summary>
        /// Represents last known mouse down position. 
        /// Used to determine mouse move delta to avoid duplicate mouse events.
        /// </summary>
        private Point mouseDownPos;

        /// <summary>
        /// Represent min delta value to consider event as a mouse move. Experimental calculated.
        /// </summary>
        private const int MouseMoveDeltaThreshold = 10;


        public BrowserMouseHelper(ref WebBrowser browser)
        {
            _browser = browser;
            browser.Loaded += new RoutedEventHandler(browser_Loaded);
        }

        private void browser_Loaded(object sender, RoutedEventArgs e)
        {
            var border0 = VisualTreeHelper.GetChild(_browser, 0);
            var border1 = VisualTreeHelper.GetChild(border0, 0);
            var panZoom = VisualTreeHelper.GetChild(border1, 0);
            var grid = VisualTreeHelper.GetChild(panZoom, 0);
            var gridChild = VisualTreeHelper.GetChild(grid, 0);

            border = gridChild as Border;
            // windows phone 7 sdk apps running on windows phone 8 os have an additional child in the visualtree
            // if border is null, we probably need to go one deeper.
            if (border == null)
            {
                border = VisualTreeHelper.GetChild(gridChild, 0) as Border;
            }

            if (border != null)
            {
                border.ManipulationStarted += Border_ManipulationStarted;
                border.ManipulationDelta += Border_ManipulationDelta;
                border.ManipulationCompleted += Border_ManipulationCompleted;
                border.DoubleTap += Border_DoubleTap;
                border.Tap += Border_Tap;
                border.Hold += Border_Hold;
                border.MouseLeftButtonDown += Border_MouseLeftButtonDown;
            }

            _browser.LoadCompleted += Browser_LoadCompleted;

        }




        void ParseViewportMeta()
        {
            string metaScript = "(function() { return document.querySelector('meta[name=viewport]').content; })()";

            try
            {
                string metaContent = _browser.InvokeScript("eval", new string[] { metaScript }) as string;
                string[] arr = metaContent.Split(new[] { ' ', ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
                Dictionary<string, string> metaDictionary = new Dictionary<string, string>();
                foreach (string val in arr)
                {
                    string[] keyVal = val.Split('=');
                    metaDictionary.Add(keyVal[0], keyVal[1]);
                }

                this.userScalable = false; // reset to default
                if (metaDictionary.ContainsKey("user-scalable"))
                {
                    this.userScalable = metaDictionary["user-scalable"] == "yes";
                }

                this.maxScale = 2.0;// reset to default
                if (metaDictionary.ContainsKey("maximum-scale"))
                {
                    this.maxScale = double.Parse(metaDictionary["maximum-scale"]);
                }

                this.minScale = 0.5;// reset to default
                if (metaDictionary.ContainsKey("minimum-scale"))
                {
                    this.minScale = double.Parse(metaDictionary["minimum-scale"]);
                }
            }
            catch (Exception)
            {

            }
        }

        void Browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            ParseViewportMeta();

            try
            {
                _browser.InvokeScript("execScript", MinifiedMouseScript);
            }
            catch (Exception)
            {
                Debug.WriteLine("BrowserHelper Failed to install mouse script in WebBrowser");
            }
        }

        bool InvokeSimulatedMouseEvent(string eventName, Point pos)
        {
            bool bCancelled = false;
            try
            {
                string strCancelled = _browser.InvokeScript("onNativeMouseEvent", new string[] { eventName, pos.X.ToString(), pos.Y.ToString() }) as string;
                if (bool.TryParse(strCancelled, out bCancelled))
                {
                    return bCancelled;
                }
            }
            catch (Exception)
            {
                // script error
            }

            return bCancelled;
        }

        #region Hold

        void Border_Hold(object sender, GestureEventArgs e)
        {
            //Debug.WriteLine("Border_Hold");
            e.Handled = true;
        }

        #endregion

        #region DoubleTap

        void Border_DoubleTap(object sender, GestureEventArgs e)
        {
            //Debug.WriteLine("Border_DoubleTap");
            e.Handled = true;
        }

        #endregion

        #region Tap

        void Border_Tap(object sender, GestureEventArgs e)
        {
            // prevents generating duplicated mouse events
            // firstMouseMove == FALSE means we already handled this situation and generated mouse events
            e.Handled = !this.firstMouseMove;
        }
        #endregion

        #region MouseEvents

        void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //Debug.WriteLine("Border_MouseLeftButtonDown");
            border.MouseMove += new MouseEventHandler(Border_MouseMove);
            border.MouseLeftButtonUp += new MouseButtonEventHandler(Border_MouseLeftButtonUp);

            this.mouseDownPos = e.GetPosition(_browser);
            // don't fire the down event until we know if this is a 'move' or not
            firstMouseMove = true;
        }
        //
        void Border_MouseMove(object sender, MouseEventArgs e)
        {
            //Debug.WriteLine("Border_MouseMove");
            Point pos = e.GetPosition(_browser);
            // only the return value from the first mouse move event should be used to determine if scrolling is prevented.
            if (firstMouseMove)
            {
                // even for simple tap there are situations where ui control generates move with some little delta value
                // we should avoid such situations allowing to browser control generate native js mousedown/up/click events
                if (Math.Abs(pos.X - mouseDownPos.X) + Math.Abs(pos.Y - mouseDownPos.Y) <= MouseMoveDeltaThreshold)
                {
                    return;
                }

                InvokeSimulatedMouseEvent("mousedown", pos);
                firstMouseMove = false;
                ScrollDisabled = InvokeSimulatedMouseEvent("mousemove", pos);
            }
            else
            {
                InvokeSimulatedMouseEvent("mousemove", pos);
            }

        }

        void Border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            //Debug.WriteLine("Border_MouseLeftButtonUp");
            border.MouseMove -= new MouseEventHandler(Border_MouseMove);
            border.MouseLeftButtonUp -= new MouseButtonEventHandler(Border_MouseLeftButtonUp);
            // if firstMouseMove is false, then we have sent our simulated mousedown, so we should also send a matching mouseup 
            if (!firstMouseMove)
            {
                Point pos = e.GetPosition(_browser);
                e.Handled = InvokeSimulatedMouseEvent("mouseup", pos);
            }
            ScrollDisabled = false;
        }


        #endregion

        #region ManipulationEvents

        void Border_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            //Debug.WriteLine("Border_ManipulationStarted");

            if (ScrollDisabled)
            {
                e.Handled = true;
                e.Complete();
            }
        }

        private void Border_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
            //Debug.WriteLine("Border_ManipulationDelta");
            // optionally suppress zoom
            if ((ScrollDisabled || !userScalable) && (e.DeltaManipulation.Scale.X != 0.0 || e.DeltaManipulation.Scale.Y != 0.0))
            {
                e.Handled = true;
                e.Complete();
            }
            // optionally suppress scrolling
            if (ScrollDisabled && (e.DeltaManipulation.Translation.X != 0.0 || e.DeltaManipulation.Translation.Y != 0.0))
            {
                e.Handled = true;
                e.Complete();
            }
        }

        private void Border_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            //Debug.WriteLine("Border_ManipulationCompleted");
            // suppress zoom
            if (!userScalable && e.FinalVelocities != null)
            {
                if (e.FinalVelocities.ExpansionVelocity.X != 0.0 ||
                   e.FinalVelocities.ExpansionVelocity.Y != 0.0)
                {
                    e.Handled = true;
                }
            }
        }


        #endregion

    }
}
