
var DisableEmscripten = false;
var algorithmsVersion = 2;

var application = new Application(document, window);

var waitCounter = false;
var fullscreen  = false;
var userAction = function(str)
{
    if (typeof window.yaCounter25827098 !== "undefined")
    {
        console.log(g_language + "/" + str);
        window.yaCounter25827098.hit(window.location.protocol + "//" + window.location.hostname + (g_language != "ru" ? "/" + g_language : "") + "/UserAction#" + str);
    }
    else if (!waitCounter)
    {
        waitCounter = true;
        setTimeout(function()
                   {
                     userAction(str);
                   }, 2000);
    }
}

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 
           || navigator.userAgent.toLowerCase().indexOf("trident") != -1);

var buttonsList = ['AddGraph', 'ConnectGraphs', 'DeleteObject', 'Default'];
var g_ctrlPressed = false;

function restButtons (me)
{
    var needSetDefault = false;
	for (let i = 0; i < buttonsList.length; i ++)
	{
		if (buttonsList[i] != me)
		{
			document.getElementById(buttonsList[i]).className = "btn btn-default btn-sm";
		}
		else
		{
			if (document.getElementById(buttonsList[i]).className != "btn btn-default btn-sm")
			{
				needSetDefault = true;	
			}
		}
	}
	if (needSetDefault)
	{
		document.getElementById(me).className = "btn btn-primary btn-sm";
	}
	else
	{
		document.getElementById(me).className = "btn btn-primary btn-sm";
	}
}

var single = 0;

function resizeCanvas()
{
  var adv = document.getElementById('bottom_info');
  var canvas    = document.getElementById('canvas');
  canvas.width  = document.getElementById('canvasSection').offsetWidth;
  var mainContainer = document.getElementById('mainContainer');
  var offset = (mainContainer.offsetTop + mainContainer.offsetHeight) - (canvas.offsetTop + canvas.offsetHeight) + ($("#footerContent").css("display") === 'block' ? 0 : 24);
        
  canvas.height = $(window).height() - document.getElementById('canvas').offsetTop - (adv && $("#bottom_info").css("display") === 'block' ? document.getElementById('bottom_info').offsetHeight : 0) - ($("#footer").css("display") === 'block' ? document.getElementById('footer').offsetHeight : 0) - offset;

  application.redrawGraph();
}

function touchHandler(event)
{
    var touches = event.changedTouches,
        first = touches[0],
        type = "";
    switch(event.type)
    {
        case "touchstart": type = "mousedown"; break;
        case "touchmove":  type="mousemove"; break;        
        case "touchend":   type="mouseup"; break;
        default: return;
    }

    var simulatedEvent = document.createEvent("MouseEvent");
    simulatedEvent.initMouseEvent(type, true, true, window, 1, 
                              first.screenX, first.screenY, 
                              first.clientX, first.clientY, false, 
                              false, false, false, 0/*left*/, null);

	first.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function preLoadPage()
{
	loadTexts();
	application.onLoad();
}

function createAlgorithmMenu()
{
    var algorithmBaseId = "Algo";
    var algorithms = application.getAlgorithmNames();
    var index = 0;

    for (var i = 0; i < algorithms.length; i++)
    {
        algorithm = algorithms[i];
        
        var list   = document.getElementById("algorithmCategoryElements" + algorithm.category);
        var item   = document.getElementById("algTopic" + algorithm.category);
        var clone  = item.cloneNode(true);
        var button   = clone.getElementsByTagName("button")[0];
        var textSpan = button.getElementsByTagName("span")[1];
        button.id = algorithm.id;
        textSpan.innerHTML = algorithm.name;
        clone.style.display = "block";
        
        buttonsList.push(algorithm.id);
        
        button.onclick = function (e)
        {
            e["closeThisMenu"] = true;
            userAction(this.id);
            restButtons (this.id);
            application.SetHandlerMode(this.id);
        }
        
        var eventData = {};
        eventData.index     = i;
        eventData.object    = clone;
        eventData.algorithm = algorithm;
        
        $("#openAlgorithmList").bind('click', eventData, function (_eventData) {
            var data      = _eventData.data;
            var algorithm = g_Algorithms[g_AlgorithmIds.indexOf(data.algorithm.id)](application.graph, application);
            
            if (application.graph.isMulti() && !algorithm.IsSupportMultiGraph())
              $(data.object).hide();
            else
              $(data.object).show();
          });
        
        list.insertBefore(clone, document.getElementById("insert" + algorithm.category));
        index++;
    }

}

    
function handelImportGraph(files) {
    var graphFileToLoad = files[0];

    var fileReader = new FileReader();
    fileReader.onload = function(fileLoadedEvent){
        var textFromFileLoaded = fileLoadedEvent.target.result;
        console.log(textFromFileLoaded);
        application.LoadGraphFromString(textFromFileLoaded);
        ImportGraphFiles.value = "";
    };

    fileReader.readAsText(graphFileToLoad, "UTF-8");
}

function postLoadPage()
{
    application.userAction = userAction;
    
	application.canvas.onmousemove = function (e)
		{
			return application.CanvasOnMouseMove(e);
		};

	application.canvas.onmousedown = function (e)
		{
			return application.CanvasOnMouseDown(e);
		};
		
	application.canvas.onmouseup   = function (e)
		{
			return application.CanvasOnMouseUp(e);
		}
    
    application.canvas.onwheel = function (e)
    {
        var e = window.event || e; // old IE support
        var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
        if (delta > 0)
        {
            application.multCanvasScale(1.3, e);
        }
        else
        {
            application.multCanvasScale(1.0 / 1.3, e);
        }
    }
    
    function getCharCode(event) {
      if (event.which == null) { // IE
        return event.keyCode;
      }

      if (event.which != 0 && event.charCode != 0) { // все кроме IE
        return event.which; // остальные
      }

      return null; // спец. символ
    }
    
    function getChar(event) {
        return String.fromCharCode(getCharCode(event)); // остальные
    }
    
    function selectHandler(buttonName, handlerName)
    {
            userAction(buttonName + "_shortcut");
			restButtons (buttonName);
			application.SetHandlerMode(handlerName);  
    }
    
    document.onkeypress   = function (e)
    {
        if (event.defaultPrevented
            || ($('#addVertex').hasClass('ui-dialog-content') && $('#addVertex').dialog('isOpen'))
            || ($('#adjacencyMatrix').hasClass('ui-dialog-content') && $('#adjacencyMatrix').dialog('isOpen'))
            || ($('#addEdge').hasClass('ui-dialog-content') && $('#addEdge').dialog('isOpen'))
            || ($('#incidenceMatrix').hasClass('ui-dialog-content') && $('#incidenceMatrix').dialog('isOpen'))
            || ($('#saveDialog').hasClass('ui-dialog-content') && $('#saveDialog').dialog('isOpen'))
            || ($('#saveImageDialog').hasClass('ui-dialog-content') && $('#saveImageDialog').dialog('isOpen'))
            || ($('#GroupRenameDialog').hasClass('ui-dialog-content') && $('#GroupRenameDialog').dialog('isOpen'))
            || $('#developerTools').css("display") != "none"
            || ($('#NeedAlgorithm').hasClass('ui-dialog-content') && $('#NeedAlgorithm').dialog('isOpen')))
        {
            console.log("prevent");
            return; // Should do nothing if the default action has been cancelled
        }
        
        
        var key = getChar(event);
        var code = getCharCode(event);
        console.log(key + " code=" + code);
        var evtobj = window.event ? event : e;
        var isCtrl = evtobj ? evtobj.ctrlKey : false;
        
        var moveValue = 10;
        if (code == 61 || code == 43) // +
        {
            application.multCanvasScale(1.5);
        }
        else if (code == 45) // -
        {
            application.multCanvasScale(1 / 1.5);
        }
        else if (key == 'w' || key == 'ц') // up
        {
            application.onCanvasMove(new Point(0, moveValue));
        }
        else if (key == 's' || key == 'ы') // down
        {
            application.onCanvasMove(new Point(0, -moveValue));
        }
        else if (key == 'a' || key == 'ф') // left
        {
            application.onCanvasMove(new Point(moveValue, 0));
        }
        else if (key == 'd' || key == 'в') // right
        {
            application.onCanvasMove(new Point(-moveValue, 0));
        }
        else if (key == 'v' || key == 'м') // vertex
        {
            selectHandler('AddGraph', 'addGraph');
        }
        else if (key == 'e' || key == 'у') // edge
        {
            selectHandler('ConnectGraphs', 'addArc');
        }
        else if (key == 'r' || key == 'к') // delete
        {
            selectHandler('DeleteObject', 'delete');
        }
        // Disabled because it is easy to lose graph, when you press miss letter.
        //else if (key == 'n' || key == 'т') // new
        //{
        //    userAction('NewGraph_shortcut');
		//	application.SetHandlerMode("deleteAll");
        //    application.SetDefaultTransformations();
        //}
        else if (key == 'm' || key == 'ь') // move
        {
            selectHandler('Default', 'default');
        }
        else if (code == 26 && isCtrl)
        {
            userAction("Key_GraphUndo");
            application.SetHandlerMode("graphUndo");        
        }
    }
 
    $(document).keydown(function(event) {
        if (event.which == "17" || event.which == "91")
          g_ctrlPressed = true;
    });

    $(document).keyup(function() {
      g_ctrlPressed = false;
    });

	document.getElementById('ShowAdjacencyMatrix').onclick = function ()
		{
            userAction(this.id);
			application.SetHandlerMode("showAdjacencyMatrix");
		}		
	document.getElementById('ShowIncidenceMatrix').onclick = function ()
		{
            userAction(this.id);
			application.SetHandlerMode("showIncidenceMatrix");
		}
	document.getElementById('ShowDistanceMatrix').onclick = function ()
		{
            userAction(this.id);
			application.SetHandlerMode("showDistanceMatrix");
		}
    
	document.getElementById('GroupRename').onclick = function ()
		{
            userAction(this.id);
			application.SetHandlerMode("GroupRename");
		}
	document.getElementById('groupRenameButton').onclick = function ()
		{
            userAction(this.id);
			application.SetHandlerMode("GroupRename");
		}
    
		
	document.getElementById('Default').onclick = function ()
		{
            userAction(this.id);
			restButtons ('Default');
			application.SetHandlerMode("default");
			document.getElementById('Default').className = "btn btn-primary btn-sm";			
		}		
		
	document.getElementById('AddGraph').onclick = function ()
		{
            userAction(this.id);
			restButtons ('AddGraph');
			application.SetHandlerMode(document.getElementById('AddGraph').className != "" ? "addGraph" : "default");
		}
	
	document.getElementById('ConnectGraphs').onclick = function ()
		{
            userAction(this.id);
			restButtons ('ConnectGraphs');
			application.SetHandlerMode(document.getElementById('ConnectGraphs').className != "" ? "addArc" : "default");
		}	
	
	document.getElementById('DeleteObject').onclick = function ()
		{
            userAction(this.id);
			restButtons ('DeleteObject');
			application.SetHandlerMode(document.getElementById('DeleteObject').className != "" ? "delete" : "default");
		}

	document.getElementById('DeleteAll').onclick = function ()
		{
            userAction(this.id);
			application.SetHandlerMode("deleteAll");
		}


	document.getElementById('SaveGraph').onclick = function ()
		{
            userAction(this.id);
			application.SetHandlerMode("saveDialog");
		}

	document.getElementById('NewGraph').onclick = function ()
		{
            userAction(this.id);
			application.SetHandlerMode("deleteAll");
            application.SetDefaultTransformations();
		}
    
    document.getElementById('SaveGraphImage').onclick = function ()
    {
        userAction(this.id);
        application.SetHandlerMode("saveDialogImage");
    }
    
    document.getElementById('SaveFullGraphImage').onclick = function ()
    {
        userAction(this.id);
        application.SetHandlerMode("saveDialogFullImage");
    }

    document.getElementById('SavePrintGraphImage').onclick = function ()
    {
        userAction(this.id);
        application.SetHandlerMode("savePrintGraphImage");
    }

    document.getElementById('SaveSvgGraphImage').onclick = function ()
    {
        userAction(this.id);
        application.SetHandlerMode("saveSvgGraphImage");
    }
    
    document.getElementById('Zoom100').onclick = function ()
    {
        userAction(this.id);
        application.setCanvasScale(1.0);
    }
    
    document.getElementById('Zoom50').onclick = function ()
    {
        userAction(this.id);
        application.setCanvasScale(50 / 100);
    }
    
    document.getElementById('Zoom25').onclick = function ()
    {
        userAction(this.id);
        application.setCanvasScale(25 / 100);
    }
  
    document.getElementById('ZoomFit').onclick = function ()
    {
        userAction(this.id);
        application.OnAutoAdjustViewport();
    }
    
    document.getElementById('ZoomIn').onclick = function ()
    {
        userAction(this.id);
        application.multCanvasScale(1.5);
    }
    
    document.getElementById('ZoomOut').onclick = function ()
    {
        userAction(this.id);
        application.multCanvasScale(1.0 / 1.5);
    }
    
    document.getElementById('MoveWorspace').onclick = function ()
    {
        userAction(this.id);
        restButtons ('Default');
        application.SetHandlerMode("default");
        document.getElementById('Default').className = "btn btn-primary btn-sm";
    }
    document.getElementById('SetupVertexStyle').onclick = function ()
    {
        userAction(this.id);
        application.SetHandlerMode("setupVertexStyle");
    }
    document.getElementById('SetupVertexStyleSelected').onclick = function ()
    {
        userAction(this.id);
        application.SetHandlerMode("setupVertexStyleSelected");
    }
    document.getElementById('SetupEdgeStyle').onclick = function ()
    {
        userAction(this.id);
        application.SetHandlerMode("setupEdgeStyle");
    }
    document.getElementById('SetupEdgeStyleSelected').onclick = function ()
    {
        userAction(this.id);
        application.SetHandlerMode("setupEdgeStyleSelected");
    }
    document.getElementById('SetupBackgroundStyle').onclick = function ()
    {
        userAction(this.id);
        application.SetHandlerMode("setupBackgroundStyle");
    }

    document.getElementById('GraphUndo').onclick = function ()
    {
        userAction(this.id);
        application.SetHandlerMode("graphUndo");
    }    
    
    document.getElementById('runUserScript').onclick = function ()
    {
        var el = document.getElementById('userScript');
        
        var oldScript = document.getElementById("userScriptSource");
        if (oldScript)
        {
            document.head.removeChild(oldScript);
        }
        
        var script = document.createElement('script');
        script.type = "text/javascript";
        script.innerHTML = el.value;
        script.id = "userScriptSource";
        document.head.appendChild(script);
        
        application.SetHandlerMode("user.algorithm");
    }
    
    document.getElementById('submitUserScript').onclick = function ()
    {
        var script = document.getElementById('userScript');
        var data = "message=" + script.value + "&";
    
        $.ajax({
            type: "POST",
            url: "/feedback",
            data: data
        });
        
        $( "#sentAlgorithm" ).dialog({
                                     resizable: false,
                                     height: "auto",
                                     width:  400,
                                     modal: true,
                                     dialogClass: 'EdgeDialog'
                                     });
    }
    
    document.getElementById('devToolsZoom').onclick = function ()
    {
        var devTools = document.getElementById('developerTools');
        if (devTools.hasOwnProperty("isMin") && !devTools["isMin"])
        {
            devTools["isMin"] = true;
            devTools.style.width = "30%";
        }
        else
        {
            devTools["isMin"] = false;
            devTools.style.width = "100%";
        }
    }
    
    document.getElementById('ExportGraph').onclick = function ()
    {
        userAction(this.id);
        
        var graphAsString  = application.graph.SaveToXML("");
        var savedGraphName = application.GetNewGraphName();
        
        var element = document.createElement('a');
        element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(graphAsString));
        element.setAttribute('download', "graph_" + savedGraphName + ".graphml");

        element.style.display = 'none';
        document.body.appendChild(element);

        element.click();

        document.body.removeChild(element);
    }
    
    document.getElementById('ImportGraph').onclick = function ()
    {
        userAction(this.id);
        
        if (ImportGraphFiles) {
            ImportGraphFiles.click();
        }
    }
    
    document.getElementById('openAlgorithmList').onclick = function()
    {
        // Show menu first
        setTimeout(function() 
                   {
                        var button = document.getElementById('openAlgorithmList');
                        var buttonRect = button.getBoundingClientRect();
                        var algorithmList = document.getElementById('algorithmList');
            
                        var delta = buttonRect.right - algorithmList.offsetWidth;
                        if (delta < 0)
                        {
                            var value = (delta - 4) + "px";
                            algorithmList.style.right = value;
                        }
                        else
                        {
                             algorithmList.style.right = "0";   
                        }
                   }, 1);
    }
    
    document.getElementById('Fullscreen').onclick = function()
    {
        var idList = ["h1Header", "h1Text", "navigation", "footerContent", "bottom_adv"];
        
        fullscreen = !fullscreen
        
        userAction(fullscreen ? "fullscreen_on" : "fullscreen_off");
        
        for (var i = 0; i < idList.length; i++) {
            let element = document.getElementById(idList[i]);
            if (!element) continue;

            if (fullscreen)
                element.style.display = "none";    
            else
                element.style.display = "block";
        }
                
        document.getElementById("mainContainer").className = fullscreen ? "container-fluid page-wrap" : "container page-wrap";
        
        document.getElementById("FullscreenIcon").className = fullscreen ? "glyphicon glyphicon-resize-small fa-fw" : "glyphicon glyphicon-resize-full fa-fw";

        resizeCanvas();
    }
    
    if (document.getElementById('VoteButton') !== null)
    document.getElementById('VoteButton').onclick = function ()
    {
        var dialogButtons = {};
        
        for (var i = 0; i < 6 && document.getElementById('vote' + i) !== null; i++)
        {
            document.getElementById('vote' + i)["voteIndex"] = i;
            document.getElementById('vote' + i).onclick = function ()
            {
                console.log("Vote" + this["voteIndex"]);
                $.ajax({
                type: "GET",
                url: "/" + SiteDir + "cgi-bin/vote.php?index=" + this["voteIndex"],
                dataType: "text"
                });
                $("#voteDialog").dialog('close');
                $("#VoteButton").hide();
            }
        }

        dialogButtons[g_close] = function() {
                $( this ).dialog( "close" );					
            }; 

        $( "#voteDialog" ).dialog({
            resizable: false,
            title: g_vote,
            width: 400,
            modal: true,
            dialogClass: 'EdgeDialog',
            buttons: dialogButtons,
        });
    }
    
    // Get algorithms list and load it.
    loadAsyncAlgorithms(createAlgorithmMenu);

    var devTools = document.getElementById('developerTools');
    devTools.style.left = 0;
	resizeCanvas();
	application.onPostLoadEvent();

    $(function() {
        $('#algorithmList').on('click', function(event) {
            if (!event.originalEvent.closeThisMenu) {
                event.stopPropagation();
            }
        });      
        $(window).on('click', function() {
          $('#algorithmList').slideUp();
        });      
      });    


    let showHideCategory = function(button, elementsListName){
        let width     = $( button ).width();
        let elementsList = $(elementsListName);
        var hideMark = button.querySelector('span[name="hideMark"]')
        var showMark = button.querySelector('span[name="showMark"]')
        if (elementsList.is(":visible")) {
            elementsList.hide();
            $(hideMark).show();
            $(showMark).hide();
        } else {
            elementsList.show();
            $(hideMark).hide();
            $(showMark).show();
        }            
        $( button ).width(width);

        userAction("algCategory_" + elementsListName);
    }

    $(document.getElementById("algorithmCategoryBtn1").querySelector('span[name="hideMark"]')).hide();
    $(document.getElementById("algorithmCategoryBtn0").querySelector('span[name="hideMark"]')).hide();

    $('#algorithmCategoryBtn1').click(function(){
        showHideCategory(this, "#algorithmCategoryElements1");
    });

    $('#algorithmCategoryBtn0').click(function(){
        showHideCategory(this, "#algorithmCategoryElements0");
    });
}

//window.onload = function ()
$(document).ready(function ()
{

	window.onresize = function(event) 
		{
			resizeCanvas();
		}


    document.getElementById('canvas').addEventListener("touchstart", touchHandler, true);
    document.getElementById('canvas').addEventListener("touchmove", touchHandler, true);
    document.getElementById('canvas').addEventListener("touchend", touchHandler, true);
    document.getElementById('canvas').addEventListener("touchcancel", touchHandler, true);

    // Try load emscripten implementation
    var isMobile = navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i);
    if (!isMobile && !DisableEmscripten) {
      let fullPathToGraphffoline = "features/graphoffline/Graphoffline.Emscripten.js";
      doIncludeAsync ([
    	include (fullPathToGraphffoline),
      ], () => {
        Module['onRuntimeInitialized'] = onRuntimeInitialized;
        var process = Module.cwrap('ProcessAlgorithm', 'string', ['string']);
        function onRuntimeInitialized() {
          application.setEmscripten(process);
        }
      })
    }
/*
	$(document).ready(function(){
	    //set up some basic options for the feedback_me plugin
	    fm_options = {
	        position: "left-bottom",
	        message_placeholder: g_what_do_you_think,
	        message_required: true,
	        name_label: g_name,
	        message_label: g_feedback,
	        trigger_label: g_feedback,
	        submit_label: g_send,
	        title_label: g_write_to_us,	        
	        feedback_url: "/feedback",
	    };
	    //init feedback_me plugin
	    fm.init(fm_options);
	});
*/
});

Array.prototype.swap = function (x,y) {
  var b = this[x];
  this[x] = this[y];
  this[y] = b;
  return this;
}
