﻿/*
* Embeds a layout to the page
*
* Usage:
*	myLayout = new CameraLayout(layout_type, number_of_rows, number_of_columns, display_method, layout_width, layout_height, camera_array);
*	myLayout.write("target_element_id");
*
*
*  Types of display technologies that can be used to support video
*  smActiveX = 1;
*  smServerPush = 2;
*  smClientPull = 3;
*  smThirdPartyActiveX = 4;
*/

//Supporting Variables

var vi_class_id = 'CLSID:7310E85A-BE41-439B-8920-AE334BDC7918';
var vi_codebase = 'utilities/VIClient5.CAB#Version=4,3,0,51';

var _1cam = { id:0, count: 1, rows: 1, cols: 1, ax_id: 1};        //1x1 grid
var _4cam = { id:1, count: 4, rows: 2, cols: 2, ax_id: 2};        //2x2 grid
var _8cam = { id:2, count: 8, rows: 4, cols: 4, ax_id: 3};        //1+7 grid, uneven size
var _9cam = { id:3, count: 9, rows: 3, cols: 3, ax_id: 201};      //3x3 grid
var _10cam = { id:4, count: 10, rows: 4, cols: 4, ax_id: 4};      //2+8 grid, uneven size
var _13cam = { id:5, count: 13, rows: 4, cols: 4, ax_id: 6};      //1+12 grid, uneven size centered
var _13_2cam = { id:6, count: 13, rows: 4, cols: 4, ax_id: 5};    //1+12 grid, uneven size
var _16cam = { id:7, count: 16, rows: 4, cols: 4, ax_id: 7};    //4x4 grid
var _19cam = { id:8, count: 19, rows: 5, cols: 5, ax_id: 101};      //2+17 grid, uneven size
var _25cam = { id:9, count: 25, rows: 5, cols: 5, ax_id: 102};      //5x5 grid
var _36cam = { id:10, count: 36, rows: 6, cols: 6, ax_id: 206};     //6x6 grid

var layoutTypes = [_1cam, _4cam, _8cam, _9cam, _10cam, _13cam, _13_2cam, _16cam, _19cam, _25cam, _36cam];

var isIE = Number(navigator.appName.indexOf('Internet Explorer')) != -1;

CameraLayout = function(layout_type, display_method, layout_width, layout_height, camera_array) {
    this.layout_type = layout_type;
    this.display_method = display_method;
    this.layout_width = layout_width;
    this.layout_height = layout_height;
    this.camera_array = camera_array;
    this.layout_page_num = 1;   //current page
}

CameraLayout.prototype.getHTML = function() {

    var html;
    if (this.display_method == 1) {
        //generate activex layout
        html = "<table border='0px' cellspacing='0' cellpadding='0' style='vertical-align:top' align='center'>";
        html += "<tr><td style='vertical-align:top' valign='top'>";
        html += "<object id='Player' classid='" + vi_class_id + "' codebase='" + vi_codebase + "' width='" + this.layout_width + "' height='" + this.layout_height + "'></object>";
        html += "</td></tr></table>";
        return html;
    }

    //Generate non-activex layout based on what type of display technology we're going to use.  
    html = "<table id='cam_table' border='0px' cellspacing='2' cellpadding='0' align='center'>";
    switch (Number(this.layout_type.id)) {
        case 2: //1+7, uneven size
            html += "<tr><td colspan='3' rowspan='3' valign='top'><a id='lnk1' href=''></a><br /><div id='divCam1'></div></td><td><a id='lnk2' href=''></a><br /><div id='divCam2'></div></td></tr>";
            html += "<tr><td><a id='lnk3' href=''></a><br /><div id='divCam3'></div></td></tr>";
            html += "<tr><td><a id='lnk4' href=''></a><br /><div id='divCam4'></div></td></tr>";
            html += "<tr><td><a id='lnk5' href=''></a><br /><div id='divCam5'></div></td><td><a id='lnk6' href=''></a><br /><div id='divCam6'></div></td><td><a id='lnk7' href=''></a><br /><div id='divCam7'></div></td><td><a id='lnk8' href=''></a><br /><div id='divCam8'></div></td></tr>";
            break;

        case 4: //2+8, uneven size
            html += "<tr><td colspan='2' valign='top'><a id='lnk1' href=''></a><br /><div id='divCam1'></div></td><td colspan='2' valign='top'><a id='lnk2' href=''></a><br /><div id='divCam2'></div></td></tr>";
            html += "<tr><td><a id='lnk3' href=''></a><br /><div id='divCam3'></div></td><td><a id='lnk4' href=''></a><br /><div id='divCam4'></div></td><td><a id='lnk5' href=''></a><br /><div id='divCam5'></div></td><td><a id='lnk6' href=''></a><br /><div id='divCam6'></div></td></tr>";
            html += "<tr><td><a id='lnk7' href=''></a><br /><div id='divCam7'></div></td><td><a id='lnk8' href=''></a><br /><div id='divCam8'></div></td><td><a id='lnk9' href=''></a><br /><div id='divCam9'></div></td><td><a id='lnk10' href=''></a><br /><div id='divCam10'></div></td></tr>";
            break;

        case 5: //1+12, uneven size centered
            html += "<tr><td valign='top'><a id='lnk1' href=''></a><br /><div id='divCam1'></div></td><td valign='top'><a id='lnk2' href=''></a><br /><div id='divCam2'></div></td><td valign='top'><a id='lnk3' href=''></a><br /><div id='divCam3'></div></td><td valign='top'><a id='lnk4' href=''></a><br /><div id='divCam4'></div></td></tr>";
            html += "<tr><td valign='top'><a id='lnk5' href=''></a><br /><div id='divCam5'></div></td><td valign='top' colspan='2' rowspan='2'><a id='lnk6' href=''></a><br /><div id='divCam6'></div></td><td valign='top'><a id='lnk7' href=''></a><br /><div id='divCam7'></div></td></tr>";
            html += "<tr><td><a id='lnk8' href=''></a><br /><div id='divCam8'></div></td><td><a id='lnk9' href=''></a><br /><div id='divCam9'></div></td></tr>";
            html += "<tr><td><a id='lnk10' href=''></a><br /><div id='divCam10'></div></td><td><a id='lnk11' href=''></a><br /><div id='divCam11'></div></td><td><a id='lnk12' href=''></a><br /><div id='divCam12'></div></td><td><a id='lnk13' href=''></a><br /><div id='divCam13'></div></td></tr>";
            break;

        case 6: //1+12, uneven size
            html += "<tr valign='top'><td colspan='2' rowspan='2' valign='top'><a id='lnk1' href=''></a><br /><div id='divCam1'></div></td><td valign='top'><a id='lnk2' href=''></a><br /><div id='divCam2'></div></td><td valign='top'><a id='lnk3' href=''></a><br /><div id='divCam3'></div></td></tr>";
            html += "<tr valign='top'><td valign='top'><a id='lnk4' href=''></a><br /><div id='divCam4'></div></td><td valign='top'><a id='lnk5' href=''></a><br /><div id='divCam5'></div></td></tr>";
            html += "<tr valign='top'><td><a id='lnk6' href=''></a><br /><div id='divCam6'></div></td><td><a id='lnk7' href=''></a><br /><div id='divCam7'></div></td><td><a id='lnk8' href=''></a><br /><div id='divCam8'></div></td><td><a id='lnk9' href=''></a><br /><div id='divCam9'></div></td></tr>";
            html += "<tr valign='top'><td><a id='lnk10' href=''></a><br /><div id='divCam10'></div></td><td><a id='lnk11' href=''></a><br /><div id='divCam11'></div></td><td><a id='lnk12' href=''></a><br /><div id='divCam12'></div></td><td><a id='lnk13' href=''></a><br /><div id='divCam13'></div></td></tr>";

        case 8: //2 + 17 grid, uneven size
            html += "<tr><td colspan='2' rowspan='2' valign='top'><a id='lnk1' href=''></a><br /><div id='divCam1'></div></td><td colspan='2' rowspan='2' valign='top'><a id='lnk2' href=''></a><br /><div id='divCam2'></div></td><td><a id='lnk3' href=''></a><br /><div id='divCam3'></div></td></tr>";
            html += "<tr><td><a id='lnk4' href=''></a><br /><div id='divCam4'></div></td></tr>";
            html += "<tr><td><a id='lnk5' href=''></a><br /><div id='divCam5'></div></td><td><a id='lnk6' href=''></a><br /><div id='divCam6'></div></td><td><a id='lnk7' href=''></a><br /><div id='divCam7'></div></td><td><a id='lnk8' href=''></a><br /><div id='divCam8'></div></td><td><a id='lnk9' href=''></a><br /><div id='divCam9'></div></td></tr>";
            html += "<tr><td><a id='lnk10' href=''></a><br /><div id='divCam10'></div></td><td><a id='lnk11' href=''></a><br /><div id='divCam11'></div></td><td><a id='lnk12' href=''></a><br /><div id='divCam12'></div></td><td><a id='lnk13' href=''></a><br /><div id='divCam13'></div></td><td><a id='lnk14' href=''></a><br /><div id='divCam14'></div></td></tr>";
            html += "<tr><td><a id='lnk15' href=''></a><br /><div id='divCam15'></div></td><td><a id='lnk16' href=''></a><br /><div id='divCam16'></div></td><td><a id='lnk17' href=''></a><br /><div id='divCam17'></div></td><td><a id='lnk18' href=''></a><br /><div id='divCam18'></div></td><td><a id='lnk19' href=''></a><br /><div id='divCam19'></div></td></tr>";
            break;

        default: //regular sized grid layout
            var ctr = 0;
            for (var y = 1; y <= this.layout_type.rows; y++) {
                html += "<tr>";
                for (var x = 1; x <= this.layout_type.cols; x++) {
                    ctr++;
                    var div_id = "divCam" + ctr;
                    html += "<td><a id='lnk" + ctr + "' href=''></a><br /><div id='" + div_id + "'></div></td>";
                }
                html += "</tr>";
            }
            break;
    }
    html += "</table>";
    return html;
}

CameraLayout.prototype.updateSelection = function(layout_type, camera_array) {
    this.layout_type = layout_type;
    this.camera_array = camera_array;
    this.displayVideo();
}

CameraLayout.prototype.stop = function() {
    //Stop video streaming
    if (this.display_method == 1) {
        var ax = document.getElementById('Player');
        if (ax) {
            try {
                ax.Close();
            } catch (e) {
                //alert(e);
            }
        }
    } else {

    }
}

CameraLayout.prototype.write = function(elementId) {
    if (elementId) {
        document.getElementById(elementId).innerHTML = this.getHTML();
    } else {
        document.write(this.getHTML());
    }
    this.displayVideo();
}

CameraLayout.prototype.refresh = function(elementId) {
    if (elementId) {
        document.getElementById(elementId).innerHTML = this.getHTML();
    } else {
        document.write(this.getHTML());
    }
    this.displayVideo(true);
}

CameraLayout.prototype.displayVideo = function(refresh) {
    if (_retry_display_tmr != 0) {
        clearTimeout(_retry_display_tmr);
        _retry_display_tmr = 0;
    }

    //Don't show any cameras if none are listed
    if (this.camera_array.length == 0) return;

    var player = document.getElementById('Player');
    if (this.display_method == 1) {
        try {
            player.clear();
        } catch (e) {
            //retry -- activeX may not be initialized or installed
            _retry_display_tmr = setTimeout('_handleDisplayVideo()', 5000);
        }
    }

    var cam_idx = this.layout_type.count * (this.layout_page_num - 1);
    var win_idx = 0;             //index of img window starts at 1
    var arr_idx = cam_idx - 1;
    for (var i = cam_idx; i < this.camera_array.length; i++) {
        win_idx++;   //Start looking at c_1 window, not c_0
        arr_idx++;
        if (this.display_method == 1) {
            var id = this.camera_array[i].get_value();
            var name = this.camera_array[i].get_text();
            var is_ptz = this.camera_array[i].get_attributes().getAttribute("PTZ");
            var ip = this.camera_array[i].get_attributes().getAttribute("IP")
            var port = this.camera_array[i].get_attributes().getAttribute("Port")
            var cmd_port = this.camera_array[i].get_attributes().getAttribute("CmdPort");
            var layout_pos = win_idx - 1;   //0 based starting position
            try {
                player.addServer(ip, port, cmd_port);
                player.addCamera(ip, id, name, layout_pos, is_ptz);
            } catch (e) {

            }
        } else {
            var cam_dimensions = getWindowDimensions(this.layout_type, arr_idx);
            var camera_width = Math.floor(cam_dimensions.split(',')[0]);
            var camera_height = Math.floor(cam_dimensions.split(',')[1]);
            var my_div = document.getElementById("divCam" + win_idx);
            if (my_div) {
                var cid = this.camera_array[arr_idx].get_value();
                my_div.innerHTML = formatClientPullControlString(win_idx, cid, camera_width, camera_height, smClientPull);
                initLink(this.camera_array[arr_idx], win_idx);
            }
        }
    }
    if (this.display_method == 1) {
        this.resizeVideo();
        player.setLayout(this.layout_type.id);
        player.play();
    }
}

var _retry_display_tmr  = 0;
function _handleDisplayVideo(refresh) {
    if (myLayout) {
        myLayout.displayVideo();
    }
}

CameraLayout.prototype.resizeVideo = function() {
    var cam_elements;
    if (this.display_method == 1) {
        resizeLayout();
    } else {
        var arrCameraID = this.camera_array;
        for (var i = 0; i < arrCameraID.length; i++) {
            var index = i + 1;
            var cam_dimensions = getWindowDimensions(this.layout_type, i);
            var camera_width = Math.floor(cam_dimensions.split(',')[0]);
            var camera_height = Math.floor(cam_dimensions.split(',')[1]);
            var my_camera = document.getElementById("c_" + index);
            if (my_camera) {
                my_camera.style.height = camera_height + 'px';
                my_camera.style.width = camera_width + 'px';
            }
        }
    }
}

function getWindowDimensions(layout_type, position) {
    var layout_id = layout_type.id;
    var num_rows = layout_type.rows;
    var num_cols = layout_type.cols;
    var x_padding = is_maximized ? 20 : 10;
    var x_spacing = 10 * num_cols; //2 pixels for each colum
    var header_h = (18 * num_rows); // pixels high
    if ((!isIE) && (num_rows >= 4)) {
        //need additional padding for cut off issue in Firefox
        header_h = header_h + 40;
    }
    var aspect_ratio = 0.75;    //.75 for live, 1.06 for playback
    var width_ratio = 1.33;
    var win_w = 0;
    var win_h = 0;
    if (is_maximized) {
        if (window.innerWidth) {
            win_w = window.innerWidth;
        } else {
            win_w = document.body.clientWidth;
        }
        if (window.innerHeight) {
            win_h = window.innerHeight;
        } else {
            win_h = document.body.clientHeight;
        }
        win_w = win_w - x_padding;
        win_h = win_h - header_h;
    } else {
        var offset_left = div_content.offsetLeft;
        var offset_top = 66; //div_content.offsetTop;
        win_w = $w() - offset_left; // parseInt(div_content.style.width) - x_padding;
        win_h = $h() - (offset_top + header_h);
    }
    var new_height;
    var new_width;
    //Determine window dimensions and size accordingly 
    var win_ratio = win_h / win_w;
    if (win_ratio <= aspect_ratio) {
        //Restrict to height and adjust height for playback controls if needed
        new_height = Math.round(win_h / Math.max(num_rows, num_cols));
        new_width = Math.round(new_height * width_ratio);
    } else {
        //Restrict to width
        new_width = win_w - x_spacing;
        new_width = Math.round(new_width / num_cols);
        new_height = Math.round(new_width * aspect_ratio);
    }
    //At this point, new_height and new_width contain width and height of the display area.  Now divide that
    //by the number of rows or columns, while taking into account that some layouts have larger windows
    //in some locations.
    switch (Number(layout_id)) {
        case 2:
            if (position == 0) {
                new_width = new_width * 3;
                new_height = new_height * 3;
            }
            break;

        case 4:
            if ((position == 0) || (position == 1)) {
                new_width = new_width * 2;
                new_height = new_height * 2;
            }
            break;

        case 5:
            if (position == 5) {
                new_width = new_width * 2;
                new_height = new_height * 2;
            }
            break;

        case 6:
            if (position == 0) {
                new_width = new_width * 2;
                new_height = new_height * 2;
            }
            break;

        case 8:
            if ((position == 0) || (position == 1)) {
                new_width = new_width * 2;
                new_height = new_height * 2;
            }
            break;

        default:    //a non-custom layout where all windows are the same size.            
            //new_width = Math.round(new_width * .95);
            //new_height = Math.round(new_height * .95);
            break;
    }
    return new_width + ',' + new_height;

}


function resizeLayout(keep_aspect_ratio) {
    var aspect_ratio = 0.75;    //.75 for live, 1.06 for playback
    var width_ratio = 1.33;
    var x_padding = 10;
    var win_w = 0;
    var win_h = 0;
    var new_height;
    var new_width;

    if (is_maximized) {
        win_w = window.innerWidth ? window.innerWidth : document.body.clientWidth;
        win_h = window.innerHeight ? window.innerHeight : document.body.clientHeight;
    } else {
        win_w = parseInt(div_content.style.width);
        win_h = parseInt(div_content.style.height);
    }

    var my_viewer = document.getElementById("Player");  //get reference to activex object

    //Determine window dimensions and size accordingly
    if (keep_aspect_ratio) {
        var win_ratio = win_h / win_w;
        if (win_ratio <= aspect_ratio) {
            //Restrict to height and adjust height for playback controls if needed
            new_height = win_h;
            new_width = Math.round(new_height * width_ratio);
        } else {
            //Restrict to width
            new_width = win_w;
            new_height = Math.round(new_width * aspect_ratio);
        }
    }

    //Resize the object
    win_w = win_w - x_padding;
    if (my_viewer) {
        //my_viewer.SetSize(new_width, new_height);
        try {
            my_viewer.SetSize(win_w, win_h - 24);
            my_viewer.SetSize(win_w, win_h - 24);
        } catch (e) {

        }
    }
}

function formatClientPullControlString(camera_index, camera_id, camera_width, camera_height, display_mode) {
    //Return a formatted image control string for the specified camera
    //var control_string = '<iframe id="c_' + camera_index + '" src="CameraFrame.aspx?cid=' + camera_id + '&dm=' + display_mode + '" width="' + camera_width + 'px" height="' + camera_height + 'px" frameborder="0" scrolling="none"></iframe>';
    var control_string;
    if (myLayout.layout_type.count == 1) {
        control_string = '<iframe allowtransparency="true" id="c_' + camera_index + '" src="CameraFrame.aspx?cid=' + camera_id + '&dm=' + display_mode + '" width="' + camera_width + 'px" height="' + camera_height + 'px" style="border:1px solid #333333;background-color:#465764;" frameborder="0" scrolling="none" onclick="alert(1);"></iframe>';
    } else {
        control_string = '<iframe allowtransparency="true" id="c_' + camera_index + '" src="CameraFrame.aspx?cid=' + camera_id + '&dm=' + display_mode + '" width="' + camera_width + 'px" height="' + camera_height + 'px" style="border:1px solid #333333;background-color:#465764;" frameborder="0" scrolling="none" onclick="alert(1);"></iframe>';
    //control_string = '<iframe allowtransparency="true" id="c_' + camera_index + '" src="CameraFrame.aspx?cid=' + camera_id + '&res=1&dm=' + display_mode + '" width="' + camera_width + 'px" height="' + camera_height + 'px" style="border:1px solid #333333;background-color:#465764;" frameborder="0" scrolling="none" onclick="alert(1);"></iframe>';
    }
    return control_string;
}

function refreshImage(cam_object, camera_id) {
    if (is_navigating) return;
    if (myLayout.layout_type.count == 1) {
        cam_object.src = "c.cam?cid=" + camera_id + "&nocache=" + new Date().getTime();
    } else {
        //request smaller image
        cam_object.src = "c.cam?cid=" + camera_id + "&nocache=" + new Date().getTime();
        //cam_object.src = "c.cam?cid=" + camera_id + "&res=1&nocache=" + new Date().getTime();
    }    
}

function initLink(node, camera_index) {
    var link = document.getElementById("lnk" + camera_index);
    if (link) {
        var camera_name = node.get_text();
        var node_value = node.get_value();
        link.innerHTML = camera_name;
        link.href = "CameraFrame.aspx?cid=" + node_value + '&dm=' + myLayout.display_method + '&pu=1';     
        link.onclick = function() {
            viewCamera(node_value, camera_name);
            return false;
        }
    }
}

var win_id = 0;
function viewCamera(camera_id, camera_name) {
    var url = 'CameraFrame.aspx?cid=' + camera_id + '&dm=' + myLayout.display_method + '&pu=1';
    
    var win_w = 640;
    var win_h = 480;
    var win_x = 10 + (win_id * 30);
    var win_y = 10 + (win_id * 30);
    //Don't let the window go off of the screen.
    if (win_x > (screen.height - 480)) {
        win_id = 0;
        win_x = 10;
        win_y = 10;
    }
    win_id++;
    var win_name = 'camera_' + win_id;
    var other_args = 'location=no,menubar=no,status=yes,scroolbars=no,toolbar=no,resizable=yes,width=' + win_w + ',height=' + win_h + ',left=' + win_x + ',top=' + win_y;
    window.open(url, win_name, other_args);
}

function formatVIControlString(camera_nodes) {
    //Return a formatted string for the VI ActiveX control
    var arrCameras = new Array();
    var arrServers = new Array();
    var arrPorts = new Array();
    var control_string = '';

    //extract camera ids
    for (var i = 0; i < camera_nodes.length; i++) {
        //Values are ServerIpAddress;ServerPort;CameraID;PTZ;LivePermission;PlaybackPermission;PTZPermission        
        var id = camera_nodes[i].get_value();
        var server_ip = camera_nodes[i].get_attributes().getAttribute("IP");
        var server_port = camera_nodes[i].get_attributes().getAttribute("Port");
        //put them in their proper arrays
        var array_index = arrServers.indexOf(server_ip);
        if ((array_index == -1) && (String(server_ip) != "undefined")) {
            array_index = arrServers.length;
            arrServers[array_index] = server_ip;
            arrPorts[array_index] = server_port;
            arrCameras[array_index] = id;
        } else {
            arrCameras[array_index] += ',' + id;
        }        
    }
    //return a formatted string
    for (var i = 0; i < arrServers.length; i++) {
        if (i > 0) {
            control_string += '|';
        }
        control_string += arrServers[i] + ';' + arrPorts[i] + ';' + arrCameras[i];
    }
    return control_string;

}

function mergeCameraList(cam_list_1, cam_list_2) {
    var control_string = cam_list_1;
    var arrCameras_2 = cam_list_2.split(',');
    for (var i = 0; i < arrCameras_2.length; i++) {
        var paddedCtrString = ',' + control_string + ',';
        var paddedCamString = ',' + arrCameras_2[i] + ',';
        if (paddedCtrString.indexOf(paddedCamString) < 0) {
            control_string += ',' + arrCameras_2[i];
        }
    }
    return control_string;
}

function formatCpLiveArray(nodes) {

    //Return a formatted string for the Client Pull display
    var camera_list = new Array();

    for (var i = 0; i < nodes.length; i++) {
        var node_category = nodes[i].get_category();
        if (node_category == 'S') {
            var csl = nodes[i].get_attributes().getAttribute("CameraList");
            var node_list = csl.split(',');
            var working_list = camera_list.concat(node_list);          
            camera_list = unique(working_list); //remove duplicates
        } else if (node_category == 'L') {
            var csl = nodes[i].get_attributes().getAttribute("CameraList");
            camera_list = sCameraList.split(',');         
        } else if (node_category == 'C') {
            var node_list = new Array(nodes[i].get_value());
            var working_list = camera_list.concat(node_list);
            camera_list = unique(working_list); //remove duplicates
        }
    }

    return camera_list;

}

function checkPTZ(camera_id, camera_name) {

    var myNode = myTree.findNodeByValue(camera_id);
    if (myNode) {
        var is_ptz_permitted = myNode.get_attributes().getAttribute("PTZ");
        var server_id = myNode.get_attributes().getAttribute("ServerID");
        if (Number(is_ptz_permitted) != 0) {
            expandPTZ();
            updatePtzPanel(myNode.get_value(), server_id, camera_name);
        } else {
            collapsePTZ();
        }
    }
}
