<commit_before>'use strict'

function FPSControls(camera) {
    this.__init__(camera)
}

FPSControls.prototype = {
    camera            : null,
    pitch             : null,
    yaw               : null,
    enabled           : null,

    // Movement.
    up                : null,
    down              : null,
    left              : null,
    right             : null,

    velocity          : null,
    acceleration      : null,

    flying_on         : null,
    left_right        : null,

    walking_direction : null,

    direction_object3D : null,

    camera_object3D    : null,

    // Camera view.
    max_upward_view   : null,
    max_downward_view : null,
    direction_vector  : null,

    // Mouse movement variables.
    buffer_mouse_movement: null,

    // Used to make mouse movement feel smoother.
    mouse_movement_x_buffer: null,
    mouse_movement_y_buffer: null,

    // Constants.
    half_pie          : null,
    max_view_angle    : null,
    diagonal_penalty  : null,
    ground_normal     : null,

    __init__: function(camera) {
        // Constants.
        this.half_pie         = Math.PI / 2
        this.max_view_angle   = this.half_pie * 0.9
        this.diagonal_penalty = Math.sqrt(.5)
        this.ground_normal    = new THREE.Vector3(0, 1, 0)

        this.buffer_mouse_movement = true

        this.camera = camera
        //this.camera.rotation.set(0, 0, 0)
        //this.camera.eulerOrder = 'ZYX'
        //this.camera.up = new THREE.Vector3(0, 1, 0)

        this.pitch = new THREE.Object3D()

        this.pitch.add(camera)

        this.yaw = new THREE.Object3D()
        this.yaw.add(this.pitch)

        this.enabled = false
        this.flying_on = true

        this.velocity = new THREE.Vector3()

        this.mouse_movement_x_buffer = new SmoothStepLowerLimitZero(this.yaw.rotation.y, 0.025)
        this.mouse_movement_y_buffer = new SmoothStepLowerLimitZero(this.pitch.rotation.x, 0.025)

        // TODO : Add smooth step to the movement buffers!!!

        document.addEventListener('keypress', this.on_key_press.bind(this), false)
        document.addEventListener('mousemove', this.on_mouse_move.bind(this), false)
        document.addEventListener('keydown', this.on_key_down.bind(this), false)
        document.addEventListener('keyup', this.on_key_up.bind(this), false)
    },

    toggle_flying: function() {
        this.flying_on = !this.flying_on
        if (this.flying_on) {
            this.velocity.y = 0
        }
    },

    toggle_mouse_movement_system: function() {
        this.buffer_mouse_movement = !this.buffer_mouse_movement
    },

    fly_left: function(delta) {
        this.velocity.x += 200 * delta * this.left_right.x
        this.velocity.y += 200 * delta * this.left_right.y
        this.velocity.z += 200 * delta * this.left_right.z
    },

    fly_right: function(delta) {
        this.velocity.x -= 200 * delta * this.left_right.x
        this.velocity.y -= 200 * delta * this.left_right.y
        this.velocity.z -= 200 * delta * this.left_right.z
    },

    fly_forward: function(delta) {
        this.velocity.x += 200 * delta * this.direction_vector.x
        this.velocity.y += 200 * delta * this.direction_vector.y
        this.velocity.z += 200 * delta * this.direction_vector.z
    },

    fly_backward: function(delta) {
        this.velocity.x -= 200 * delta * this.direction_vector.x
        this.velocity.y -= 200 * delta * this.direction_vector.y
        this.velocity.z -= 200 * delta * this.direction_vector.z
    },

    move_forward: function(delta) {
        this.velocity.x += 200 * delta * this.direction_vector.x
        this.velocity.z += 200 * delta * this.direction_vector.z
    },

    move_backward: function(delta) {
        this.velocity.x -= 200 * delta * this.direction_vector.x
        this.velocity.z -= 200 * delta * this.direction_vector.z
    },

    move_left: function(delta) {
        this.velocity.x += 200 * delta * this.left_right.x
        this.velocity.z += 200 * delta * this.left_right.z
    },

    move_right: function(delta) {
        this.velocity.x -= 200 * delta * this.left_right.x
        this.velocity.z -= 200 * delta * this.left_right.z
    },

    physics: function(delta) {
        if (this.enabled) {

            if (this.buffer_mouse_movement) {
                this.mouse_movement_x_buffer.update(delta)
                this.mouse_movement_y_buffer.update(delta)
            }
            this.update_mouse_view_position()

            if (this.flying_on) {
                // Flying code.
                if (this.space) {
                    this.velocity.y += 200.0 * delta
                }
                if (this.shift) {
                    this.velocity.y -= 200.0 * delta
                }

                if ((this.up ^ this.down) & (this.left ^ this.right)) {
                    if (this.up) {
                        this.fly_forward(delta * this.diagonal_penalty)
                    } else {
                        this.fly_backward(delta * this.diagonal_penalty)
                    }
                    if (this.left) {
                        this.fly_left(delta * this.diagonal_penalty)
                    } else {
                        this.fly_right(delta * this.diagonal_penalty)
                    }
                } else if (this.up ^ this.down) {
                    if (this.up) {
                        this.fly_forward(delta)
                    } else {
                        this.fly_backward(delta)
                    }
                } else if (this.left ^ this.right) {
                    if (this.left) {
                        this.fly_left(delta)
                    } else {
                        this.fly_right(delta)
                    }
                }
                this.velocity.y *= (1 - delta * 15)
                this.yaw.position.y += this.velocity.y
                //this.direction_object3D.position.y += this.velocity.y
            } else {
                // Walking code.
                if ((this.up ^ this.down) & (this.left ^ this.right)) {
                    if (this.up) {
                        this.move_forward(delta * this.diagonal_penalty)
                    } else {
                        this.move_backward(delta * this.diagonal_penalty)
                    }
                    if (this.left) {
                        this.move_left(delta * this.diagonal_penalty)
                    } else {
                        this.move_right(delta * this.diagonal_penalty)
                    }
                } else if (this.up ^ this.down) {
                    if (this.up) {
                        this.fly_forward(delta)
                    } else {
                        this.fly_backward(delta)
                    }
                } else if (this.left ^ this.right) {
                    if (this.left) {
                        this.move_left(delta)
                    } else {
                        this.move_right(delta)
                    }
                }

                if (this.velocity.y != 0) {
                    this.velocity.y -= 9.8 * delta * 10
                    this.velocity.y *= (1 - delta * 15)
                    this.yaw.position.y += this.velocity.y
                    if (this.yaw.position.y <= 10) {
                        this.yaw.position.y = 10
                        this.velocity.y = 0
                    }
                }

            }
            // Both flying and walking treat the following lines the same.
            this.velocity.x *= (1 - delta * 15)
            this.velocity.z *= (1 - delta * 15)
            //this.direction_object3D.position.x += this.velocity.x
            //this.direction_object3D.position.z += this.velocity.z
            this.yaw.position.x += this.velocity.x
            this.yaw.position.z += this.velocity.z
        }
    },

    get_position: function() {
        //return this.direction_object3D.position
        return this.yaw.position
    },

    get_velocity: function() {
        return this.velocity
    },

    enable: function() {
        this.enabled = true
    },

    disable: function() {
        this.enabled = false
    },

    on_key_press: function(event) {
        switch(event.which) {
        case 102: // f
            this.toggle_flying()
            break
        case 109: // m
            this.toggle_mouse_movement_system()
            break
        }
    },

    on_key_down: function(event) {
        switch(event.keyCode) {
        case 38: // up
        case 87: // w
            this.up = true
            break
        case 37: // left
        case 65: // a
            this.left = true
            break
        case 40: // down
        case 83: // s
            this.down = true
            break
        case 39: // right
        case 68: // d
            this.right = true
            break
        case 32: // space
            this.space = true
            break
        case 16: // shift
            this.shift = true
            break
        }
    },

    on_key_up: function(event) {
        switch(event.keyCode) {
        case 38: // up
        case 87: // w
            this.up = false
            break
        case 37: // left
        case 65: // a
            this.left = false
            break
        case 40: // down
        case 83: // s
            this.down = false
            break
        case 39: // right
        case 68: // d
            this.right = false
            break
        case 32: // space
            this.space = false
            break
        case 16: // shift
            this.shift = false
            break
        }
    },

    look_at: function(position_vector_to_look_at) {
        var look_at_normal = new THREE.Vector3(position_vector_to_look_at.x, position_vector_to_look_at.y, position_vector_to_look_at.z)
        look_at_normal.sub(this.yaw.position)
        look_at_normal.normalize()

        var look_at_angle = Math.atan2(look_at_normal.z, look_at_normal.x)

        var d = this.get_direction()
        var x_rotation = new THREE.Vector2(d.x, d.z)
        x_rotation.normalize()

        var angle = Math.atan2(x_rotation.y, x_rotation.x)

        console.log('Look at normal : ' + look_at_normal.y)
        console.log('Current        : ' + d.y)

        var y_angle = Math.atan2(d.y, look_at_normal.y)

        console.log('Y difference : ' + (d.y - look_at_normal.y))
        console.log('Y difference 2 : ' + y_angle * (Math.PI / 180.0))
        console.log('Y difference 3 : ' + y_angle)

        this.mouse_movement_y_buffer.add_force(-1.0 * ((d.y - look_at_normal.y) * HALF_PIE))
        //this.mouse_movement_y_buffer.add_force(y_angle * (Math.PI / 180.0))

        this.mouse_movement_x_buffer.add_force(-1.0 * (look_at_angle - angle))
    },

    update_mouse_view_position: function() {
        if (this.buffer_mouse_movement) {
            this.yaw.rotation.y = this.mouse_movement_x_buffer.get_current_value()
            this.pitch.rotation.x = this.mouse_movement_y_buffer.get_current_value()
        }

        this.pitch.rotation.x = Math.max(-this.max_view_angle, Math.min(this.max_view_angle, this.pitch.rotation.x))

        this.direction_vector = this.get_direction()
        this.direction_vector.normalize()

        this.left_right = new THREE.Vector3(0, 1, 0)
        this.left_right.cross(this.direction_vector)
        this.left_right.normalize()

        if (!this.flying_on) {
            this.walking_direction = new THREE.Vector3(this.direction_vector.x, this.direction_vector.y, this.direction_vector.z)
            this.walking_direction = this.walking_direction.projectOnPlane(this.ground_normal)
            this.walking_direction.normalize()
        }
    },

    on_mouse_move: function(event) {
        console.log('Rotation Y : ' + this.yaw.rotation.y)
        //console.log('Rotation X : ' + this.pitch.rotation.x)
        //console.log('---')

        if (this.enabled) {
            var movement_x = event.movementX || event.mozMovementX || event.webkitMovementX || 0
            var movement_y = event.movementY || event.mozMovementY || event.webkitMovementY || 0

            if (this.buffer_mouse_movement) {
                this.mouse_movement_x_buffer.add_force(movement_x * -0.002)
                this.mouse_movement_y_buffer.add_force(movement_y * -0.002)
            } else {
                this.yaw.rotation.y   -= movement_x * 0.002
                this.pitch.rotation.x -= movement_y * 0.002
            }
        }
    },

    get_object: function() {
        //return this.direction_object3D
        return this.yaw
    },

    get_direction: function() {
        var direction = new THREE.Vector3(0, 0, -1)
        //var rotation  = new THREE.Euler(this.pitch.rotation.x, this.yaw.rotation.y, 0, 'YXZ')
        var rotation  = new THREE.Euler(this.mouse_movement_y_buffer.get_current_value(), this.mouse_movement_x_buffer.get_current_value(), 0, 'YXZ')
        return direction.applyEuler(rotation)
    }

}<commit_msg>general updating 24<commit_after>'use strict'

function FPSControls(camera) {
    this.__init__(camera)
}

FPSControls.prototype = {
    camera            : null,
    pitch             : null,
    yaw               : null,
    enabled           : null,

    // Movement.
    up                : null,
    down              : null,
    left              : null,
    right             : null,

    velocity          : null,
    acceleration      : null,

    flying_on         : null,
    left_right        : null,

    walking_direction : null,

    direction_object3D : null,

    camera_object3D    : null,

    // Camera view.
    max_upward_view   : null,
    max_downward_view : null,
    direction_vector  : null,

    // Mouse movement variables.
    buffer_mouse_movement: null,

    // Used to make mouse movement feel smoother.
    mouse_movement_x_buffer: null,
    mouse_movement_y_buffer: null,

    // Constants.
    half_pie          : null,
    max_view_angle    : null,
    diagonal_penalty  : null,
    ground_normal     : null,

    __init__: function(camera) {
        // Constants.
        this.diagonal_penalty = Math.sqrt(.5)
        this.ground_normal    = new THREE.Vector3(0, 1, 0)

        this.buffer_mouse_movement = true

        this.camera = camera
        //this.camera.rotation.set(0, 0, 0)
        //this.camera.eulerOrder = 'ZYX'
        //this.camera.up = new THREE.Vector3(0, 1, 0)

        this.pitch = new THREE.Object3D()

        this.pitch.add(camera)

        this.yaw = new THREE.Object3D()
        this.yaw.add(this.pitch)

        this.enabled = false
        this.flying_on = true

        this.velocity = new THREE.Vector3()

        this.mouse_movement_x_buffer = new SmoothStepLowerLimitZero(this.yaw.rotation.y, 0.025)
        this.mouse_movement_y_buffer = new SmoothStepLowerLimitZero(this.pitch.rotation.x, 0.025)

        // TODO : Add smooth step to the movement buffers!!!

        document.addEventListener('keypress', this.on_key_press.bind(this), false)
        document.addEventListener('mousemove', this.on_mouse_move.bind(this), false)
        document.addEventListener('keydown', this.on_key_down.bind(this), false)
        document.addEventListener('keyup', this.on_key_up.bind(this), false)
    },

    toggle_flying: function() {
        this.flying_on = !this.flying_on
        if (this.flying_on) {
            this.velocity.y = 0
        }
    },

    toggle_mouse_movement_system: function() {
        this.buffer_mouse_movement = !this.buffer_mouse_movement
    },

    fly_left: function(delta) {
        this.velocity.x += 200 * delta * this.left_right.x
        this.velocity.y += 200 * delta * this.left_right.y
        this.velocity.z += 200 * delta * this.left_right.z
    },

    fly_right: function(delta) {
        this.velocity.x -= 200 * delta * this.left_right.x
        this.velocity.y -= 200 * delta * this.left_right.y
        this.velocity.z -= 200 * delta * this.left_right.z
    },

    fly_forward: function(delta) {
        this.velocity.x += 200 * delta * this.direction_vector.x
        this.velocity.y += 200 * delta * this.direction_vector.y
        this.velocity.z += 200 * delta * this.direction_vector.z
    },

    fly_backward: function(delta) {
        this.velocity.x -= 200 * delta * this.direction_vector.x
        this.velocity.y -= 200 * delta * this.direction_vector.y
        this.velocity.z -= 200 * delta * this.direction_vector.z
    },

    move_forward: function(delta) {
        this.velocity.x += 200 * delta * this.direction_vector.x
        this.velocity.z += 200 * delta * this.direction_vector.z
    },

    move_backward: function(delta) {
        this.velocity.x -= 200 * delta * this.direction_vector.x
        this.velocity.z -= 200 * delta * this.direction_vector.z
    },

    move_left: function(delta) {
        this.velocity.x += 200 * delta * this.left_right.x
        this.velocity.z += 200 * delta * this.left_right.z
    },

    move_right: function(delta) {
        this.velocity.x -= 200 * delta * this.left_right.x
        this.velocity.z -= 200 * delta * this.left_right.z
    },

    physics: function(delta) {
        if (this.enabled) {

            if (this.buffer_mouse_movement) {
                this.mouse_movement_x_buffer.update(delta)
                this.mouse_movement_y_buffer.update(delta)
            }
            this.update_mouse_view_position()

            if (this.flying_on) {
                // Flying code.
                if (this.space) {
                    this.velocity.y += 200.0 * delta
                }
                if (this.shift) {
                    this.velocity.y -= 200.0 * delta
                }

                if ((this.up ^ this.down) & (this.left ^ this.right)) {
                    if (this.up) {
                        this.fly_forward(delta * this.diagonal_penalty)
                    } else {
                        this.fly_backward(delta * this.diagonal_penalty)
                    }
                    if (this.left) {
                        this.fly_left(delta * this.diagonal_penalty)
                    } else {
                        this.fly_right(delta * this.diagonal_penalty)
                    }
                } else if (this.up ^ this.down) {
                    if (this.up) {
                        this.fly_forward(delta)
                    } else {
                        this.fly_backward(delta)
                    }
                } else if (this.left ^ this.right) {
                    if (this.left) {
                        this.fly_left(delta)
                    } else {
                        this.fly_right(delta)
                    }
                }
                this.velocity.y *= (1 - delta * 15)
                this.yaw.position.y += this.velocity.y
                //this.direction_object3D.position.y += this.velocity.y
            } else {
                // Walking code.
                if ((this.up ^ this.down) & (this.left ^ this.right)) {
                    if (this.up) {
                        this.move_forward(delta * this.diagonal_penalty)
                    } else {
                        this.move_backward(delta * this.diagonal_penalty)
                    }
                    if (this.left) {
                        this.move_left(delta * this.diagonal_penalty)
                    } else {
                        this.move_right(delta * this.diagonal_penalty)
                    }
                } else if (this.up ^ this.down) {
                    if (this.up) {
                        this.fly_forward(delta)
                    } else {
                        this.fly_backward(delta)
                    }
                } else if (this.left ^ this.right) {
                    if (this.left) {
                        this.move_left(delta)
                    } else {
                        this.move_right(delta)
                    }
                }

                if (this.velocity.y != 0) {
                    this.velocity.y -= 9.8 * delta * 10
                    this.velocity.y *= (1 - delta * 15)
                    this.yaw.position.y += this.velocity.y
                    if (this.yaw.position.y <= 10) {
                        this.yaw.position.y = 10
                        this.velocity.y = 0
                    }
                }

            }
            // Both flying and walking treat the following lines the same.
            this.velocity.x *= (1 - delta * 15)
            this.velocity.z *= (1 - delta * 15)
            //this.direction_object3D.position.x += this.velocity.x
            //this.direction_object3D.position.z += this.velocity.z
            this.yaw.position.x += this.velocity.x
            this.yaw.position.z += this.velocity.z
        }
    },

    get_position: function() {
        //return this.direction_object3D.position
        return this.yaw.position
    },

    get_velocity: function() {
        return this.velocity
    },

    enable: function() {
        this.enabled = true
    },

    disable: function() {
        this.enabled = false
    },

    on_key_press: function(event) {
        switch(event.which) {
        case 102: // f
            this.toggle_flying()
            break
        case 109: // m
            this.toggle_mouse_movement_system()
            break
        }
    },

    on_key_down: function(event) {
        switch(event.keyCode) {
        case 38: // up
        case 87: // w
            this.up = true
            break
        case 37: // left
        case 65: // a
            this.left = true
            break
        case 40: // down
        case 83: // s
            this.down = true
            break
        case 39: // right
        case 68: // d
            this.right = true
            break
        case 32: // space
            this.space = true
            break
        case 16: // shift
            this.shift = true
            break
        }
    },

    on_key_up: function(event) {
        switch(event.keyCode) {
        case 38: // up
        case 87: // w
            this.up = false
            break
        case 37: // left
        case 65: // a
            this.left = false
            break
        case 40: // down
        case 83: // s
            this.down = false
            break
        case 39: // right
        case 68: // d
            this.right = false
            break
        case 32: // space
            this.space = false
            break
        case 16: // shift
            this.shift = false
            break
        }
    },

    look_at: function(position_vector_to_look_at) {
        var look_at_normal = new THREE.Vector3(position_vector_to_look_at.x, position_vector_to_look_at.y, position_vector_to_look_at.z)
        look_at_normal.sub(this.yaw.position)
        look_at_normal.normalize()

        var look_at_angle = Math.atan2(look_at_normal.z, look_at_normal.x)

        var d = this.get_direction()
        var x_rotation = new THREE.Vector2(d.x, d.z)
        x_rotation.normalize()

        var angle = Math.atan2(x_rotation.y, x_rotation.x)

        console.log('Look at normal : ' + look_at_normal.y)
        console.log('Current        : ' + d.y)

        var y_angle = Math.atan2(d.y, look_at_normal.y)

        console.log('Y difference : ' + (d.y - look_at_normal.y))
        console.log('Y difference 2 : ' + y_angle * (Math.PI / 180.0))
        console.log('Y difference 3 : ' + y_angle)

        this.mouse_movement_y_buffer.add_force(-1.0 * ((d.y - look_at_normal.y) * HALF_PIE))
        //this.mouse_movement_y_buffer.add_force(y_angle * (Math.PI / 180.0))

        this.mouse_movement_x_buffer.add_force(-1.0 * (look_at_angle - angle))
    },

    update_mouse_view_position: function() {
        if (this.buffer_mouse_movement) {
            this.yaw.rotation.y = this.mouse_movement_x_buffer.get_current_value()
            this.pitch.rotation.x = this.mouse_movement_y_buffer.get_current_value()
        }

        this.pitch.rotation.x = Math.max(-1.0 * HALF_PIE, Math.min(HALF_PIE, this.pitch.rotation.x))

        this.direction_vector = this.get_direction()
        this.direction_vector.normalize()

        this.left_right = new THREE.Vector3(0, 1, 0)
        this.left_right.cross(this.direction_vector)
        this.left_right.normalize()

        if (!this.flying_on) {
            this.walking_direction = new THREE.Vector3(this.direction_vector.x, this.direction_vector.y, this.direction_vector.z)
            this.walking_direction = this.walking_direction.projectOnPlane(this.ground_normal)
            this.walking_direction.normalize()
        }
    },

    on_mouse_move: function(event) {
        //console.log('Rotation X : ' + this.yaw.rotation.y)
        console.log('Rotation Y : ' + this.pitch.rotation.x)
        //console.log('---')

        if (this.enabled) {
            var movement_x = event.movementX || event.mozMovementX || event.webkitMovementX || 0
            var movement_y = event.movementY || event.mozMovementY || event.webkitMovementY || 0

            if (this.buffer_mouse_movement) {
                this.mouse_movement_x_buffer.add_force(movement_x * -0.002)
                this.mouse_movement_y_buffer.add_force(movement_y * -0.002)
            } else {
                this.yaw.rotation.y   -= movement_x * 0.002
                this.pitch.rotation.x -= movement_y * 0.002
            }
        }
    },

    get_object: function() {
        //return this.direction_object3D
        return this.yaw
    },

    get_direction: function() {
        var direction = new THREE.Vector3(0, 0, -1)
        //var rotation  = new THREE.Euler(this.pitch.rotation.x, this.yaw.rotation.y, 0, 'YXZ')
        var rotation  = new THREE.Euler(this.mouse_movement_y_buffer.get_current_value(), this.mouse_movement_x_buffer.get_current_value(), 0, 'YXZ')
        return direction.applyEuler(rotation)
    }

}<|endoftext|>


<commit_before>
function generateInstanceDivs(nodesList) {
    var nodesMap = nodesList.reduce(function (map, node) {
        map[node.id] = node;
        return map;
    }, {});

    $("[data-fo-id]").each(function () {
        var id = $(this).attr("data-fo-id");
        $(this).html(
        	'

'
        );
    });
    nodesList.forEach(function (node) {
    	var popoverElement = $("[data-fo-id='" + node.id + "'] .popover");
    	renderInstanceElement(popoverElement, node, "cluster");
    });
    $("[data-fo-id]").each(
        function () {
            var id = $(this).attr("data-fo-id");
            var popoverDiv = $("[data-fo-id='" + id + "'] div.popover");

            popoverDiv.attr("x", $(this).attr("x"));
            $(this).attr("y",
                0 - popoverDiv.height() / 2 - 2);
            popoverDiv.attr("y", $(this).attr("y"));
            $(this).attr("width",
                popoverDiv.width() + 30);
            $(this).attr("height",
                popoverDiv.height() +16);
        });
    $("div.popover").popover();
    $("div.popover").show();

    $("[data-fo-id]").on("mouseenter", ".popover[data-nodeid]", function() {
    	if ($(".popover.instance[data-duplicate-node]").hasClass("ui-draggable-dragging")) {
    		// Do not remove & recreate while dragging. Ignore any mouseenter
    		return false;
    	}
    	var draggedNodeId = $(this).attr("data-nodeid");
    	if (draggedNodeId == $(".popover.instance[data-duplicate-node]").attr("data-nodeid")) {
    		return false;
    	}
    	$(".popover.instance[data-duplicate-node]").remove();
    	var duplicate = $(this).clone().appendTo("#cluster_container");
    	$(duplicate).attr("data-duplicate-node", "true");
    	//$(".popover.instance[data-duplicate-node] h3").addClass("label-primary");
    	$(duplicate).css({"margin-left": "0"});
    	$(duplicate).css($(this).offset());
    	$(duplicate).width($(this).width());
    	$(duplicate).height($(this).height());
    	$(duplicate).popover();
        $(duplicate).show();
        $(".popover.instance[data-duplicate-node] h3 a").click(function () {
        	openNodeModal(nodesMap[draggedNodeId]);
        	return false;
        });
        $(duplicate).draggable({
        	//scroll: true,
        	addClasses: true,
        	opacity: 0.67,
        	start: function(event, ui) {
        		//$(this).data("startingScrollTop",$(window).scrollTop());
        		$("#cluster_container .popover.instance").droppable({
        			accept: function(draggable) {
        				var draggedNode = nodesMap[draggedNodeId];
        				var targetNode = nodesMap[$(this).attr("data-nodeid")];
        				var acceptDrop =  moveInstance(draggedNode, targetNode, false);
        				if (acceptDrop) {
        					$(this).addClass("accept_drop");
        				}
        				return acceptDrop;
        			},
        			hoverClass: "draggable-hovers",
					drop: function( event, ui ) {
				        $(".popover.instance[data-duplicate-node]").remove();
				        moveInstance(nodesMap[draggedNodeId], nodesMap[$(this).attr("data-nodeid")], true);
					}
        		});
        	},
	    	drag: function(event, ui) {
	    		/*
	    		var st = parseInt($(this).data("startingScrollTop"));
	    		var offset = $(duplicate).offset();
	    		offset.top -= $(window).scrollTop();// - st;
	    		$(duplicate).css(offset);
	    		*/
	    	},
	    	stop: function(event, ui) {
        		$("#cluster_container .accept_drop").removeClass("accept_drop");
	    	}
        });
    	$(duplicate).on("mouseleave", function() {
    		if (!$(this).hasClass("ui-draggable-dragging")) {
	        	//$(".popover.instance[data-duplicate-node]").remove();
	    		$(this).remove();
    		}
    	});
    });
}

function moveInstance(node, droppableNode, shouldApply) {
	if (instancesAreSiblings(node, droppableNode)) {
		if (node.hasProblem || droppableNode.hasProblem) {
			return false;
		}
		if (shouldApply) {
			moveBelow(node, droppableNode);
		}
		return true;
	}
	if (instanceIsGrandchild(node, droppableNode)) {
		if (node.hasProblem) {
			return false;
		}
		if (shouldApply) {
			moveUp(node, droppableNode);
		}
		return true;
	}

	if (shouldApply) {
		addAlert(
				"Cannot move " +
					node.Key.Hostname + ":" + node.Key.Port +
					" under " +
					droppableNode.Key.Hostname + ":" + droppableNode.Key.Port +
					". " +
				"You may only move a node down below its sibling or up below its grandparent."
			);
	}
	return false;
}

function moveBelow(node, siblingNode) {
	var message = "Are you sure you wish to turn " +
		node.Key.Hostname + ":" + node.Key.Port +
		" into a slave of " +
		siblingNode.Key.Hostname + ":" + siblingNode.Key.Port +
		"?";
	bootbox.confirm(message, function(confirm) {
		if (confirm) {
			showLoader();
			var apiUrl = "/api/move-below/" + node.Key.Hostname + "/" + node.Key.Port + "/" + siblingNode.Key.Hostname + "/" + siblingNode.Key.Port;
		    $.get(apiUrl, function (operationResult) {
	    			hideLoader();
	    			if (operationResult.Code == "ERROR") {
	    				addAlert(operationResult.Message)
	    			} else {
	    				location.reload();
	    			}
	            }, "json");
		}
	});
	return false;
}

function moveUp(node, grandparentNode) {
	var message = "Are you sure you wish to turn " +
		node.Key.Hostname + ":" + node.Key.Port +
		" into a slave of " +
		grandparentNode.Key.Hostname + ":" + grandparentNode.Key.Port +
		"?"
	bootbox.confirm(message, function(confirm) {
		if (confirm) {
			showLoader();
			var apiUrl = "/api/move-up/" + node.Key.Hostname + "/" + node.Key.Port;
		    $.get(apiUrl, function (operationResult) {
	    			hideLoader();
	    			if (operationResult.Code == "ERROR") {
	    				addAlert(operationResult.Message)
	    			} else {
	    				location.reload();
	    			}
	            }, "json");
		}
	});
	return false;
}

function instancesAreSiblings(node1, node2) {
	if (node1.id == node2.id) return false;
	if (node1.parent == null ) return false;
	if (node2.parent == null ) return false;
	if (node1.parent.id != node2.parent.id) return false;
	return true;
}

function instanceIsGrandchild(node, grandparentNode, nodesMap) {
	if (!node.hasMaster) {
		return false;
	}
	var parentNode = node.parent;
	if (!parentNode.hasMaster) {
		return false;
	}
	if (parentNode.parent.id != grandparentNode.id) {
		return false;
	}
	return true;
}

$(document)
    .ready(
        function () {

            $.get("/api/cluster/"+currentClusterName(), function (instances) {
                $.get("/api/maintenance",
                    function (maintenanceList) {
                		var instancesMap = normalizeInstances(instances, maintenanceList);
                        visualizeInstances(instances, instancesMap);
                        generateInstanceDivs(instances);
                    }, "json");
            }, "json");
        });
<commit_msg>patched solution for crazy jqueryui behavior on click (used to assign draggable classes)<commit_after>
function generateInstanceDivs(nodesList) {
    var nodesMap = nodesList.reduce(function (map, node) {
        map[node.id] = node;
        return map;
    }, {});

    $("[data-fo-id]").each(function () {
        var id = $(this).attr("data-fo-id");
        $(this).html(
        	'

'
        );
    });
    nodesList.forEach(function (node) {
    	var popoverElement = $("[data-fo-id='" + node.id + "'] .popover");
    	renderInstanceElement(popoverElement, node, "cluster");
    });
    $("[data-fo-id]").each(
        function () {
            var id = $(this).attr("data-fo-id");
            var popoverDiv = $("[data-fo-id='" + id + "'] div.popover");

            popoverDiv.attr("x", $(this).attr("x"));
            $(this).attr("y",
                0 - popoverDiv.height() / 2 - 2);
            popoverDiv.attr("y", $(this).attr("y"));
            $(this).attr("width",
                popoverDiv.width() + 30);
            $(this).attr("height",
                popoverDiv.height() +16);
        });
    $("div.popover").popover();
    $("div.popover").show();

    $("[data-fo-id]").on("mouseenter", ".popover[data-nodeid]", function() {
    	if ($(".popover.instance[data-duplicate-node]").hasClass("ui-draggable-dragging")) {
    		// Do not remove & recreate while dragging. Ignore any mouseenter
    		return false;
    	}
    	var draggedNodeId = $(this).attr("data-nodeid");
    	if (draggedNodeId == $(".popover.instance[data-duplicate-node]").attr("data-nodeid")) {
    		return false;
    	}
    	$(".popover.instance[data-duplicate-node]").remove();
    	var duplicate = $(this).clone().appendTo("#cluster_container");
    	$(duplicate).attr("data-duplicate-node", "true");
    	//$(".popover.instance[data-duplicate-node] h3").addClass("label-primary");
    	$(duplicate).css({"margin-left": "0"});
    	$(duplicate).css($(this).offset());
    	$(duplicate).width($(this).width());
    	$(duplicate).height($(this).height());
    	$(duplicate).popover();
        $(duplicate).show();
        $(".popover.instance[data-duplicate-node] h3 a").click(function () {
        	openNodeModal(nodesMap[draggedNodeId]);
        	return false;
        });
        $(duplicate).draggable({
        	addClasses: true,
        	opacity: 0.67,
        	cancel: "#cluster_container .popover.instance h3 a",
        	start: function(event, ui) {
        		$("#cluster_container .accept_drop").removeClass("accept_drop");
        		$("#cluster_container .popover.instance").droppable({
        			accept: function(draggable) {
        				var draggedNode = nodesMap[draggedNodeId];
        				var targetNode = nodesMap[$(this).attr("data-nodeid")];
        				var acceptDrop =  moveInstance(draggedNode, targetNode, false);
        				if (acceptDrop) {
        					$(this).addClass("accept_drop");
        				}
        				return acceptDrop;
        			},
        			hoverClass: "draggable-hovers",
					drop: function( event, ui ) {
				        $(".popover.instance[data-duplicate-node]").remove();
				        moveInstance(nodesMap[draggedNodeId], nodesMap[$(this).attr("data-nodeid")], true);
					}
        		});
        	},
	    	drag: function(event, ui) {
	    	},
	    	stop: function(event, ui) {
        		$("#cluster_container .accept_drop").removeClass("accept_drop");
	    	}
        });
    	$(duplicate).on("mouseleave", function() {
    		if (!$(this).hasClass("ui-draggable-dragging")) {
	    		$(this).remove();
    		}
    	});
    	// Don't ask why the following... jqueryUI recognizes the click as start drag, but fails to stop...
    	$(duplicate).on("click", function() {
        	$("#cluster_container .accept_drop").removeClass("accept_drop");
        	return false;
        });
    });
}

function moveInstance(node, droppableNode, shouldApply) {
	if (instancesAreSiblings(node, droppableNode)) {
		if (node.hasProblem || droppableNode.hasProblem) {
			return false;
		}
		if (shouldApply) {
			moveBelow(node, droppableNode);
		}
		return true;
	}
	if (instanceIsGrandchild(node, droppableNode)) {
		if (node.hasProblem) {
			return false;
		}
		if (shouldApply) {
			moveUp(node, droppableNode);
		}
		return true;
	}

	if (shouldApply) {
		addAlert(
				"Cannot move " +
					node.Key.Hostname + ":" + node.Key.Port +
					" under " +
					droppableNode.Key.Hostname + ":" + droppableNode.Key.Port +
					". " +
				"You may only move a node down below its sibling or up below its grandparent."
			);
	}
	return false;
}

function moveBelow(node, siblingNode) {
	var message = "Are you sure you wish to turn " +
		node.Key.Hostname + ":" + node.Key.Port +
		" into a slave of " +
		siblingNode.Key.Hostname + ":" + siblingNode.Key.Port +
		"?";
	bootbox.confirm(message, function(confirm) {
		if (confirm) {
			showLoader();
			var apiUrl = "/api/move-below/" + node.Key.Hostname + "/" + node.Key.Port + "/" + siblingNode.Key.Hostname + "/" + siblingNode.Key.Port;
		    $.get(apiUrl, function (operationResult) {
	    			hideLoader();
	    			if (operationResult.Code == "ERROR") {
	    				addAlert(operationResult.Message)
	    			} else {
	    				location.reload();
	    			}
	            }, "json");
		}
	});
	return false;
}

function moveUp(node, grandparentNode) {
	var message = "Are you sure you wish to turn " +
		node.Key.Hostname + ":" + node.Key.Port +
		" into a slave of " +
		grandparentNode.Key.Hostname + ":" + grandparentNode.Key.Port +
		"?"
	bootbox.confirm(message, function(confirm) {
		if (confirm) {
			showLoader();
			var apiUrl = "/api/move-up/" + node.Key.Hostname + "/" + node.Key.Port;
		    $.get(apiUrl, function (operationResult) {
	    			hideLoader();
	    			if (operationResult.Code == "ERROR") {
	    				addAlert(operationResult.Message)
	    			} else {
	    				location.reload();
	    			}
	            }, "json");
		}
	});
	return false;
}

function instancesAreSiblings(node1, node2) {
	if (node1.id == node2.id) return false;
	if (node1.parent == null ) return false;
	if (node2.parent == null ) return false;
	if (node1.parent.id != node2.parent.id) return false;
	return true;
}

function instanceIsGrandchild(node, grandparentNode, nodesMap) {
	if (!node.hasMaster) {
		return false;
	}
	var parentNode = node.parent;
	if (!parentNode.hasMaster) {
		return false;
	}
	if (parentNode.parent.id != grandparentNode.id) {
		return false;
	}
	return true;
}

$(document)
    .ready(
        function () {

            $.get("/api/cluster/"+currentClusterName(), function (instances) {
                $.get("/api/maintenance",
                    function (maintenanceList) {
                		var instancesMap = normalizeInstances(instances, maintenanceList);
                        visualizeInstances(instances, instancesMap);
                        generateInstanceDivs(instances);
                    }, "json");
            }, "json");
        });
<|endoftext|>


<commit_before>angular.module("leaflet-directive").factory('leafletLayerHelpers', function ($rootScope, $log, leafletHelpers) {
    var Helpers = leafletHelpers,
        isString = leafletHelpers.isString,
        isObject = leafletHelpers.isObject,
        isDefined = leafletHelpers.isDefined;

    var utfGridCreateLayer = function(params) {
        if (!Helpers.UTFGridPlugin.isLoaded()) {
            $log.error('[AngularJS - Leaflet] The UTFGrid plugin is not loaded.');
            return;
        }
        var utfgrid = new L.UtfGrid(params.url, params.pluginOptions);

        utfgrid.on('mouseover', function(e) {
            $rootScope.$broadcast('leafletDirectiveMap.utfgridMouseover', e);
        });

        utfgrid.on('mouseout', function(e) {
            $rootScope.$broadcast('leafletDirectiveMap.utfgridMouseout', e);
        });

        utfgrid.on('click', function(e) {
            $rootScope.$broadcast('leafletDirectiveMap.utfgridClick', e);
        });

        return utfgrid;
    };

    var layerTypes = {
        xyz: {
            mustHaveUrl: true,
            createLayer: function(params) {
                return L.tileLayer(params.url, params.options);
            }
        },
        mapbox: {
            mustHaveKey: true,
            createLayer: function(params) {
                var url = '//{s}.tiles.mapbox.com/v3/' + params.key + '/{z}/{x}/{y}.png';
                return L.tileLayer(url, params.options);
            }
        },
        geoJSON: {
            mustHaveUrl: true,
            createLayer: function(params) {
                if (!Helpers.GeoJSONPlugin.isLoaded()) {
                    return;
                }
                return new L.TileLayer.GeoJSON(params.url, params.pluginOptions, params.options);
            }
        },
        utfGrid: {
            mustHaveUrl: true,
            createLayer: utfGridCreateLayer
        },
        cartodbTiles: {
            mustHaveKey: true,
            createLayer: function(params) {
                var url = '//' + params.user + '.cartodb.com/api/v1/map/' + params.key + '/{z}/{x}/{y}.png';
                return L.tileLayer(url, params.options);
            }
        },
        cartodbUTFGrid: {
            mustHaveKey: true,
            mustHaveLayer : true,
            createLayer: function(params) {
                params.url = '//' + params.user + '.cartodb.com/api/v1/map/' + params.key + '/' + params.layer + '/{z}/{x}/{y}.grid.json';
                return utfGridCreateLayer(params);
            }
        },
        cartodbInteractive: {
            mustHaveKey: true,
            mustHaveLayer : true,
            createLayer: function(params) {
                var tilesURL = '//' + params.user + '.cartodb.com/api/v1/map/' + params.key + '/{z}/{x}/{y}.png';
                var tileLayer = L.tileLayer(tilesURL, params.options);
                params.url = '//' + params.user + '.cartodb.com/api/v1/map/' + params.key + '/' + params.layer + '/{z}/{x}/{y}.grid.json';
                var utfLayer = utfGridCreateLayer(params);
                return L.layerGroup([tileLayer, utfLayer]);
            }
        },
        wms: {
            mustHaveUrl: true,
            createLayer: function(params) {
                return L.tileLayer.wms(params.url, params.options);
            }
        },
        wmts: {
            mustHaveUrl: true,
            createLayer: function(params) {
                return L.tileLayer.wmts(params.url, params.options);
            }
        },
        wfs: {
            mustHaveUrl: true,
            mustHaveLayer : true,
            createLayer: function(params) {
                if (!Helpers.WFSLayerPlugin.isLoaded()) {
                    return;
                }
                var options = angular.copy(params.options);
                if(options.crs && 'string' === typeof options.crs) {
                    /*jshint -W061 */
                    options.crs = eval(options.crs);
                }
                return new L.GeoJSON.WFS(params.url, params.layer, options);
            }
        },
        group: {
            mustHaveUrl: false,
            createLayer: function (params) {
                var lyrs = [];
                angular.forEach(params.options.layers, function(l){
                  lyrs.push(createLayer(l));
                });
                return L.layerGroup(lyrs);
            }
        },
        featureGroup: {
            mustHaveUrl: false,
            createLayer: function () {
                return L.featureGroup();
            }
        },
        google: {
            mustHaveUrl: false,
            createLayer: function(params) {
                var type = params.type || 'SATELLITE';
                if (!Helpers.GoogleLayerPlugin.isLoaded()) {
                    return;
                }
                return new L.Google(type, params.options);
            }
        },
        china:{
            mustHaveUrl:false,
            createLayer:function(params){
                var type = params.type || '';
                if(!Helpers.ChinaLayerPlugin.isLoaded()){
                    return;
                }
                return L.tileLayer.chinaProvider(type, params.options);
            }
        },
        ags: {
            mustHaveUrl: true,
            createLayer: function(params) {
                if (!Helpers.AGSLayerPlugin.isLoaded()) {
                    return;
                }

                var options = angular.copy(params.options);
                angular.extend(options, {
                    url: params.url
                });
                var layer = new lvector.AGS(options);
                layer.onAdd = function(map) {
                    this.setMap(map);
                };
                layer.onRemove = function() {
                    this.setMap(null);
                };
                return layer;
            }
        },
        dynamic: {
            mustHaveUrl: true,
            createLayer: function(params) {
                if (!Helpers.DynamicMapLayerPlugin.isLoaded()) {
                    return;
                }
                return L.esri.dynamicMapLayer(params.url, params.options);
            }
        },
        markercluster: {
            mustHaveUrl: false,
            createLayer: function(params) {
                if (!Helpers.MarkerClusterPlugin.isLoaded()) {
                    $log.error('[AngularJS - Leaflet] The markercluster plugin is not loaded.');
                    return;
                }
                return new L.MarkerClusterGroup(params.options);
            }
        },
        bing: {
            mustHaveUrl: false,
            createLayer: function(params) {
                if (!Helpers.BingLayerPlugin.isLoaded()) {
                    return;
                }
                return new L.BingLayer(params.key, params.options);
            }
        },
        heatmap: {
            mustHaveUrl: false,
            mustHaveData: true,
            createLayer: function(params) {
                if (!Helpers.HeatMapLayerPlugin.isLoaded()) {
                    return;
                }
                var layer = new L.TileLayer.WebGLHeatMap(params.options);
                if (isDefined(params.data)) {
                    layer.setData(params.data);
                }

                return layer;
            }
        },
        yandex: {
            mustHaveUrl: false,
            createLayer: function(params) {
                var type = params.type || 'map';
                if (!Helpers.YandexLayerPlugin.isLoaded()) {
                    return;
                }
                return new L.Yandex(type, params.options);
            }
        },
        imageOverlay: {
            mustHaveUrl: true,
            mustHaveBounds : true,
            createLayer: function(params) {
                return L.imageOverlay(params.url, params.bounds, params.options);
            }
        },

        // This "custom" type is used to accept every layer that user want to define himself.
        // We can wrap these custom layers like heatmap or yandex, but it means a lot of work/code to wrap the world,
        // so we let user to define their own layer outside the directive,
        // and pass it on "createLayer" result for next processes
        custom: {
            createLayer: function (params) {
                if (params.layer instanceof L.Class) {
                    return angular.copy(params.layer);
                }
                else {
                    $log.error('[AngularJS - Leaflet] A custom layer must be a leaflet Class');
                }
            }
        },
        cartodb: {
            mustHaveUrl: true,
            createLayer: function(params) {
                return cartodb.createLayer(params.map, params.url);
            }
        }
    };

    function isValidLayerType(layerDefinition) {
        // Check if the baselayer has a valid type
        if (!isString(layerDefinition.type)) {
            $log.error('[AngularJS - Leaflet] A layer must have a valid type defined.');
            return false;
        }

        if (Object.keys(layerTypes).indexOf(layerDefinition.type) === -1) {
            $log.error('[AngularJS - Leaflet] A layer must have a valid type: ' + Object.keys(layerTypes));
            return false;
        }

        // Check if the layer must have an URL
        if (layerTypes[layerDefinition.type].mustHaveUrl && !isString(layerDefinition.url)) {
            $log.error('[AngularJS - Leaflet] A base layer must have an url');
            return false;
        }

        if (layerTypes[layerDefinition.type].mustHaveData && !isDefined(layerDefinition.data)) {
            $log.error('[AngularJS - Leaflet] The base layer must have a "data" array attribute');
            return false;
        }

        if(layerTypes[layerDefinition.type].mustHaveLayer && !isDefined(layerDefinition.layer)) {
            $log.error('[AngularJS - Leaflet] The type of layer ' + layerDefinition.type + ' must have an layer defined');
            return false;
        }

        if (layerTypes[layerDefinition.type].mustHaveBounds && !isDefined(layerDefinition.bounds)) {
            $log.error('[AngularJS - Leaflet] The type of layer ' + layerDefinition.type + ' must have bounds defined');
            return false ;
        }

        if (layerTypes[layerDefinition.type].mustHaveKey && !isDefined(layerDefinition.key)) {
            $log.error('[AngularJS - Leaflet] The type of layer ' + layerDefinition.type + ' must have key defined');
            return false ;
        }
        return true;
    }

    function createLayer(layerDefinition) {
        if (!isValidLayerType(layerDefinition)) {
            return;
        }

        if (!isString(layerDefinition.name)) {
            $log.error('[AngularJS - Leaflet] A base layer must have a name');
            return;
        }
        if (!isObject(layerDefinition.layerParams)) {
            layerDefinition.layerParams = {};
        }
        if (!isObject(layerDefinition.layerOptions)) {
            layerDefinition.layerOptions = {};
        }

        // Mix the layer specific parameters with the general Leaflet options. Although this is an overhead
        // the definition of a base layers is more 'clean' if the two types of parameters are differentiated
        for (var attrname in layerDefinition.layerParams) {
            layerDefinition.layerOptions[attrname] = layerDefinition.layerParams[attrname];
        }

        var params = {
            url: layerDefinition.url,
            data: layerDefinition.data,
            options: layerDefinition.layerOptions,
            layer: layerDefinition.layer,
            type: layerDefinition.layerType,
            bounds: layerDefinition.bounds,
            key: layerDefinition.key,
            pluginOptions: layerDefinition.pluginOptions,
            user: layerDefinition.user
        };

        //TODO Add $watch to the layer properties
        return layerTypes[layerDefinition.type].createLayer(params);
    };

    return {
        createLayer: createLayer
    };
});<commit_msg>removed uneeded semi-colon<commit_after>angular.module("leaflet-directive").factory('leafletLayerHelpers', function ($rootScope, $log, leafletHelpers) {
    var Helpers = leafletHelpers,
        isString = leafletHelpers.isString,
        isObject = leafletHelpers.isObject,
        isDefined = leafletHelpers.isDefined;

    var utfGridCreateLayer = function(params) {
        if (!Helpers.UTFGridPlugin.isLoaded()) {
            $log.error('[AngularJS - Leaflet] The UTFGrid plugin is not loaded.');
            return;
        }
        var utfgrid = new L.UtfGrid(params.url, params.pluginOptions);

        utfgrid.on('mouseover', function(e) {
            $rootScope.$broadcast('leafletDirectiveMap.utfgridMouseover', e);
        });

        utfgrid.on('mouseout', function(e) {
            $rootScope.$broadcast('leafletDirectiveMap.utfgridMouseout', e);
        });

        utfgrid.on('click', function(e) {
            $rootScope.$broadcast('leafletDirectiveMap.utfgridClick', e);
        });

        return utfgrid;
    };

    var layerTypes = {
        xyz: {
            mustHaveUrl: true,
            createLayer: function(params) {
                return L.tileLayer(params.url, params.options);
            }
        },
        mapbox: {
            mustHaveKey: true,
            createLayer: function(params) {
                var url = '//{s}.tiles.mapbox.com/v3/' + params.key + '/{z}/{x}/{y}.png';
                return L.tileLayer(url, params.options);
            }
        },
        geoJSON: {
            mustHaveUrl: true,
            createLayer: function(params) {
                if (!Helpers.GeoJSONPlugin.isLoaded()) {
                    return;
                }
                return new L.TileLayer.GeoJSON(params.url, params.pluginOptions, params.options);
            }
        },
        utfGrid: {
            mustHaveUrl: true,
            createLayer: utfGridCreateLayer
        },
        cartodbTiles: {
            mustHaveKey: true,
            createLayer: function(params) {
                var url = '//' + params.user + '.cartodb.com/api/v1/map/' + params.key + '/{z}/{x}/{y}.png';
                return L.tileLayer(url, params.options);
            }
        },
        cartodbUTFGrid: {
            mustHaveKey: true,
            mustHaveLayer : true,
            createLayer: function(params) {
                params.url = '//' + params.user + '.cartodb.com/api/v1/map/' + params.key + '/' + params.layer + '/{z}/{x}/{y}.grid.json';
                return utfGridCreateLayer(params);
            }
        },
        cartodbInteractive: {
            mustHaveKey: true,
            mustHaveLayer : true,
            createLayer: function(params) {
                var tilesURL = '//' + params.user + '.cartodb.com/api/v1/map/' + params.key + '/{z}/{x}/{y}.png';
                var tileLayer = L.tileLayer(tilesURL, params.options);
                params.url = '//' + params.user + '.cartodb.com/api/v1/map/' + params.key + '/' + params.layer + '/{z}/{x}/{y}.grid.json';
                var utfLayer = utfGridCreateLayer(params);
                return L.layerGroup([tileLayer, utfLayer]);
            }
        },
        wms: {
            mustHaveUrl: true,
            createLayer: function(params) {
                return L.tileLayer.wms(params.url, params.options);
            }
        },
        wmts: {
            mustHaveUrl: true,
            createLayer: function(params) {
                return L.tileLayer.wmts(params.url, params.options);
            }
        },
        wfs: {
            mustHaveUrl: true,
            mustHaveLayer : true,
            createLayer: function(params) {
                if (!Helpers.WFSLayerPlugin.isLoaded()) {
                    return;
                }
                var options = angular.copy(params.options);
                if(options.crs && 'string' === typeof options.crs) {
                    /*jshint -W061 */
                    options.crs = eval(options.crs);
                }
                return new L.GeoJSON.WFS(params.url, params.layer, options);
            }
        },
        group: {
            mustHaveUrl: false,
            createLayer: function (params) {
                var lyrs = [];
                angular.forEach(params.options.layers, function(l){
                  lyrs.push(createLayer(l));
                });
                return L.layerGroup(lyrs);
            }
        },
        featureGroup: {
            mustHaveUrl: false,
            createLayer: function () {
                return L.featureGroup();
            }
        },
        google: {
            mustHaveUrl: false,
            createLayer: function(params) {
                var type = params.type || 'SATELLITE';
                if (!Helpers.GoogleLayerPlugin.isLoaded()) {
                    return;
                }
                return new L.Google(type, params.options);
            }
        },
        china:{
            mustHaveUrl:false,
            createLayer:function(params){
                var type = params.type || '';
                if(!Helpers.ChinaLayerPlugin.isLoaded()){
                    return;
                }
                return L.tileLayer.chinaProvider(type, params.options);
            }
        },
        ags: {
            mustHaveUrl: true,
            createLayer: function(params) {
                if (!Helpers.AGSLayerPlugin.isLoaded()) {
                    return;
                }

                var options = angular.copy(params.options);
                angular.extend(options, {
                    url: params.url
                });
                var layer = new lvector.AGS(options);
                layer.onAdd = function(map) {
                    this.setMap(map);
                };
                layer.onRemove = function() {
                    this.setMap(null);
                };
                return layer;
            }
        },
        dynamic: {
            mustHaveUrl: true,
            createLayer: function(params) {
                if (!Helpers.DynamicMapLayerPlugin.isLoaded()) {
                    return;
                }
                return L.esri.dynamicMapLayer(params.url, params.options);
            }
        },
        markercluster: {
            mustHaveUrl: false,
            createLayer: function(params) {
                if (!Helpers.MarkerClusterPlugin.isLoaded()) {
                    $log.error('[AngularJS - Leaflet] The markercluster plugin is not loaded.');
                    return;
                }
                return new L.MarkerClusterGroup(params.options);
            }
        },
        bing: {
            mustHaveUrl: false,
            createLayer: function(params) {
                if (!Helpers.BingLayerPlugin.isLoaded()) {
                    return;
                }
                return new L.BingLayer(params.key, params.options);
            }
        },
        heatmap: {
            mustHaveUrl: false,
            mustHaveData: true,
            createLayer: function(params) {
                if (!Helpers.HeatMapLayerPlugin.isLoaded()) {
                    return;
                }
                var layer = new L.TileLayer.WebGLHeatMap(params.options);
                if (isDefined(params.data)) {
                    layer.setData(params.data);
                }

                return layer;
            }
        },
        yandex: {
            mustHaveUrl: false,
            createLayer: function(params) {
                var type = params.type || 'map';
                if (!Helpers.YandexLayerPlugin.isLoaded()) {
                    return;
                }
                return new L.Yandex(type, params.options);
            }
        },
        imageOverlay: {
            mustHaveUrl: true,
            mustHaveBounds : true,
            createLayer: function(params) {
                return L.imageOverlay(params.url, params.bounds, params.options);
            }
        },

        // This "custom" type is used to accept every layer that user want to define himself.
        // We can wrap these custom layers like heatmap or yandex, but it means a lot of work/code to wrap the world,
        // so we let user to define their own layer outside the directive,
        // and pass it on "createLayer" result for next processes
        custom: {
            createLayer: function (params) {
                if (params.layer instanceof L.Class) {
                    return angular.copy(params.layer);
                }
                else {
                    $log.error('[AngularJS - Leaflet] A custom layer must be a leaflet Class');
                }
            }
        },
        cartodb: {
            mustHaveUrl: true,
            createLayer: function(params) {
                return cartodb.createLayer(params.map, params.url);
            }
        }
    };

    function isValidLayerType(layerDefinition) {
        // Check if the baselayer has a valid type
        if (!isString(layerDefinition.type)) {
            $log.error('[AngularJS - Leaflet] A layer must have a valid type defined.');
            return false;
        }

        if (Object.keys(layerTypes).indexOf(layerDefinition.type) === -1) {
            $log.error('[AngularJS - Leaflet] A layer must have a valid type: ' + Object.keys(layerTypes));
            return false;
        }

        // Check if the layer must have an URL
        if (layerTypes[layerDefinition.type].mustHaveUrl && !isString(layerDefinition.url)) {
            $log.error('[AngularJS - Leaflet] A base layer must have an url');
            return false;
        }

        if (layerTypes[layerDefinition.type].mustHaveData && !isDefined(layerDefinition.data)) {
            $log.error('[AngularJS - Leaflet] The base layer must have a "data" array attribute');
            return false;
        }

        if(layerTypes[layerDefinition.type].mustHaveLayer && !isDefined(layerDefinition.layer)) {
            $log.error('[AngularJS - Leaflet] The type of layer ' + layerDefinition.type + ' must have an layer defined');
            return false;
        }

        if (layerTypes[layerDefinition.type].mustHaveBounds && !isDefined(layerDefinition.bounds)) {
            $log.error('[AngularJS - Leaflet] The type of layer ' + layerDefinition.type + ' must have bounds defined');
            return false ;
        }

        if (layerTypes[layerDefinition.type].mustHaveKey && !isDefined(layerDefinition.key)) {
            $log.error('[AngularJS - Leaflet] The type of layer ' + layerDefinition.type + ' must have key defined');
            return false ;
        }
        return true;
    }

    function createLayer(layerDefinition) {
        if (!isValidLayerType(layerDefinition)) {
            return;
        }

        if (!isString(layerDefinition.name)) {
            $log.error('[AngularJS - Leaflet] A base layer must have a name');
            return;
        }
        if (!isObject(layerDefinition.layerParams)) {
            layerDefinition.layerParams = {};
        }
        if (!isObject(layerDefinition.layerOptions)) {
            layerDefinition.layerOptions = {};
        }

        // Mix the layer specific parameters with the general Leaflet options. Although this is an overhead
        // the definition of a base layers is more 'clean' if the two types of parameters are differentiated
        for (var attrname in layerDefinition.layerParams) {
            layerDefinition.layerOptions[attrname] = layerDefinition.layerParams[attrname];
        }

        var params = {
            url: layerDefinition.url,
            data: layerDefinition.data,
            options: layerDefinition.layerOptions,
            layer: layerDefinition.layer,
            type: layerDefinition.layerType,
            bounds: layerDefinition.bounds,
            key: layerDefinition.key,
            pluginOptions: layerDefinition.pluginOptions,
            user: layerDefinition.user
        };

        //TODO Add $watch to the layer properties
        return layerTypes[layerDefinition.type].createLayer(params);
    }

    return {
        createLayer: createLayer
    };
});
<|endoftext|>


<commit_before>var lastClicked;
elements = [];
intervalId = 0;

var grid = clickableGrid(10, 10, function(el, row, col, i){
    clear();
    el.className='clicked';

    dfs({'x': row,
         'y': col});
});

document.body.appendChild(grid);

function clear(){
    elements = [];
    clearInterval(intervalId);

    var selectedElements = document.getElementsByClassName('clicked');
    var i, len = selectedElements.length;
    for(i = 0; i < len; i++)
        selectedElements[0].className = '';
}

function clickableGrid(rows, cols, callback ){
    var i = 0;
    var grid = document.createElement('table');
    grid.className = 'grid';

    for (var r = 0; r < rows; ++r){
        var tr = grid.appendChild(document.createElement('tr'));

        for (var c = 0; c<cols; ++c){
            var cell = tr.appendChild(document.createElement('td'));
            cell.innerHTML = ++i;
            cell.id = i;
            cell.addEventListener('click', (function(el, r, c, i){
                return function(){
                    callback(el, r, c, i);
                }
            })(cell, r, c, i),false);
        }
    }
    return grid;
}

function neighbors(item) {
    var n = [];

    for (var i = -1; i < 2; i++) {
        for (var j = -1; j < 2; j++) {
            n.push({
                'x': i+item['x'],
                'y': j+item['y']
            });
        }
    }

    return n;
}

function dfs(start){
    var search = document.getElementsByName('search');
    search = search[0].checked? "bfs": "dfs";

    var stack = [start];
    var item;
    var visited = {};

    visited[JSON.stringify(start)] = 1;

    while (stack.length != 0) {
        if (search == "bfs")
            // this is O(n), what madness!
            item = stack.shift();
        else
            item = stack.pop();

        if (item['x'] < 0 || item['x'] > 9)
            continue;

        if (item['y'] < 0 || item['y'] > 9)
            continue;

        //console.log(item['x'], item['y'], item['x']*10+item['y']+1);
        var el = document.getElementById(item['x']*10+item['y']+1);
        if (el != undefined) {
            elements.push(el);
        }

        var n = neighbors(item);
        for (var i in n) {
            if (visited[JSON.stringify(n[i])] != 1) {
                visited[JSON.stringify(n[i])] = 1;
                stack.push(n[i]);
            }
        }
    }

    elements.reverse();
    intervalId = window.setInterval(color, 25);
}

function color() {
    if (elements.length == 0){
        clearInterval(intervalId);
        return;
    }

    item = elements.pop();
    item.className = 'clicked';
}
<commit_msg>cleanup<commit_after>var lastClicked;
elements = [];
intervalId = 0;

var grid = clickableGrid(10, 10, function(el, row, col, i){
    clear();
    el.className='clicked';

    search({'x': row,
         'y': col});
});

document.body.appendChild(grid);

function clear(){
    elements = [];
    clearInterval(intervalId);

    var selectedElements = document.getElementsByClassName('clicked');
    var i, len = selectedElements.length;
    for(i = 0; i < len; i++)
        selectedElements[0].className = '';
}

function clickableGrid(rows, cols, callback ){
    var i = 0;
    var grid = document.createElement('table');
    grid.className = 'grid';

    for (var r = 0; r < rows; ++r){
        var tr = grid.appendChild(document.createElement('tr'));

        for (var c = 0; c<cols; ++c){
            var cell = tr.appendChild(document.createElement('td'));
            cell.innerHTML = ++i;
            cell.id = i;
            cell.addEventListener('click', (function(el, r, c, i){
                return function(){
                    callback(el, r, c, i);
                }
            })(cell, r, c, i),false);
        }
    }
    return grid;
}

function neighbors(item) {
    var n = [];

    for (var i = -1; i < 2; i++) {
        for (var j = -1; j < 2; j++) {
            n.push({
                'x': i+item['x'],
                'y': j+item['y']
            });
        }
    }

    return n;
}

function search(start){
    var search = document.getElementsByName('search');
    search = search[0].checked? "bfs": "dfs";

    var stack = [start];
    var item;
    var visited = {};

    visited[JSON.stringify(start)] = 1;

    while (stack.length != 0) {
        if (search == "bfs")
            // this is O(n), what madness!
            item = stack.shift();
        else
            item = stack.pop();

        if (item['x'] < 0 || item['x'] > 9)
            continue;

        if (item['y'] < 0 || item['y'] > 9)
            continue;

        var el = document.getElementById(item['x']*10 + item['y'] + 1);
        if (el != undefined) {
            elements.push(el);
        }

        var n = neighbors(item);
        for (var i in n) {
            if (visited[JSON.stringify(n[i])] != 1) {
                visited[JSON.stringify(n[i])] = 1;
                stack.push(n[i]);
            }
        }
    }

    elements.reverse();
    intervalId = window.setInterval(color, 25);
}

function color() {
    if (elements.length == 0){
        clearInterval(intervalId);
        return;
    }

    item = elements.pop();
    item.className = 'clicked';
}
<|endoftext|>


<commit_before>/*
 * 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.
 */

//******************************
// Class FicheDetail
function FicheDetail() {
  var self = this;
  var detailSelector = null;
  var indiceElement = null;
  var idFiche = null;
  var objetFiche = null;

  var champsActif = null;

  var largeurImposee = 240;
  var hauteurImposee = 320;

  var imageToShare = null;

  // constructeur
  this.initialise = function(_parent, element) {
    self.parent = _parent;
    var vignette = $(element);
    self.indiceElement = vignette.attr('data-id');
    self.detailSelector = $('#detailManager');

    self.detailSelector.load('js/tpl/detail.html', function(){
      // récuperation de la fiche de l'élément
      var idElement = self.indiceElement;
      self.objetFiche = donneesJson[idElement];

      self.idFiche = self.objetFiche["id"];

      var titre = self.objetFiche["texte"].split('
')[0];
      var reg=new RegExp("(
)", "g")
      self.messagePerso = "";//elementVignette["texte"].replace(reg, ' ');

      var imagePreview = cdn_visuel+'images/preview/'+self.objetFiche["preview"];
      var imageVierge = cdn_visuel+'images/image/'+self.objetFiche["preview"];

      // customisation de la fiche detail
      //self.detailSelector.find('.titre').html('
'+titre+'...
');
      self.detailSelector.find('.titre').html('

');

      // modification dimension en fonction du téléphone
      var hauteurElementsUI = 131;
      var hauteurPossible = window.innerHeight - hauteurElementsUI;
      var largeurPossible = window.innerWidth;

      self.largeurImposee = 240;
      self.hauteurImposee = 320;

      if(largeurPossible > 300){
        if(hauteurPossible > 400){
          largeurImposee = 300;
          hauteurImposee = 400;
        }
      }

      self.detailSelector.find('.visuel .wrapper').css({'width':self.largeurImposee, 'height':self.hauteurImposee});
      self.detailSelector.find('.visuel .wrapper').html('');

      // liaison des boutons
      self.detailSelector.find('.fermer a').bind('click', function(event){
        event.preventDefault();
        fermerDetail(element);
      });

      self.detailSelector.find('.editer a').bind('click', function(event){
        event.preventDefault();
        personnalisation(imageVierge);
      });

      self.detailSelector.find('.envoyer a').bind('click', function(event){
        event.preventDefault();
        if($(this).hasClass('share'))
        {
          self.imageToShare = cdn_visuel+'images/preview/'+donneesJson[idElement]["preview"];
          ouvreChoixPartage();//element,idElement);
        }/*else if($(this).hasClass('share-sms'))
        {
          ouvreChoixPartage(element,idElement);
        }else if($(this).hasClass('share-mail'))
        {
          envoiChoixParMail(element,idElement);
        }else if($(this).hasClass('share-fb'))
        {
          ouvreChoixPartage(element,idElement);
        }else if($(this).hasClass('share-tw'))
        {
          ouvreChoixPartage(element,idElement);
        }*/

        $.ajax({
                  type: 'POST',
                  url: webservice_stats,
                  data: {id:idShare},
                  async:true
                })

      });

      self.detailSelector.find('.envoyerPerso a').bind('click', function(event){
        event.preventDefault();
        if($(this).hasClass('sharePerso'))
        {
          var text1val = '';
          var text2val = '';

          if(self.detailSelector.find('.visuel .wrapper p.ligne1').length > 0)
          {
            text1val = self.detailSelector.find('.visuel .wrapper p.ligne1').html();
          }
          if(self.detailSelector.find('.visuel .wrapper p.ligne2').length > 0)
          {
            text1val = self.detailSelector.find('.visuel .wrapper p.ligne2').html();
          }

          $.ajax({
                  type: 'POST',
                  url: webservice_perso,
                  data: {id:idShare, text1:text1val, text2:text2val},
                  async:true
                }).done(function(objJSon){

                  if(objJSon["contenu"].length > 0)
                  {
                    self.imageToShare = objJSon["contenu"]["urlImagePerso"];
                    ouvreChoixPartage();

                    objJSon = null;
                  }

              }
            );
        }

        $.ajax({
                  type: 'POST',
                  url: webservice_stats,
                  data: {id:idShare, p:1},
                  async:true
                });

      });

      self.detailSelector.addClass('affiche');
      self.detailSelector.height(window.innerHeight);
      self.detailSelector.animate({'opacity':1},500);
    });

  };

  function fermerDetail(element){
    // désactive navigation
    self.parent.parent.menuNav.activeMenu();

    var vignette = $(element);
    vignette.removeClass('selected');

    self.detailSelector.animate({'opacity':0},500, function(){
      self.detailSelector.removeClass('affiche');
      self.detailSelector.find('.toolbox').css({'left':'0%','opacity':0});
      self.detailSelector.find('.toolboxPerso').css({'left':'100%','opacity':0});

      self.detailSelector.find('.fermer a').unbind('click');

      //vide detail
      self.detailSelector.html('');
    });
  }

  function ouvreChoixPartage() { //element,idElement){
    //var vignette = $(element);
    //var elementVignette = donneesJson[idElement];

        //window.plugins.socialsharing.share(null, null, imageToShare);
        var socialShare = window.plugins.socialsharing;
        socialShare.available(function(isAvailable) {
          if (isAvailable) {

            //var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];

            //self.messagePerso = '

Offrez, vous aussi, une bonne (ou mauvaise) résolution : wishit.freetouch.fr';
            self.messagePerso = "Offrez, vous aussi, une bonne (ou mauvaise) résolution";

            //share('message', 'sujet', 'image', 'site web');
            window.plugins.socialsharing.share(self.messagePerso, 'Bonne année et...', self.imageToShare, website_app);
          }
        });

  }

  function envoiChoixParSMS(){ //element,idElement){
    //var vignette = $(element);
    //var elementVignette = donneesJson[idElement];

    //var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];
    //var imageToShare = cdn_visuel+'images/preview/requin.jpg';
    //self.messagePerso, 'Meilleurs voeux 2014', imageToShare, website_app);
    //window.location.href = "sms:contactno?body=Meilleurs voeux 2014";
  }

  function envoiChoixParMail(element,idElement){
    /*var vignette = $(element);
    var elementVignette = donneesJson[idElement];

    var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];

    var mailShare = plugin.email;
    mailShare.isServiceAvailable(function(isAvailable) {
      if (isAvailable) {
        mailShare.open({
            to:      [],
            cc:      [],
            bcc:     [],
            subject: 'Bonne année et...',
            body:    '

Offrez, vous aussi, une bonne (ou mauvaise) résolution : wishit.freetouch.fr',
            isHtml:  true
        });
      }
    });
    */

  }

  function personnalisation(imageVierge){
    var zoneEdition = self.detailSelector.find('.visuel .wrapper');
    // mise en place du visuel vierge
    zoneEdition.find('img').attr('src',imageVierge);

    self.detailSelector.find('.toolbox').animate({'left':'-100%','opacity':0}, 500, function(){
      self.detailSelector.find('.toolboxPerso').animate({'left':'0%','opacity':1}, 500, function(){
        zoneEdition.append('
ceci est
');
        zoneEdition.append('
un texte
');

        // initialisation des outils
        self.detailSelector.find('.toolboxPerso a.alignGauche').bind('click', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            resetCss();
            $(self.champsActif).addClass("txt_gauche");
            $(this).addClass("actif");
          }
        });
        self.detailSelector.find('.toolboxPerso a.alignCentre').bind('click', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            resetCss();
            $(self.champsActif).addClass("txt_centre");
            $(this).addClass("actif");
          }
        });
        self.detailSelector.find('.toolboxPerso a.alignDroite').bind('click', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            resetCss();
            $(self.champsActif).addClass("txt_droite");
            $(this).addClass("actif");
          }
        });

        zoneEdition.find('.txt_editable').bind('click', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            $(self.champsActif).removeClass("txt_actif");
          }
          self.champsActif = this;
          $(self.champsActif).addClass("txt_actif");
        });
        zoneEdition.find('.txt_editable').bind('focus', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            $(self.champsActif).removeClass("txt_actif");
          }
          self.champsActif = this;
          $(self.champsActif).addClass("txt_actif");
        });

        zoneEdition.find('.txt_editable').bind('blur', function(event){
          event.preventDefault();
        });

        // libère les sélections pour afficher sans aucun élément actif
        zoneEdition.find('img').bind('click', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            $(self.champsActif).removeClass("txt_actif");
            self.champsActif = null;
          }
        });

      });
    });

  }

  function resetCss()
  {
    if(self.champsActif != null)
    {
      $(self.champsActif).removeClass("txt_gauche");
      $(self.champsActif).removeClass("txt_centre");
      $(self.champsActif).removeClass("txt_droite");
    }
    self.detailSelector.find('.toolboxPerso a').each(function(){
      $(this).removeClass("actif");
    });
  }

  /*function virtualKeyboardHeight() {
      var sx = document.body.scrollLeft, sy = document.body.scrollTop;
      var naturalHeight = window.innerHeight;
      window.scrollTo(sx, document.body.scrollHeight);
      var keyboardHeight = naturalHeight - window.innerHeight;
      window.scrollTo(sx, sy);
      return keyboardHeight;
  }*/

  /*
  function getViewport() {    // Note viewport sizing broken in Android 2.x see http://stackoverflow.com/questions/6601881/problem-with-meta-viewport-and-android
    var viewport = {
            left: window.pageXOffset || document.documentElement.scrollLeft || 0,    // http://www.quirksmode.org/mobile/tableViewport.html
            top: window.pageYOffset || document.documentElement.scrollTop || 0,
            width: window.innerWidth || document.documentElement.clientWidth,
            height: window.innerHeight || document.documentElement.clientHeight
    };
    //if (isTouchDevice && isInput(getActiveElement())) {     // iOS *lies* about viewport size when keyboard is visible. See http://stackoverflow.com/questions/2593139/ipad-web-app-detect-virtual-keyboard-using-javascript-in-safari Input focus/blur can indicate, also scrollTop:
        return {
            left: viewport.left,
            top: viewport.top,
            width: viewport.width,
            height: viewport.height * (viewport.height > viewport.width ? 0.66 : 0.45)  // Fudge factor to allow for keyboard on iPad
        };
    //}
    //return viewport;
  }*/
}<commit_msg>test debug image perso<commit_after>/*
 * 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.
 */

//******************************
// Class FicheDetail
function FicheDetail() {
  var self = this;
  var detailSelector = null;
  var indiceElement = null;
  var idFiche = null;
  var objetFiche = null;

  var champsActif = null;

  var largeurImposee = 240;
  var hauteurImposee = 320;

  var imageToShare = null;

  // constructeur
  this.initialise = function(_parent, element) {
    self.parent = _parent;
    var vignette = $(element);
    self.indiceElement = vignette.attr('data-id');
    self.detailSelector = $('#detailManager');

    self.detailSelector.load('js/tpl/detail.html', function(){
      // récuperation de la fiche de l'élément
      var idElement = self.indiceElement;
      self.objetFiche = donneesJson[idElement];

      self.idFiche = self.objetFiche["id"];

      var titre = self.objetFiche["texte"].split('
')[0];
      var reg=new RegExp("(
)", "g")
      self.messagePerso = "";//elementVignette["texte"].replace(reg, ' ');

      var imagePreview = cdn_visuel+'images/preview/'+self.objetFiche["preview"];
      var imageVierge = cdn_visuel+'images/image/'+self.objetFiche["preview"];

      // customisation de la fiche detail
      //self.detailSelector.find('.titre').html('
'+titre+'...
');
      self.detailSelector.find('.titre').html('

');

      // modification dimension en fonction du téléphone
      var hauteurElementsUI = 131;
      var hauteurPossible = window.innerHeight - hauteurElementsUI;
      var largeurPossible = window.innerWidth;

      self.largeurImposee = 240;
      self.hauteurImposee = 320;

      if(largeurPossible > 300){
        if(hauteurPossible > 400){
          largeurImposee = 300;
          hauteurImposee = 400;
        }
      }

      self.detailSelector.find('.visuel .wrapper').css({'width':self.largeurImposee, 'height':self.hauteurImposee});
      self.detailSelector.find('.visuel .wrapper').html('');

      // liaison des boutons
      self.detailSelector.find('.fermer a').bind('click', function(event){
        event.preventDefault();
        fermerDetail(element);
      });

      self.detailSelector.find('.editer a').bind('click', function(event){
        event.preventDefault();
        personnalisation(imageVierge);
      });

      self.detailSelector.find('.envoyer a').bind('click', function(event){
        event.preventDefault();
        if($(this).hasClass('share'))
        {
          self.imageToShare = cdn_visuel+'images/preview/'+donneesJson[idElement]["preview"];
          ouvreChoixPartage();//element,idElement);
        }/*else if($(this).hasClass('share-sms'))
        {
          ouvreChoixPartage(element,idElement);
        }else if($(this).hasClass('share-mail'))
        {
          envoiChoixParMail(element,idElement);
        }else if($(this).hasClass('share-fb'))
        {
          ouvreChoixPartage(element,idElement);
        }else if($(this).hasClass('share-tw'))
        {
          ouvreChoixPartage(element,idElement);
        }*/

        $.ajax({
                  type: 'POST',
                  url: webservice_stats,
                  data: {id:idShare},
                  async:true
                })

      });

      self.detailSelector.find('.envoyerPerso a').bind('click', function(event){
        event.preventDefault();
        if($(this).hasClass('sharePerso'))
        {
          var champs1 = self.detailSelector.find('.visuel .wrapper p.ligne1');
          var champs2 = self.detailSelector.find('.visuel .wrapper p.ligne2');

                  txt_gauche

          var text1val = '';
          var text2val = '';
          var align1 = 'c';
          var align2 = 'c';

          if(champs1.length > 0)
          {
            text1val = champs1.html();
            if(text1val.hasClass("txt_gauche")) { align1 = 'l'; }
            if(text1val.hasClass("txt_centre")) { align1 = 'c'; }
            if(text1val.hasClass("txt_droite")) { align1 = 'r'; }
          }
          if(champs2.length > 0)
          {
            text1val = champs2.html();
            if(text2val.hasClass("txt_gauche")) { align2 = 'l'; }
            if(text2val.hasClass("txt_centre")) { align2 = 'c'; }
            if(text2val.hasClass("txt_droite")) { align2 = 'r'; }
          }

          $.ajax({
                  type: 'POST',
                  url: webservice_perso,
                  data: {id:idShare, text1:text1val, a1:align1, text2:text2val, a2:align2},
                  async:true
                }).done(function(objJSon){

                  alert(objJSon["contenu"]);
                  alert(objJSon["contenu"][0]["urlImagePerso"]);
                  alert(objJSon["contenu"]["urlImagePerso"]);
                  if(objJSon["contenu"].length > 0)
                  {
                    self.imageToShare = objJSon["contenu"]["urlImagePerso"];
                    ouvreChoixPartage();

                    objJSon = null;
                  }

              }
            );
        }

        $.ajax({
                  type: 'POST',
                  url: webservice_stats,
                  data: {id:idShare, p:1},
                  async:true
                });

      });

      self.detailSelector.addClass('affiche');
      self.detailSelector.height(window.innerHeight);
      self.detailSelector.animate({'opacity':1},500);
    });

  };

  function fermerDetail(element){
    // désactive navigation
    self.parent.parent.menuNav.activeMenu();

    var vignette = $(element);
    vignette.removeClass('selected');

    self.detailSelector.animate({'opacity':0},500, function(){
      self.detailSelector.removeClass('affiche');
      self.detailSelector.find('.toolbox').css({'left':'0%','opacity':0});
      self.detailSelector.find('.toolboxPerso').css({'left':'100%','opacity':0});

      self.detailSelector.find('.fermer a').unbind('click');

      //vide detail
      self.detailSelector.html('');
    });
  }

  function ouvreChoixPartage() { //element,idElement){
    //var vignette = $(element);
    //var elementVignette = donneesJson[idElement];

        //window.plugins.socialsharing.share(null, null, imageToShare);
        var socialShare = window.plugins.socialsharing;
        socialShare.available(function(isAvailable) {
          if (isAvailable) {

            //var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];

            //self.messagePerso = '

Offrez, vous aussi, une bonne (ou mauvaise) résolution : wishit.freetouch.fr';
            self.messagePerso = "Offrez, vous aussi, une bonne (ou mauvaise) résolution";

            //share('message', 'sujet', 'image', 'site web');
            window.plugins.socialsharing.share(self.messagePerso, 'Bonne année et...', self.imageToShare, website_app);
          }
        });

  }

  function envoiChoixParSMS(){ //element,idElement){
    //var vignette = $(element);
    //var elementVignette = donneesJson[idElement];

    //var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];
    //var imageToShare = cdn_visuel+'images/preview/requin.jpg';
    //self.messagePerso, 'Meilleurs voeux 2014', imageToShare, website_app);
    //window.location.href = "sms:contactno?body=Meilleurs voeux 2014";
  }

  function envoiChoixParMail(element,idElement){
    /*var vignette = $(element);
    var elementVignette = donneesJson[idElement];

    var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];

    var mailShare = plugin.email;
    mailShare.isServiceAvailable(function(isAvailable) {
      if (isAvailable) {
        mailShare.open({
            to:      [],
            cc:      [],
            bcc:     [],
            subject: 'Bonne année et...',
            body:    '

Offrez, vous aussi, une bonne (ou mauvaise) résolution : wishit.freetouch.fr',
            isHtml:  true
        });
      }
    });
    */

  }

  function personnalisation(imageVierge){
    var zoneEdition = self.detailSelector.find('.visuel .wrapper');
    // mise en place du visuel vierge
    zoneEdition.find('img').attr('src',imageVierge);

    self.detailSelector.find('.toolbox').animate({'left':'-100%','opacity':0}, 500, function(){
      self.detailSelector.find('.toolboxPerso').animate({'left':'0%','opacity':1}, 500, function(){
        zoneEdition.append('
ceci est
');
        zoneEdition.append('
un texte
');

        // initialisation des outils
        self.detailSelector.find('.toolboxPerso a.alignGauche').bind('click', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            resetCss();
            $(self.champsActif).addClass("txt_gauche");
            $(this).addClass("actif");
          }
        });
        self.detailSelector.find('.toolboxPerso a.alignCentre').bind('click', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            resetCss();
            $(self.champsActif).addClass("txt_centre");
            $(this).addClass("actif");
          }
        });
        self.detailSelector.find('.toolboxPerso a.alignDroite').bind('click', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            resetCss();
            $(self.champsActif).addClass("txt_droite");
            $(this).addClass("actif");
          }
        });

        zoneEdition.find('.txt_editable').bind('click', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            $(self.champsActif).removeClass("txt_actif");
          }
          self.champsActif = this;
          $(self.champsActif).addClass("txt_actif");
        });
        zoneEdition.find('.txt_editable').bind('focus', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            $(self.champsActif).removeClass("txt_actif");
          }
          self.champsActif = this;
          $(self.champsActif).addClass("txt_actif");
        });

        zoneEdition.find('.txt_editable').bind('blur', function(event){
          event.preventDefault();
        });

        // libère les sélections pour afficher sans aucun élément actif
        zoneEdition.find('img').bind('click', function(event){
          event.preventDefault();
          if(self.champsActif != null)
          {
            $(self.champsActif).removeClass("txt_actif");
            self.champsActif = null;
          }
        });

      });
    });

  }

  function resetCss()
  {
    if(self.champsActif != null)
    {
      $(self.champsActif).removeClass("txt_gauche");
      $(self.champsActif).removeClass("txt_centre");
      $(self.champsActif).removeClass("txt_droite");
    }
    self.detailSelector.find('.toolboxPerso a').each(function(){
      $(this).removeClass("actif");
    });
  }

  /*function virtualKeyboardHeight() {
      var sx = document.body.scrollLeft, sy = document.body.scrollTop;
      var naturalHeight = window.innerHeight;
      window.scrollTo(sx, document.body.scrollHeight);
      var keyboardHeight = naturalHeight - window.innerHeight;
      window.scrollTo(sx, sy);
      return keyboardHeight;
  }*/

  /*
  function getViewport() {    // Note viewport sizing broken in Android 2.x see http://stackoverflow.com/questions/6601881/problem-with-meta-viewport-and-android
    var viewport = {
            left: window.pageXOffset || document.documentElement.scrollLeft || 0,    // http://www.quirksmode.org/mobile/tableViewport.html
            top: window.pageYOffset || document.documentElement.scrollTop || 0,
            width: window.innerWidth || document.documentElement.clientWidth,
            height: window.innerHeight || document.documentElement.clientHeight
    };
    //if (isTouchDevice && isInput(getActiveElement())) {     // iOS *lies* about viewport size when keyboard is visible. See http://stackoverflow.com/questions/2593139/ipad-web-app-detect-virtual-keyboard-using-javascript-in-safari Input focus/blur can indicate, also scrollTop:
        return {
            left: viewport.left,
            top: viewport.top,
            width: viewport.width,
            height: viewport.height * (viewport.height > viewport.width ? 0.66 : 0.45)  // Fudge factor to allow for keyboard on iPad
        };
    //}
    //return viewport;
  }*/
}<|endoftext|>