var canvas = d3.select("#map-grid-svg");

var width = canvas.node().getBoundingClientRect().width;
var height = canvas.node().getBoundingClientRect().height;
var minimum = Math.min(width, height);
var offset = 10;
var padding = 15;

var data_extents = {left: 0, top: 0, right: 0, bottom: 0, horizontal: 0, vertical: 0, width: 0, height: 0};
var bottom_most = {x: 0, y: 0};
var hit_limits = {left: 0, right: 0};

for (var i = 0; i < blocks.length; i++) {
    if (data_extents.left == 0 || blocks[i].c[0] < data_extents.left) data_extents.left = blocks[i].c[0];
    if (data_extents.top == 0 || blocks[i].c[1] > data_extents.top) data_extents.top = blocks[i].c[1];
    if (data_extents.right == 0 || blocks[i].c[2] > data_extents.right) data_extents.right = blocks[i].c[2];
    if (data_extents.bottom == 0 || blocks[i].c[3] < data_extents.bottom) data_extents.bottom = blocks[i].c[3];
    if ((bottom_most.x == 0 && bottom_most.y == 0) || (bottom_most.y > Math.min(blocks[i].c[1], blocks[i].c[3])) || (bottom_most.y == Math.min(blocks[i].c[1], blocks[i].c[3]) && bottom_most.x < Math.min(blocks[i].c[0], blocks[i].c[2]))) {
        bottom_most.y = Math.min(blocks[i].c[1], blocks[i].c[3]);
        bottom_most.x = Math.max(blocks[i].c[0], blocks[i].c[2]);
    }
}
data_extents.width = data_extents.right - data_extents.left;
data_extents.height = data_extents.bottom - data_extents.top;
data_extents.vertical = data_extents.width/2 + data_extents.left;
data_extents.horizontal = data_extents.height/2 + data_extents.top;

var scale = Math.max(data_extents.width*1.1/width, data_extents.height*1.1/height);

//Frame GPS limits
var frame_x1 = (data_extents.vertical - ((width/2)*scale))*1000000;
var frame_y1 = (data_extents.horizontal + ((height/2)*scale))*1000000;
var frame_x2 = (data_extents.vertical + ((width/2)*scale))*1000000;
var frame_y2 = (data_extents.horizontal - ((height/2)*scale))*1000000;

var linesx = [];
var linesy = [];

var xscale = d3.scaleLinear()
.domain([frame_x1, frame_x2])
.range([padding,(width - padding)]);

var yscale = d3.scaleLinear()
.domain([frame_y1, frame_y2])
.range([padding,(height - padding)]);

var cscale1 = d3.scaleLinear()
.domain([120, 225])
.range(["#1a93ce","#d6f1ff"]);

var cscale1 = d3.scaleLinear()
.domain([225, 330])
.range(["#f9dfae","#ffa600"]);

var cscale = {
    0: "#953631",
    10: "#9b4235",
    20: "#a14f39",
    30: "#a75b3d",
    40: "#ad6841",

    50: "#b47545",
    60: "#ba8045",
    70: "#c08b45",
    80: "#c69645",
    90: "#cca145",

    100: "#d1ad74",
    110: "#d5b67f",
    120: "#dabf8a",
    130: "#dfc895",
    140: "#e4d0a0",

    150: "#e9d9ab",
    160: "#ede0bc",
    170: "#f1eecd",
    180: "#f6f5de",
    190: "#fafcef",

    200: "#ffffff",

    210: "#e8f9ff",
    220: "#d2f3ff",
    230: "#bcecfe",
    240: "#a6e6fe",
    250: "#90e0fe",

    260: "#87d6fe",
    270: "#7eccfe",
    280: "#74c2fd",
    290: "#6bb8fd",
    300: "#61aefd",

    310: "#5ba1fc",
    320: "#5594fa",
    330: "#4f87f8",
    340: "#497af6",
    350: "#436df4",

    360: "#3d60ef",
    370: "#3854e9",
    380: "#3248e3",
    390: "#2d3cdd",
    400: "#2730d7",

    410: "#2727cd",
    420: "#271dc3",
    430: "#2614b9",
    440: "#260aaf",
    450: "#2600a5",
}

//Grid lines
//Get start point
var start = Math.round(Math.min(frame_x1,frame_x2)/1000);
var finish = Math.round(Math.max(frame_x1,frame_x2)/1000);
for (var i = start; i < finish; i++) {
    var stroke_width = "1px";
    if (i%2 == 0) stroke_width = "2px";
    linesx[i] = canvas.append("line")
    .attr("x1", xscale(i*1000))
    .attr("y1", offset)
    .attr("x2", xscale(i*1000))
    .attr("y2", (height - offset))
    .attr("stroke", "#26fff720")
    .attr("stroke-width", stroke_width);
}

var start = Math.round(Math.min(frame_y1,frame_y2)/1000);
var finish = Math.round(Math.max(frame_y1,frame_y2)/1000);
for (var i = start; i < finish; i++) {
    var stroke_width = "1px";
    if (i%2 == 0) stroke_width = "2px";
    linesy[i] = canvas.append("line")
    .attr("x1", offset)
    .attr("y1", yscale(i*1000))
    .attr("x2", (width - offset))
    .attr("y2", yscale(i*1000))
    .attr("stroke", "#26fff720")
    .attr("stroke-width", stroke_width);
}

var start = Math.round(Math.min(frame_x1,frame_x2)/100);
var finish = Math.round( Math.max(frame_x1,frame_x2)/100);
for (var i = start; i < finish; i++) {
    //Stroke
    var stroke_width = "1px";
    //Length
    var length = 10;
    if (i%10 == 0) length = 20;
    else if (i%5 == 0) length = 15;
    //Draw
    //Side 1
    linesx[i] = canvas.append("line")
    .attr("x1", xscale(i*100))
    .attr("y1", offset)
    .attr("x2", xscale(i*100))
    .attr("y2", offset + length)
    .attr("stroke", "#ffffff60")
    .attr("stroke-width", stroke_width);
    //Side 2
    linesx[i] = canvas.append("line")
    .attr("x1", xscale(i*100))
    .attr("y1", (height - (offset + length)))
    .attr("x2", xscale(i*100))
    .attr("y2", (height - offset))
    .attr("stroke", "#ffffff60")
    .attr("stroke-width", stroke_width);
}

var start = Math.round(Math.min(frame_y1,frame_y2)/100);
var finish = Math.round(Math.max(frame_y1,frame_y2)/100);
for (var i = start; i < finish; i++) {
    //Stroke
    var stroke_width = "1px";
    //Length
    var length = 10;
    if (i%10 == 0) length = 20;
    else if (i%5 == 0) length = 15;
    //Draw
    //Side 1
    linesy[i] = canvas.append("line")
    .attr("x1", offset)
    .attr("y1", yscale(i*100))
    .attr("x2", offset + length)
    .attr("y2", yscale(i*100))
    .attr("stroke", "#ffffff60")
    .attr("stroke-width", stroke_width);
    //Side 2
    linesy[i] = canvas.append("line")
    .attr("x1", (width - (offset + length)))
    .attr("y1", yscale(i*100))
    .attr("x2", (width - offset))
    .attr("y2", yscale(i*100))
    .attr("stroke", "#ffffff60")
    .attr("stroke-width", stroke_width);
}


var d_blocks = [];

var data_blocks = canvas.selectAll("data_blocks")
    .data(blocks)
    .enter()
    .append("rect");

var blockAttributes = data_blocks
    .attr("x", function (d) { return Math.min(xscale(d.c[0]*1000000), xscale(d.c[2]*1000000)); })
    .attr("y", function (d) { return Math.min(yscale(d.c[1]*1000000), yscale(d.c[3]*1000000)); })
    .attr("width", function (d) { return (Math.max(xscale(d.c[0]*1000000), xscale(d.c[2]*1000000)) - Math.min(xscale(d.c[0]*1000000), xscale(d.c[2]*1000000))); })
    .attr("height", function (d) { return (Math.max(yscale(d.c[1]*1000000), yscale(d.c[3]*1000000)) - Math.min(yscale(d.c[1]*1000000), yscale(d.c[3]*1000000))); })
    .style("stroke", function(d) { return "#000a"; })
    .style("stroke-width", function(d) { return "1px"; })
    .style("fill", function(d) { return cscale[d.f]; });

var x = xscale(bottom_most.x*1000000);
var y = yscale(bottom_most.y*1000000) - 2;

var deg_per_pixel = (frame_x2 - frame_x1)/width;    //displacement per pixel
var m_per_pix = deg_per_pixel*0.111600;             //Was 2.311;
var row_width = 1.00;                               //Row wsidth
var rows = 4;                                       //Number of rows
var impl_width = row_width*rows;                    //Total implement width
var speed_t = 10;                                   //km/h
var speed = speed_t/m_per_pix;                      //km/h
var speed_s = speed*1000/3600;
var direction = 0;                  //0:left, 1:right
var turn_phase = 0;                  //0:left, 1:right
var angle = 180;                     //Right is 0 degrees counterclockwise around
var turn_angle = 2.2*speed_t/impl_width;
var default_actual_rate = 400;

var eng_target = 0;
var eng_actual = 0;

var logCounter = 0;

var marker = canvas.append("svg:path")
        .attr("class", "ai-marker")
        .attr("d", "M0,0l-8.8-17.7C-12.1-24.3-7.4-32,0-32h0c7.4,0,12.1,7.7,8.8,14.3L0,0z")
        .attr("transform", "translate(" + x + "," + y + ")");

var number = canvas.append("text")
        .text("1")
        .attr("x", x )
        .attr("y", y )
        .attr("font-family", "Courier" )
        .attr("font-weight", "bold" )
        .attr("font-size", "14px")
        .attr("transform", "translate(" + -5 + "," + -17 + ")")
        .attr("fill", "#fff");

var updateMarkerOff = function()
{
    speed_t = 0;                          //km/h
    speed = 0;          //km/h
    speed_s = 0;

    //Update position
    x += Math.cos(angle/180*Math.PI)*speed_s/10;
    y -= Math.sin(angle/180*Math.PI)*speed_s/10;

    //Update marker
    marker.attr("transform", "translate(" + x + "," + y + ")");
    number.attr("x", x )
    .attr("y", y );
}

var updateMarkerPosition = function()
{
    //Execute turn
    if (speed_t < 7) {
        speed_t += 2;                       //km/h
        speed = speed_t/m_per_pix;          //km/h
        speed_s = speed*1000/3600;
    }

    if (turn_phase == 0) {
        FCUpdateEngage(1);
    } else if (turn_phase == 1) {
        speed_t--;                          //km/h
        speed = speed_t/m_per_pix;          //km/h
        speed_s = speed*1000/3600;
        if (speed_t == 7) {
            turn_phase++;
        }
        FCUpdateEngage(0);
    } else if (turn_phase == 2) {
        if (direction == 0) {
            if (angle < 180) angle += turn_angle;
            else {
                angle = 180;
                turn_phase++;
            }
        } else {
            if (angle > 0) angle -= turn_angle; 
            else {
                angle = 0;
                turn_phase++;
            }
        }
        FCUpdateEngage(0);
    } else if (turn_phase == 3) {
        speed_t++;                          //km/h
        speed = speed_t/m_per_pix;          //km/h
        speed_s = speed*1000/3600;
        if (speed_t >= 10) {
            calculateLimits();
            turn_phase = 0;
        }
        FCUpdateEngage(0);
    } else if (turn_phase == 4) {
        //Run until specific point
        if (x > xscale(data_extents.right*1000000)) {
            turn_phase++;
        }
        FCUpdateEngage(0);
    } else if (turn_phase == 5) {
        if (angle > -90) angle -= turn_angle;
        else {
            turn_phase++;
            angle = -90;
        }
        FCUpdateEngage(0);
    } else if (turn_phase == 6) {
        if (y > yscale(data_extents.bottom*1000000)) {
            turn_phase++;
        }
        FCUpdateEngage(0);
    } else if (turn_phase == 7) {
        if (angle > -180) angle -= turn_angle;
        else {
            turn_phase++;
            angle = 180;
            direction = 0;
        }
        FCUpdateEngage(0);
    } else if (turn_phase == 8) {
        if (x < xscale(bottom_most.x*1000000)) {
            turn_phase = 0;
            calculateLimits();
        }
        FCUpdateEngage(0);
    }

    //Check for turn
    if (turn_phase == 0) {
        if (y < yscale(data_extents.top*1000000)) {
            if (direction == 0) {
                turn_phase++;
            } else {
                turn_phase = 4;
            }
        } else {
            if (direction == 0) {
                if (check_left_limit() == 0) {
                    turn_phase++;
                    direction = 1;
                }
            } else {
                if (check_right_limit() == 0) {
                    turn_phase++;
                    direction = 0;
                }
            }
        }
    }

    /*if (check_left_limit() == 1 && check_right_limit() == 1) {
        eng_target = 1;
    } else {
        eng_target = 0;
    }*/

    //Update position
    x += Math.cos(angle/180*Math.PI)*speed_s/10;
    y -= Math.sin(angle/180*Math.PI)*speed_s/10;

    //Update marker
    marker.attr("transform", "translate(" + x + "," + y + ")");
    number.attr("x", x )
    .attr("y", y );

    //Logging simulater
    if (logCounter >= 50) {
        logCounter = 0;
        var lat = yscale.invert(y)/10000.0;
        var min = lat % 100;
    
        lat -= min;
        var min = (min/100.0*60.0);
        lat += min;
        
        lat*= 10000;

        var lon = xscale.invert(x)/10000.0;
        var min = lon % 100;
    
        lon -= min;
        var min = (min/100.0*60.0);
        lon += min;
        
        lon*= 10000;
        //logData(lat, lon, speed_t, rows, row_width, GetApp());
    }
    logCounter++;
}

var GetApp = function()
{
    var app = 0;

    for (var i = 0; i < blocks.length; i++) {
        var y_t = Math.max(blocks[i].c[1]*1000000, blocks[i].c[3]*1000000);
        var y_b = Math.min(blocks[i].c[1]*1000000, blocks[i].c[3]*1000000);
        if (y < yscale(y_b) && y > yscale(y_t)) {
            var x_l = Math.min(blocks[i].c[0]*1000000, blocks[i].c[2]*1000000);
            var x_r = Math.max(blocks[i].c[0]*1000000, blocks[i].c[2]*1000000);
            if (x > xscale(x_l) && x < xscale(x_r)) {
                app = blocks[i].f;
                break;
            }
        }
    }

    return app;
}

var updateBigRad = function()
{
    angle += 0.5;
    if (angle > 360) angle = 0;
    if (angle < 0) angle = 360;
    speed_t = 10;                          //km/h
    speed = speed_t/m_per_pix;          //km/h
    speed_s = speed*1000/3600;
    //Execute turn

    eng_target = 1;

    //Update position
    x += Math.cos(angle/180*Math.PI)*speed_s/10;
    y -= Math.sin(angle/180*Math.PI)*speed_s/10;

    //Update marker
    marker.attr("transform", "translate(" + x + "," + y + ")");
    number.attr("x", x )
    .attr("y", y );
}

var updateSmallRad = function()
{
    angle += 6.5;
    if (angle > 360) angle = 0;
    if (angle < 0) angle = 360;
    speed_t = 8;                          //km/h
    speed = speed_t/m_per_pix;          //km/h
    speed_s = speed*1000/3600;
    //Execute turn

    eng_target = 1;

    //Update position
    x += Math.cos(angle/180*Math.PI)*speed_s/10;
    y -= Math.sin(angle/180*Math.PI)*speed_s/10;

    //Update marker
    marker.attr("transform", "translate(" + x + "," + y + ")");
    number.attr("x", x )
    .attr("y", y );
}

//Frame limits

var xl_1 = xscale(29115850);
var yl_1 = yscale(data_extents.top*1000000);
var xl_2 = xscale(29117226);
var yl_2 = yscale(-26303948);
var xl_3 = xscale(29115963);
var yl_3 = yscale(-26305886);
var xl_4 = xscale(29117395);
var yl_4 = yscale(-26306880);

var check_left_limit = function()
{
    if (x < xscale(hit_limits.left)) return 0; else return 1;
    /*var topmost = Math.min(yl_1, yl_2);
    var topmid = Math.max(yl_1, yl_2);
    var bottommid = Math.min(yl_3, yl_4);
    var bottommost = Math.max(yl_3, yl_4);

    if (y < topmost) {
        //Above topmost point
        return 0;
    } else if (y < topmid) {
        //Top section
    var x_limit = (y - yl_1)/(yl_2 - yl_1)*(xl_2 - xl_1) + xl_1;
    if (x < x_limit) return 0;
    else return 1;
    } else if (y < bottommid) {
        //Mid section
    var x_limit = (y - yl_1)/(yl_3 - yl_1)*(xl_3 - xl_1) + xl_1;
    if (x < x_limit) return 0;
    else return 1;
    } else if (y < bottommost) {
        //Bottom section
    var x_limit = (y - yl_3)/(yl_4 - yl_3)*(xl_4 - xl_3) + xl_3;
    if (x < x_limit) return 0;
    else return 1;
    } else {
        //Below bottommost point
        return 0;
    }*/
}

var calculateLimits = function()
{
    hit_limits.left = 0;
    hit_limits.right = 0;

    for (var i = 0; i < blocks.length; i++) {
        var ytop = yscale(Math.max(blocks[i].c[1]*1000000, blocks[i].c[3]*1000000));
        var ybottom = yscale(Math.min(blocks[i].c[1]*1000000, blocks[i].c[3]*1000000));
        if (y > ytop && y < ybottom) {
            var xleft = Math.min(blocks[i].c[0]*1000000, blocks[i].c[2]*1000000);
            var xright = Math.max(blocks[i].c[0]*1000000, blocks[i].c[2]*1000000);
            if (hit_limits.left == 0 || hit_limits.left > xleft) {
                hit_limits.left = xleft;
            }
            if (hit_limits.right == 0 || hit_limits.right < xright) {
                hit_limits.right = xright;
            }
        }
    }
}

calculateLimits();

var check_right_limit = function()
{
    if (x > xscale(hit_limits.right)) return 0; else return 1;
    /*var topmost = Math.min(yl_1, yl_2);
    var topmid = Math.max(yl_1, yl_2);
    var bottommid = Math.min(yl_3, yl_4);
    var bottommost = Math.max(yl_3, yl_4);

    if (y < topmost) {
        //Above topmost point
        return 0;
    } else if (y < topmid) {
        //Top section
    var x_limit = (y - yl_1)/(yl_2 - yl_1)*(xl_2 - xl_1) + xl_1;
    if (x > x_limit) return 0;
    else return 1;
    } else if (y < bottommost) {
        //Mid section
    var x_limit = (y - yl_2)/(yl_4 - yl_2)*(xl_4 - xl_2) + xl_4;
    if (x > x_limit) return 0;
    else return 1;
    } else if (y < bottommost) {
        //Bottom section
    var x_limit = (y - yl_3)/(yl_4 - yl_3)*(xl_4 - xl_3) + xl_3;
    if (x > x_limit) return 0;
    else return 1;
    } else {
        //Below bottommost point
        return 0;
    }*/
}

var sendGPSPortData = function()
{
    var GPSDataString = "$GNRMC,";
    //Time
    var today = new Date();
    var ss = today.getUTCSeconds();
    var mm = today.getUTCMinutes(); 
    var hh = today.getUTCHours();
    if (ss < 10) {
        ss = '0' + ss.toString();
    } else {
        ss = ss.toString();
    }
    if (mm < 10) {
        mm = '0' + mm.toString();
    } else {
        mm = mm.toString();
    } 
    if (hh < 10) {
        hh = '0' + hh.toString();
    }  else {
        hh = hh.toString();
    }
    var time = hh + mm + ss;
    GPSDataString += time + '.000,';
    
    //Status
    GPSDataString += 'A,';

    //Lattitude
    var lat = yscale.invert(y)/10000.0;
    var min = lat % 100;
    var out_y = (0xFFFFFFFF - (-1*Math.floor(parseFloat(lat)*10000)));

    lat -= min;
    var min = (min/100.0*60.0);
    lat += min;
    var lat_d = 'N';
    if (lat < 0) {
        lat_d = 'S';
        lat *= -1;
    }

    if (lat < 10) {
        lat = '000' + lat.toFixed(4);
    } else if (lat < 100) {
        lat = '00' + lat.toFixed(4);
    } else if (lat < 1000) {
        lat = '0' + lat.toFixed(4);
    } else {
        lat = lat.toFixed(4);
    }
    GPSDataString += lat + ',' + lat_d + ',';

    //Longitude
    var lon = xscale.invert(x)/10000.0;
    var min = lon % 100;
    var out_x = Math.floor(parseFloat(lon)*10000);

    lon -= min;
    var min = (min/100.0*60.0);
    lon += min;

    var lon_d = 'E'
    if (lon < 0) {
        lon_d = 'W';
        lon *= -1;
    }

    if (lon < 10) {
        lon = '0000' + lon.toFixed(4);
    } else if (lon < 100) {
        lon = '000' + lon.toFixed(4);
    } else if (lon < 1000) {
        lon = '00' + lon.toFixed(4);
    } else if (lon < 10000) {
        lon = '0' + lon.toFixed(4);
    } else {
        lon = lon.toFixed(4);
    }
    GPSDataString += lon + ',' + lon_d + ',';

    //Speed
    var spd = Math.round(speed_t/1.852,1);
    if (spd < 10) {
        spd = '00' + spd.toFixed(1);
    } else if (spd < 100) {
        spd = '0' + spd.toFixed(1);
    } else {
        spd = spd.toFixed(1);
    }
    GPSDataString += spd + ',';

    //Course
    var top = (90 - angle);
    if (top < 0) top += 360;
    if (top > 360) top -= 360;

    var ang = Math.round(top,1);
    if (ang < 0) ang += 360;
    if (ang < 10) {
        ang = '00' + ang.toFixed(1);
    } else if (ang < 100) {
        ang = '0' + ang.toFixed(1);
    } else {
        ang = ang.toFixed(1);
    }
    GPSDataString += ang + ',';

    //Date
    var today = new Date();
    var dd = today.getUTCDate();
    var mm = today.getUTCMonth() + 1; 
    var yy = (today.getUTCFullYear()%100).toString();

    if (dd < 10) {
        dd = '0' + dd.toString();
    }  else {
        dd = dd.toString();
    }

    if (mm < 10) {
        mm = '0' + mm.toString();
    } else {
        mm = mm.toString();
    }
    var date = dd + mm + yy;
    GPSDataString += date + ',';

    //Space
    GPSDataString += ',,D*';

    //Checksum
    var check = 0;
    for (var i = 0; i < GPSDataString.length; i++) {
        check = ((check&0xFF) ^ (GPSDataString.charCodeAt(i)&0xFF));
    }

    var char = '0123456789ABCDEF';
    var chk1 = Math.floor(check/16%16);
    var chk2 = check%16;
    GPSDataString += char.charAt(chk1);
    GPSDataString += char.charAt(chk2);
    GPSDataString += String.fromCharCode(13);
    GPSDataString += String.fromCharCode(10);

    //Send data
    ipcRenderer.send('gps-message', GPSDataString);
}

var dec_to_string = function(dec)
{
    if (dec >= 0 && dec <= 9) {
        return String.fromCharCode(0x30 + dec);
    }
}

var get_digit = function(dec, digit)
{
    if (dec < 0) dec *= -1;
    return Math.floor(dec / Math.pow(10,digit))%10;
}

var logData = function(latitude, longitude, speed, rows, row_Width, app_rate)
{
    var random_app = Math.round(app_rate + (Math.random()*40 - 20), 1);

    var data = ":{" + dec_to_string(get_digit(random_app, 2)) + dec_to_string(get_digit(random_app, 1)) + dec_to_string(get_digit(random_app, 0));
    data += ",01,PLANTER000,";
    data += dec_to_string(get_digit(rows, 1)) + dec_to_string(get_digit(rows, 0)) + ",";
    data += dec_to_string(get_digit(row_Width, 0)) + "." + dec_to_string(get_digit(row_Width, -1)) + dec_to_string(get_digit(row_Width, -2));
    data += ",PL,5000100,125,0680,DEFAULT000,STANDARD00,026,3900,1646,016,000,000,009,007,";
    data += dec_to_string(get_digit(speed, 2)) + dec_to_string(get_digit(speed, 1)) + dec_to_string(get_digit(speed, 0));
    data += ",295,800,16161616160000000000000000000000000000000000000000000000000000000000000000000000,AA,191014131149,";
    data += dec_to_string(get_digit(angle, 2)) + dec_to_string(get_digit(angle, 1)) + dec_to_string(get_digit(angle, 0)) + "0,";
    data += dec_to_string(get_digit(latitude, 7)) + dec_to_string(get_digit(latitude, 6)) + dec_to_string(get_digit(latitude, 5)) + dec_to_string(get_digit(latitude, 4)) + dec_to_string(get_digit(latitude, 3)) + dec_to_string(get_digit(latitude, 2)) + dec_to_string(get_digit(latitude, 1)) + dec_to_string(get_digit(latitude, 0));
    if (latitude < 0) data += "S"; else data += "N";
    data += "," + dec_to_string(get_digit(longitude, 8)) + dec_to_string(get_digit(longitude, 7)) + dec_to_string(get_digit(longitude, 6)) + dec_to_string(get_digit(longitude, 5)) + dec_to_string(get_digit(longitude, 4)) + dec_to_string(get_digit(longitude, 3)) + dec_to_string(get_digit(longitude, 2)) + dec_to_string(get_digit(longitude, 1)) + dec_to_string(get_digit(longitude, 0));
    if (longitude < 0) data += "W"; else data += "E";
    data += "}\n";
    document.getElementById("prec-logs").value += data;
}

setInterval(function() {
    if (document.getElementById("prec-sel-off").className == "ai-cell ai-cell-warning") {
        updateMarkerOff();
    } else if (document.getElementById("prec-sel-row").className == "ai-cell ai-cell-warning") {
        updateMarkerPosition();
    } else if (document.getElementById("prec-sel-big-rad").className == "ai-cell ai-cell-warning") {
        updateBigRad();
    } else if (document.getElementById("prec-sel-small-rad").className == "ai-cell ai-cell-warning") {
        updateSmallRad();
    }
}, 30);

setInterval(function() {
    if (document.getElementById("prec-out-output").className == "ai-cell ai-cell-warning") {
        sendGPSPortData();
    }
}, 250);