<commit_before>// Copyright 2002-2013, University of Colorado Boulder

/**
 * Scenery-based combo box. Composed of a button and a list of items.
 * The list of items is displayed when the button is pressed, and dismissed an item is selected
 * or the user clicks outside the list.  The list can be displayed either above or below the button.
 *

 * An item in the combo box had 2 properties: {Node} node, {*} value.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // imports
  var assert = require( 'ASSERT/assert' )( 'beers-law-lab' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Path = require( 'SCENERY/nodes/Path' );
  var Rectangle = require( 'SCENERY/nodes/Rectangle' );
  var Shape = require( 'KITE/Shape' );
  var Vector2 = require( 'DOT/Vector2' );

  /**
   * The button that is clicked to show the list of items.
   * @param {Node} itemNode
   * @param {*} options object with optional properties
   * @constructor
   */
  function ButtonNode( itemNode, options ) {
    var thisNode = this;
    Node.call( this );

    // up or down arrow
    var arrow = new Path( { fill: 'black' } );
    var arrowWidth = 0.5 * itemNode.height;
    var arrowHeight = arrowWidth * Math.sqrt( 3 ) / 2; // height of equilateral triangle
    if ( options.listPosition === 'above' ) {
      arrow.shape = new Shape().moveTo( 0, arrowHeight ).lineTo( arrowWidth / 2, 0 ).lineTo( arrowWidth, arrowHeight ).close(); // up arrow
    }
    else {
      arrow.shape = new Shape().moveTo( 0, 0 ).lineTo( arrowWidth, 0 ).lineTo( arrowWidth / 2, arrowHeight ).close(); // down arrow
    }

    // button background
    var width = itemNode.width + ( 2 * options.buttonXMargin ) + arrow.width + 5;
    var background = new Rectangle( 0, 0, width, itemNode.height + ( 2 * options.buttonYMargin ), options.buttonCornerRadius, options.buttonCornerRadius,
      { fill: options.buttonFill, stroke: options.buttonStroke, lineWidth: options.buttonLineWidth } );

    // itemNode's parent
    var itemNodeParent = new Node();

    thisNode.addChild( background );
    thisNode.addChild( arrow );
    thisNode.addChild( itemNodeParent );

    thisNode.setItemNode = function( itemNode ) {
      itemNodeParent.removeAllChildren();
      itemNodeParent.addChild( itemNode );
      itemNode.left = options.buttonXMargin;
      itemNode.top = options.buttonYMargin;
    };
    thisNode.setItemNode( itemNode );

    arrow.left = itemNode.right;
    arrow.centerY = background.centerY;
  }

  inherit( Node, ButtonNode );

  /**
   * A wrapper around the combo box item, adds margins, etc.
   * @param item
   * @param {Number} width
   * @param {Number} height
   * @param {Number} xMargin
   * @constructor
   */
  function ItemNode( item, width, height, xMargin ) {
    var thisNode = this;
    Rectangle.call( this, 0, 0, width, height );
    this.item = item;
    thisNode.addChild( item.node );
    item.node.x = xMargin;
    item.node.centerY = height / 2;
  }

  inherit( Rectangle, ItemNode );

  /**
   * @param {Array} items
   * @param {*} property
   * @param {*} options object with optional properties
   */
  function ComboBox( items, property, options ) {

    var thisNode = this;

    options = _.extend( {
        labelNode: null, // optional label, placed to the left of the combo box
        labelXSpacing: 10, // horizontal space between label and combo box
        // button
        buttonFill: 'white',
        buttonStroke: 'black',
        buttonLineWidth: 1,
        buttonCornerRadius: 3,
        buttonXMargin: 4,
        buttonYMargin: 4,
        // list
        listPosition: 'below', // where the list is positioned relative to the button, either 'below' or 'above'
        //TODO consider defaulting this to the scene, so that list can be guaranteed to be in front
        listParent: thisNode, // node that will be used as the list's parent, useful for ensuring that the list is in front of everything else
        listXMargin: 4,
        listYMargin: 4,
        listFill: 'white',
        listStroke: 'black',
        listLineWidth: 1,
        listCornerRadius: 5,
        // items
        itemXMargin: 6,
        itemYMargin: 6,
        itemHighlightFill: 'rgb(245,245,245)',
        itemHighlightStroke: null,
        itemHighlightLineWidth: 1
      },
      options );

    Node.call( thisNode, options );

    // optional label
    if ( options.labelNode !== null ) {
      thisNode.addChild( options.labelNode );
    }

    // determine uniform dimensions for button and list items
    var itemWidth = 0, itemHeight = 0;
    for ( var i = 0; i < items.length; i++ ) {
      var item = items[i];
      if ( item.node.width > itemWidth ) { itemWidth = item.node.width; }
      if ( item.node.height > itemHeight ) { itemHeight = item.node.height; }
    }
    itemWidth += ( 2 * options.itemXMargin );
    itemHeight += ( 2 * options.itemYMargin );

    // button, will be set to correct value when property observer is registered
    var buttonNode = new ButtonNode( new ItemNode( items[0], itemWidth, itemHeight, options.itemXMargin ), options );
    thisNode.addChild( buttonNode );

    // list
    var listWidth = itemWidth + ( 2 * options.listXMargin );
    var listHeight = ( items.length * itemHeight ) + ( 2 * options.listYMargin );
    var listNode = new Rectangle( 0, 0, listWidth, listHeight, options.listCornerRadius, options.listCornerRadius,
      { fill: options.listFill, stroke: options.listStroke, lineWidth: options.listLineWidth } );

    //TODO move these to ItemNode
    // how to highlight an item in the list
    var highlightItem = function( itemNode ) {
      itemNode.fill = options.itemHighlightFill;
      itemNode.stroke = options.itemHighlightStroke;
    };
    var unhighlightItem = function( itemNode ) {
      itemNode.fill = null;
      itemNode.stroke = null;
    };

    // listener that we'll attach to each item in the list
    var itemListener = {
      enter: function( event ) {
        highlightItem( event.currentTarget );
      },
      exit: function( event ) {
        unhighlightItem( event.currentTarget );
      },
      down: function( event ) {
        event.abort(); // prevent click-to-dismiss on the list
      },
      up: function( event ) {
        unhighlightItem( event.currentTarget );
        property.value = event.currentTarget.item.value; // set the property
        options.listParent.removeChild( listNode ); // close the list
        thisNode.getUniqueTrail().rootNode().removeInputListener( clickToDismissListener ); // remove the click-to-dismiss listener
        event.abort(); // prevent nodes (eg, controls) behind the list from receiving the event
      }
    };

    // populate list with items
    for ( var j = 0; j < items.length; j++ ) {
      // add item to list
      var itemNode = new ItemNode( items[j], itemWidth, itemHeight, options.itemXMargin );
      listNode.addChild( itemNode );
      itemNode.left = options.listXMargin;
      itemNode.top = options.listYMargin + ( j * itemHeight );

      // item interactivity
      itemNode.cursor = 'pointer';
      itemNode.addInputListener( itemListener );
    }

    // Handles the coordinate transform required to make the list pop up near the button.
    var moveList = function() {
      var xOffset = 0, yOffset = 0;
      if ( options.listParent !== thisNode ) {
        var pParentGlobal = options.listParent.localToGlobalPoint( options.listParent.translation );
        var pParentLocal = thisNode.globalToLocalPoint( pParentGlobal );
        xOffset = thisNode.x - pParentLocal.x;
        yOffset = thisNode.y - pParentLocal.y;
      }
      listNode.left = buttonNode.left + xOffset;
      if ( options.listPosition === 'above' ) {
        listNode.bottom = buttonNode.top + yOffset;
      }
      else {
        listNode.top = buttonNode.bottom + yOffset;
      }
    };

    /**
     * Because clickToDismissListener is added to the scene, it receives the 'down' event that
     * buttonNode received to register the listener. This is because scenery propagates events
     * up the event trail, and the scene is further up the trail than the button.  This flag
     * is used to ignore the first 'down' event, which is the one that the button received.
     * If we don't do this, then we never see the list because it is immediately popped down.
     * This behavior is may change, and is being discussed in scenery#58.
     */
    var enableClickToDismissListener;

    // listener for 'click outside to dismiss'
    var clickToDismissListener = {
      down: function( event ) {
        if ( enableClickToDismissListener ) {
          thisNode.getUniqueTrail().rootNode().removeInputListener( clickToDismissListener );
          options.listParent.removeChild( listNode );
        }
        else {
          enableClickToDismissListener = true;
        }
      }
    };

    // button interactivity
    buttonNode.cursor = 'pointer';
    buttonNode.addInputListener(
      {
        down: function( event ) {
          if ( !options.listParent.isChild( listNode ) ) {
            moveList();
            options.listParent.addChild( listNode );
            enableClickToDismissListener = false;
            thisNode.getUniqueTrail().rootNode().addInputListener( clickToDismissListener ); // add listener to scene
          }
        }
      } );

    // layout
    if ( options.labelNode ) {
      buttonNode.left = options.labelNode.right + options.labelXSpacing;
      buttonNode.centerY = options.labelNode.centerY;
    }

    // when property changes, update button
    property.link( function( value ) {
      // TODO brute force search, better way?
      var item = null;
      for ( var i = 0; i < items.length; i++ ) {
        if ( items[i].value === value ) {
          item = items[i];
        }
      }
      assert && assert( item !== null );
      buttonNode.setItemNode( new ItemNode( item, itemWidth, itemHeight, options.itemXMargin ) );
    } );
  }

  inherit( Node, ComboBox );

  /**
   * Creates a combo box item.
   * This exists primarily to document the structure of an item.
   * @param {Node} node
   * @param {*} value
   * @returns {{node: *, value: *}}
   */
  ComboBox.createItem = function( node, value ) {
    return { node: node, value: value };
  };

  return ComboBox;
} );<commit_msg>store the node that clickToDismissListener is added to,  because the scene may change, closes #14<commit_after>// Copyright 2002-2013, University of Colorado Boulder

/**
 * Scenery-based combo box. Composed of a button and a list of items.
 * The list of items is displayed when the button is pressed, and dismissed an item is selected
 * or the user clicks outside the list.  The list can be displayed either above or below the button.
 *

 * An item in the combo box had 2 properties: {Node} node, {*} value.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // imports
  var assert = require( 'ASSERT/assert' )( 'beers-law-lab' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Path = require( 'SCENERY/nodes/Path' );
  var Rectangle = require( 'SCENERY/nodes/Rectangle' );
  var Shape = require( 'KITE/Shape' );
  var Vector2 = require( 'DOT/Vector2' );

  /**
   * The button that is clicked to show the list of items.
   * @param {Node} itemNode
   * @param {*} options object with optional properties
   * @constructor
   */
  function ButtonNode( itemNode, options ) {
    var thisNode = this;
    Node.call( this );

    // up or down arrow
    var arrow = new Path( { fill: 'black' } );
    var arrowWidth = 0.5 * itemNode.height;
    var arrowHeight = arrowWidth * Math.sqrt( 3 ) / 2; // height of equilateral triangle
    if ( options.listPosition === 'above' ) {
      arrow.shape = new Shape().moveTo( 0, arrowHeight ).lineTo( arrowWidth / 2, 0 ).lineTo( arrowWidth, arrowHeight ).close(); // up arrow
    }
    else {
      arrow.shape = new Shape().moveTo( 0, 0 ).lineTo( arrowWidth, 0 ).lineTo( arrowWidth / 2, arrowHeight ).close(); // down arrow
    }

    // button background
    var width = itemNode.width + ( 2 * options.buttonXMargin ) + arrow.width + 5;
    var background = new Rectangle( 0, 0, width, itemNode.height + ( 2 * options.buttonYMargin ), options.buttonCornerRadius, options.buttonCornerRadius,
      { fill: options.buttonFill, stroke: options.buttonStroke, lineWidth: options.buttonLineWidth } );

    // itemNode's parent
    var itemNodeParent = new Node();

    thisNode.addChild( background );
    thisNode.addChild( arrow );
    thisNode.addChild( itemNodeParent );

    thisNode.setItemNode = function( itemNode ) {
      itemNodeParent.removeAllChildren();
      itemNodeParent.addChild( itemNode );
      itemNode.left = options.buttonXMargin;
      itemNode.top = options.buttonYMargin;
    };
    thisNode.setItemNode( itemNode );

    arrow.left = itemNode.right;
    arrow.centerY = background.centerY;
  }

  inherit( Node, ButtonNode );

  /**
   * A wrapper around the combo box item, adds margins, etc.
   * @param item
   * @param {Number} width
   * @param {Number} height
   * @param {Number} xMargin
   * @constructor
   */
  function ItemNode( item, width, height, xMargin ) {
    var thisNode = this;
    Rectangle.call( this, 0, 0, width, height );
    this.item = item;
    thisNode.addChild( item.node );
    item.node.x = xMargin;
    item.node.centerY = height / 2;
  }

  inherit( Rectangle, ItemNode );

  /**
   * @param {Array} items
   * @param {*} property
   * @param {*} options object with optional properties
   */
  function ComboBox( items, property, options ) {

    var thisNode = this;

    options = _.extend( {
        labelNode: null, // optional label, placed to the left of the combo box
        labelXSpacing: 10, // horizontal space between label and combo box
        // button
        buttonFill: 'white',
        buttonStroke: 'black',
        buttonLineWidth: 1,
        buttonCornerRadius: 3,
        buttonXMargin: 4,
        buttonYMargin: 4,
        // list
        listPosition: 'below', // where the list is positioned relative to the button, either 'below' or 'above'
        //TODO consider defaulting this to the scene, so that list can be guaranteed to be in front
        listParent: thisNode, // node that will be used as the list's parent, useful for ensuring that the list is in front of everything else
        listXMargin: 4,
        listYMargin: 4,
        listFill: 'white',
        listStroke: 'black',
        listLineWidth: 1,
        listCornerRadius: 5,
        // items
        itemXMargin: 6,
        itemYMargin: 6,
        itemHighlightFill: 'rgb(245,245,245)',
        itemHighlightStroke: null,
        itemHighlightLineWidth: 1
      },
      options );

    Node.call( thisNode, options );

    // optional label
    if ( options.labelNode !== null ) {
      thisNode.addChild( options.labelNode );
    }

    // determine uniform dimensions for button and list items
    var itemWidth = 0, itemHeight = 0;
    for ( var i = 0; i < items.length; i++ ) {
      var item = items[i];
      if ( item.node.width > itemWidth ) { itemWidth = item.node.width; }
      if ( item.node.height > itemHeight ) { itemHeight = item.node.height; }
    }
    itemWidth += ( 2 * options.itemXMargin );
    itemHeight += ( 2 * options.itemYMargin );

    // button, will be set to correct value when property observer is registered
    var buttonNode = new ButtonNode( new ItemNode( items[0], itemWidth, itemHeight, options.itemXMargin ), options );
    thisNode.addChild( buttonNode );

    // list
    var listWidth = itemWidth + ( 2 * options.listXMargin );
    var listHeight = ( items.length * itemHeight ) + ( 2 * options.listYMargin );
    var listNode = new Rectangle( 0, 0, listWidth, listHeight, options.listCornerRadius, options.listCornerRadius,
      { fill: options.listFill, stroke: options.listStroke, lineWidth: options.listLineWidth } );

    //TODO move these to ItemNode
    // how to highlight an item in the list
    var highlightItem = function( itemNode ) {
      itemNode.fill = options.itemHighlightFill;
      itemNode.stroke = options.itemHighlightStroke;
    };
    var unhighlightItem = function( itemNode ) {
      itemNode.fill = null;
      itemNode.stroke = null;
    };

    // listener that we'll attach to each item in the list
    var itemListener = {
      enter: function( event ) {
        highlightItem( event.currentTarget );
      },
      exit: function( event ) {
        unhighlightItem( event.currentTarget );
      },
      down: function( event ) {
        event.abort(); // prevent click-to-dismiss on the list
      },
      up: function( event ) {
        unhighlightItem( event.currentTarget );
        property.value = event.currentTarget.item.value; // set the property
        options.listParent.removeChild( listNode ); // close the list
        thisNode.getUniqueTrail().rootNode().removeInputListener( clickToDismissListener ); // remove the click-to-dismiss listener
        event.abort(); // prevent nodes (eg, controls) behind the list from receiving the event
      }
    };

    // populate list with items
    for ( var j = 0; j < items.length; j++ ) {
      // add item to list
      var itemNode = new ItemNode( items[j], itemWidth, itemHeight, options.itemXMargin );
      listNode.addChild( itemNode );
      itemNode.left = options.listXMargin;
      itemNode.top = options.listYMargin + ( j * itemHeight );

      // item interactivity
      itemNode.cursor = 'pointer';
      itemNode.addInputListener( itemListener );
    }

    // Handles the coordinate transform required to make the list pop up near the button.
    var moveList = function() {
      var xOffset = 0, yOffset = 0;
      if ( options.listParent !== thisNode ) {
        var pParentGlobal = options.listParent.localToGlobalPoint( options.listParent.translation );
        var pParentLocal = thisNode.globalToLocalPoint( pParentGlobal );
        xOffset = thisNode.x - pParentLocal.x;
        yOffset = thisNode.y - pParentLocal.y;
      }
      listNode.left = buttonNode.left + xOffset;
      if ( options.listPosition === 'above' ) {
        listNode.bottom = buttonNode.top + yOffset;
      }
      else {
        listNode.top = buttonNode.bottom + yOffset;
      }
    };

    /**
     * Because clickToDismissListener is added to the scene, it receives the 'down' event that
     * buttonNode received to register the listener. This is because scenery propagates events
     * up the event trail, and the scene is further up the trail than the button.  This flag
     * is used to ignore the first 'down' event, which is the one that the button received.
     * If we don't do this, then we never see the list because it is immediately popped down.
     * This behavior is may change, and is being discussed in scenery#58.
     */
    var enableClickToDismissListener;
    var sceneNode; // store the node that clickToDismissListener is added to, because the scene may change, see sun#14

    // listener for 'click outside to dismiss'
    var clickToDismissListener = {
      down: function( event ) {
        if ( enableClickToDismissListener ) {
          sceneNode.removeInputListener( clickToDismissListener );
          options.listParent.removeChild( listNode );
        }
        else {
          enableClickToDismissListener = true;
        }
      }
    };

    // button interactivity
    buttonNode.cursor = 'pointer';
    buttonNode.addInputListener(
      {
        down: function( event ) {
          if ( !options.listParent.isChild( listNode ) ) {
            moveList();
            options.listParent.addChild( listNode );
            enableClickToDismissListener = false;
            sceneNode = thisNode.getUniqueTrail().rootNode();
            sceneNode.addInputListener( clickToDismissListener ); // add listener to scene
          }
        }
      } );

    // layout
    if ( options.labelNode ) {
      buttonNode.left = options.labelNode.right + options.labelXSpacing;
      buttonNode.centerY = options.labelNode.centerY;
    }

    // when property changes, update button
    property.link( function( value ) {
      // TODO brute force search, better way?
      var item = null;
      for ( var i = 0; i < items.length; i++ ) {
        if ( items[i].value === value ) {
          item = items[i];
        }
      }
      assert && assert( item !== null );
      buttonNode.setItemNode( new ItemNode( item, itemWidth, itemHeight, options.itemXMargin ) );
    } );
  }

  inherit( Node, ComboBox );

  /**
   * Creates a combo box item.
   * This exists primarily to document the structure of an item.
   * @param {Node} node
   * @param {*} value
   * @returns {{node: *, value: *}}
   */
  ComboBox.createItem = function( node, value ) {
    return { node: node, value: value };
  };

  return ComboBox;
} );<|endoftext|>


<commit_before>(function (window, $, undefined) {

'use strict';

var graph       = window.setNamespace('app.graph'),
    transformer = window.use('app.transformer'),
    app         = window.use('app'),
    model       = window.use('app.model'),
    NodeEvent   = window.use('app.event.NodeEvent'),
    EdgeEvent   = window.use('app.event.EdgeEvent'),
    _defaults   = {
        host: 'localhost',
        port: 7474,
        version: 2,
    },
    self;

graph.API = app.createClass({

    construct: function (options) {

        this.options = $.extend({}, _defaults, options);

        self = this;
    },

    url: function (path) {
        var url = 'http://' + this.options.host;

        if (this.options.port) {
            url += ':' + this.options.port;
        }

        if (path) {
            url += path;
        }

        return url;
    },

    nodeUrl: function (id) {

        var path = '/db/data/node';

        if (id) {
            path += '/' + id;
        }

        return this.url(path);
    },

    edgeUrl: function (id) {

        var path = '/db/data/relationship';

        if (id) {
            path += '/' + id;
        }

        return this.url(path);
    },

    cypherUrl: function () {
        return this.url('/db/data/cypher');
    },

    initialize: function () {
        $(this.kernel).on(NodeEvent.CREATED, this.handleNodeCreated.bind(this));
        $(this.kernel).on(NodeEvent.DESTROYED, this.handleNodeDeleted.bind(this));
        $(this.kernel).on(EdgeEvent.CREATED, this.handleEdgeCreated.bind(this));
        $(this.kernel).on(EdgeEvent.DESTROYED, this.handleEdgeDeleted.bind(this));
        $(this.kernel).on(NodeEvent.UPDATED, this.handleNodeUpdated.bind(this));
        $(this.kernel).on(NodeEvent.UPDATED, this.handleNodeLabelUpdated.bind(this));
    },

    get: function (callback) {

        var nodeQuery = {
            query: 'START n=node(*) RETURN n, labels(n)',
            // query: 'START n=node(*) RETURN n',
            params: {}
        };
        var edgeQuery = {
            query: 'START r=relationship(*) RETURN r',
            params: {}
        };
        var url = this.cypherUrl();
        var graph;

        // TODO use promises
        $.post(url, nodeQuery)
         .done(function (nodeResult) {

        $.post(url, edgeQuery)
         .done(function (edgeResult) {

            graph = transformer.neo4j.from(nodeResult, edgeResult);

            callback(graph);
         });
        });
    },

    /**
     * Create a node in the neo4j database
     * Store the id to easily delete the node later
     */
    handleNodeCreated: function (event, data) {

        var url = this.nodeUrl(),
            props = transformer.neo4j.toNode(data);

        $.ajax({
            url: url,
            data: props,
            type: 'POST',
            async: false
        }).done(function (result) {
            data._id = transformer.neo4j.idFromSelf(result.self);
        });
    },

    /**
     * We're doing this with a cypher, because we also have to delete
     * all relationships
     */
    handleNodeDeleted: function (event, data) {

        var query,
            url = this.cypherUrl();

        // TODO this query should work, but can't find parameter nodeId
        // query = {
        //      "query" : "START n=node({nodeId}) OPTIONAL MATCH n-[r]-() DELETE n,r",
        //      "params" : {
        //          "nodeId": nodeId
        //  }
        // };
        query = {
            "query" : "START n=node("+data._id+") OPTIONAL MATCH n-[r]-() DELETE n,r",
            // "query" : "START n=node("+data._id+") MATCH n-[r?]-() DELETE n,r",
            "params" : {}
        };

        $.post(url, query);
    },

    handleEdgeCreated: function (event, data, source, target) {

        var url = this.nodeUrl(source._id) + '/relationships',
            props = {
                to: this.edgeUrl(target._id),
                type: data.type
            };

        $.post(url, props)
         .done(function (result) {
            data._id = transformer.neo4j.idFromSelf(result.self);
         });
    },

    handleEdgeDeleted: function (event, data) {

        var url = this.edgeUrl(data._id);

        $.ajax({
            url: url,
            type: 'DELETE'
        });
    },

    handleNodeUpdated: function (event, node, data, diff) {

        // check if a property was updated
        if (!model.Node.pathInDifference(diff, model.Node.getPropertiesPath())) {
            return;
        }

        console.log("handling node update");
        console.log(data._id);
        console.log(diff);

        var obj = transformer.neo4j.toNode(data),
            url = this.nodeUrl(data._id) + '/properties';

        $.ajax({
            url: url,
            type: 'PUT',
            data: obj
        });
    },

    /**
     * Removes all labels from the node and replaces them with the ones in data
     * @param data string or array<string>
     */
    handleNodeLabelUpdated: function (event, node, data, diff) {

        // check if a label was added or removed
        // TODO syntax needs some work...
        if (!model.Node.pathInDifference(diff, model.Node.getLabelsPath())) {
            return;
        }

        console.log("handling node label update");
        console.log(data._id);
        console.log(diff);

        var url = this.nodeUrl(data._id) + '/labels';

        $.ajax({
            url: url,
            type: 'PUT',
            contentType: 'application/json',
            data: JSON.stringify(data._labels)
        });
    }
});

}(window, jQuery));<commit_msg>better api update<commit_after>(function (window, $, undefined) {

'use strict';

var graph       = window.setNamespace('app.graph'),
    transformer = window.use('app.transformer'),
    app         = window.use('app'),
    model       = window.use('app.model'),
    NodeEvent   = window.use('app.event.NodeEvent'),
    EdgeEvent   = window.use('app.event.EdgeEvent'),
    _defaults   = {
        host: 'localhost',
        port: 7474,
        version: 2,
    },
    self;

graph.API = app.createClass({

    construct: function (options) {

        this.options = $.extend({}, _defaults, options);

        self = this;
    },

    url: function (path) {
        var url = 'http://' + this.options.host;

        if (this.options.port) {
            url += ':' + this.options.port;
        }

        if (path) {
            url += path;
        }

        return url;
    },

    nodeUrl: function (id) {

        var path = '/db/data/node';

        if (id) {
            path += '/' + id;
        }

        return this.url(path);
    },

    edgeUrl: function (id) {

        var path = '/db/data/relationship';

        if (id) {
            path += '/' + id;
        }

        return this.url(path);
    },

    cypherUrl: function () {
        return this.url('/db/data/cypher');
    },

    initialize: function () {
        $(this.kernel).on(NodeEvent.CREATED, this.handleNodeCreated.bind(this));
        $(this.kernel).on(NodeEvent.DESTROYED, this.handleNodeDeleted.bind(this));
        $(this.kernel).on(EdgeEvent.CREATED, this.handleEdgeCreated.bind(this));
        $(this.kernel).on(EdgeEvent.DESTROYED, this.handleEdgeDeleted.bind(this));
        $(this.kernel).on(NodeEvent.UPDATED, this.handleNodeUpdated.bind(this));
        $(this.kernel).on(NodeEvent.UPDATED, this.handleNodeLabelUpdated.bind(this));
    },

    get: function (callback) {

        var nodeQuery = {
            query: 'START n=node(*) RETURN n, labels(n)',
            // query: 'START n=node(*) RETURN n',
            params: {}
        };
        var edgeQuery = {
            query: 'START r=relationship(*) RETURN r',
            params: {}
        };
        var url = this.cypherUrl();
        var graph;

        // TODO use promises
        $.post(url, nodeQuery)
         .done(function (nodeResult) {

        $.post(url, edgeQuery)
         .done(function (edgeResult) {

            graph = transformer.neo4j.from(nodeResult, edgeResult);

            callback(graph);
         });
        });
    },

    /**
     * Create a node in the neo4j database
     * Store the id to easily delete the node later
     */
    handleNodeCreated: function (event, data) {

        var url = this.nodeUrl(),
            props = transformer.neo4j.toNode(data);

        $.ajax({
            url: url,
            data: props,
            type: 'POST',
            async: false
        }).done(function (result) {
            data._id = transformer.neo4j.idFromSelf(result.self);
        });
    },

    /**
     * We're doing this with a cypher, because we also have to delete
     * all relationships
     */
    handleNodeDeleted: function (event, data) {

        var query,
            url = this.cypherUrl();

        // TODO this query should work, but can't find parameter nodeId
        // query = {
        //      "query" : "START n=node({nodeId}) OPTIONAL MATCH n-[r]-() DELETE n,r",
        //      "params" : {
        //          "nodeId": nodeId
        //  }
        // };
        query = {
            "query" : "START n=node("+data._id+") OPTIONAL MATCH n-[r]-() DELETE n,r",
            // "query" : "START n=node("+data._id+") MATCH n-[r?]-() DELETE n,r",
            "params" : {}
        };

        $.post(url, query);
    },

    handleEdgeCreated: function (event, data, source, target) {

        var url = this.nodeUrl(source._id) + '/relationships',
            props = {
                to: this.edgeUrl(target._id),
                type: data.type
            };

        $.post(url, props)
         .done(function (result) {
            data._id = transformer.neo4j.idFromSelf(result.self);
         });
    },

    handleEdgeDeleted: function (event, data) {

        var url = this.edgeUrl(data._id);

        $.ajax({
            url: url,
            type: 'DELETE'
        });
    },

    handleNodeUpdated: function (event, node, data, diff) {

        // check if a property was updated
        if (!model.Node.pathInDifference(diff, model.Node.getPropertiesPath()) &&
            !model.Node.pathInDifference(diff, '_style')) {

            return;
        }

        console.log("handling node update");
        console.log(data._id);
        console.log(diff);

        var obj = transformer.neo4j.toNode(data),
            url = this.nodeUrl(data._id) + '/properties';

        $.ajax({
            url: url,
            type: 'PUT',
            data: obj
        });
    },

    /**
     * Removes all labels from the node and replaces them with the ones in data
     * @param data string or array<string>
     */
    handleNodeLabelUpdated: function (event, node, data, diff) {

        // check if a label was added or removed
        // TODO syntax needs some work...
        if (!model.Node.pathInDifference(diff, model.Node.getLabelsPath())) {
            return;
        }

        console.log("handling node label update");
        console.log(data._id);
        console.log(diff);

        var url = this.nodeUrl(data._id) + '/labels';

        $.ajax({
            url: url,
            type: 'PUT',
            contentType: 'application/json',
            data: JSON.stringify(data._labels)
        });
    }
});

}(window, jQuery));<|endoftext|>


<commit_before>// Copyright 2015, University of Colorado Boulder

/**
 * Text that has a handler set up to open a link in a new window when clicked.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var Text = require( 'SCENERY/nodes/Text' );
  var ButtonListener = require( 'SCENERY/input/ButtonListener' );
  var AccessiblePeer = require( 'SCENERY/accessibility/AccessiblePeer' );
  var joist = require( 'JOIST/joist' );

  function LinkText( text, url, options ) {

    // defaults
    options = _.extend( {
      handleEvent: false, // whether the up in the click event should be handled, e.g. to prevent the About dialog closing.
      accessibleContent: {
        createPeer: function( accessibleInstance ) {

          /* We want the accessible peer to look like the following in the Parallel DOM.
           *
           * text>
           */
          var domElement = document.createElement( 'a' );
          domElement.tabIndex = '0'; // in tab order by default
          domElement.href = url; // define link address
          domElement.innerText = text; // inner description, read by screen readers
          domElement.setAttribute( 'target', '_blank' ); // open in a new window/tab

          return new AccessiblePeer( accessibleInstance, domElement );
        }
      }
    }, options );

    Text.call( this, text, _.extend( {
      fill: 'rgb(27,0,241)', // blue, like a typical hypertext link
      cursor: 'pointer'
    }, options ) );

    this.addInputListener( new ButtonListener( {
      fire: function( event ) {
        options.handleEvent && event.handle();
        var newWindow = window.open( url, '_blank' ); // open in a new window/tab
        newWindow.focus();
      }
    } ) );
  }

  joist.register( 'LinkText', LinkText );

  return inherit( Text, LinkText );
} );<commit_msg>Remove AccessiblePeer from LinkText<commit_after>// Copyright 2015, University of Colorado Boulder

/**
 * Text that has a handler set up to open a link in a new window when clicked.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var Text = require( 'SCENERY/nodes/Text' );
  var ButtonListener = require( 'SCENERY/input/ButtonListener' );
  var joist = require( 'JOIST/joist' );

  function LinkText( text, url, options ) {

    // defaults
    options = _.extend( {
      handleEvent: false // whether the up in the click event should be handled, e.g. to prevent the About dialog closing.
    }, options );

    Text.call( this, text, _.extend( {
      fill: 'rgb(27,0,241)', // blue, like a typical hypertext link
      cursor: 'pointer'
    }, options ) );

    this.addInputListener( new ButtonListener( {
      fire: function( event ) {
        options.handleEvent && event.handle();
        var newWindow = window.open( url, '_blank' ); // open in a new window/tab
        newWindow.focus();
      }
    } ) );
  }

  joist.register( 'LinkText', LinkText );

  return inherit( Text, LinkText );
} );<|endoftext|>


<commit_before>var x=document.getElementById("search");
navigator.geolocation.getCurrentPosition(reverseGeoLookup);

function getLocation()
  {
  if (navigator.geolocation)
    {
       navigator.geolocation.getCurrentPosition(reverseGeoLookup);
    }
  else
    {
       x.innerHTML="Geolocation is not supported by this browser.";
    }
  }

function reverseGeoLookup(position) {
    console.log(position);
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
  var req = new XMLHttpRequest()
  req.open("GET", "https://maps.googleapis.com/maps/api/geocode/json?latlng="+lat+","+lon+"&sensor=true", true)
  req.onreadystatechange = function() {
      if(req.readyState == 4) {
          var result = JSON.parse(req.response).results
          for(var i = 0, length = result.length; i < length; i++) {
              for(var j = 0; j < result[i].address_components.length; j++) {
                  var component = result[i].address_components[j]
                  console.log(component.long_name);
                  if(~component.types.indexOf("postal_code")) {
                    var out = document.getElementById('search');
                    out.innerHTML = 'Approximate Post Code for your location is ' + component.long_name;
                    return false;
                  }
              }
          }
      }
  }
  req.send()
}<commit_msg>location<commit_after>var x=document.getElementById("search");
navigator.geolocation.getCurrentPosition(reverseGeoLookup);

function getLocation()
  {
  if (navigator.geolocation)
    {
       navigator.geolocation.getCurrentPosition(reverseGeoLookup);
    }
  else
    {
       x.innerHTML="Geolocation is not supported by this browser.";
    }
  }

function reverseGeoLookup(position) {
    console.log(position);
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
  var req = new XMLHttpRequest()
  req.open("GET", "https://maps.googleapis.com/maps/api/geocode/json?latlng="+lat+","+lon+"&sensor=true", true)
  req.onreadystatechange = function() {
      if(req.readyState == 4) {
          var result = JSON.parse(req.response).results
          for(var i = 0, length = result.length; i < length; i++) {
              for(var j = 0; j < result[i].address_components.length; j++) {
                  var component = result[i].address_components[j]
                  console.log(component.long_name);
                  if(~component.types.indexOf("postal_code")) {
                    var out = document.getElementById('search');
                    out.innerHTML = component.long_name;
                    return false;
                  }
              }
          }
      }
  }
  req.send()
}<|endoftext|>


<commit_before>var renderers = {
    "CAMERA_CONTROL": drawWorld,
    "UNIT_CONTROL": drawWorld,
    "MENU_CONTROL" : drawMenu,
    "CELL_PLACEMENT": drawWorld
};

// A cross-browser requestAnimationFrame
// See https://hacks.mozilla.org/2011/08/animating-with-javascript-from-setinterval-to-requestanimationframe/
var requestAnimFrame = (function(){
    return window.requestAnimationFrame    ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame    ||
        window.oRequestAnimationFrame      ||
        window.msRequestAnimationFrame     ||
        function(callback){
            window.setTimeout(callback, 1000 / 60);
        };
})();

function Renderer(width, height, destination) {
    // This contains all the graphics contexts which can render to their specific
    // layers. All contexts are overlapped on the screen, and have the same overall
    // width and height
    var contextLayers = {
        spriteLayer: new LayerRenderer(),
        backgroundLayer: new LayerRenderer(),
        foregroundLayer: new LayerRenderer(),
    };

    var width = width;
    var height = height;

    function LayerRenderer() {
        this.canvas = null;
        this.ctx = null;
        this.valid = false;
        this.renderingTasks = [];

        this.render = function(width, height) {
            if (!this.valid) {
                this.clearLayer(width, height);

                for (var i = 0; i < this.renderingTasks.length; i++) {
                    this.renderingTasks[i](this.ctx, width, height);
                }
            }
            this.valid = true;
        }

        // Rendering tasks are functions that use a graphics context to render
        // something. As such they must be of the form:
        //      renderTask(bound arguments..., context, width, height)
        this.registerTask = function(renderFunc) {
            this.renderingTasks.push(renderFunc);
        }

        this.invalidate = function() {
            this.valid = false;
        }

        this.clearLayer = function(width, height) {
            this.ctx.clearRect(0, 0, width, height);
        }
    }

    function initializeContexts(width, height, destination) {
        var canvas = document.createElement("canvas");
        canvas.id = "spriteLayer";
        contextLayers.spriteLayer.canvas = canvas;
        contextLayers.spriteLayer.ctx = setupContext(canvas.getContext("2d"));
        document.getElementById("canvas_land").appendChild(canvas);

        canvas = document.createElement("canvas");
        canvas.id = "backgroundLayer";
        contextLayers.backgroundLayer.canvas = canvas;
        contextLayers.backgroundLayer.ctx = setupContext(canvas.getContext("2d"));
        document.getElementById("canvas_land").appendChild(canvas);

        canvas = document.createElement("canvas");
        canvas.id = "foregroundLayer";
        contextLayers.foregroundLayer.canvas = canvas;
        contextLayers.foregroundLayer.ctx = setupContext(canvas.getContext("2d"));
        document.getElementById("canvas_land").appendChild(canvas);

        width = width;
        height = height;
    }

    // Intelligent rendering function. Makes rendering calls only for layers
    // that require it
    function render() {
        contextLayers.backgroundLayer.render(width, height);
        contextLayers.spriteLayer.render(width, height);
        contextLayers.foregroundLayer.render(width, height);
    }

}

function SpecialRenderer() {
    function addLayer(key, priority, renderfunc, renderable) {
        renderer = {
            key: key,
            priority: priority,
            rfunc: renderfunc.bind(null, renderable)
        };
        renderers.push(renderer);
    }

    function removeLayer(key) {
        // renderers are wrapped in objects which contain a key, so an
        // object needs to be created and passed here to delete
        renderers.remove({key: key});
    }

    function render() {
        for (var i = renderers.content.length - 1; i >= 0 ; i--) {
            renderers.content[i].rfunc();
        }
    }

    function rendererScore(r) {
        return r.priority;
    }

    function rendererEquality(r1, r2) {
        return r1.key == r2.key;
    }

    var renderers = new BinaryHeap(rendererScore, rendererEquality);

    this.addLayer = function(key, priority, renderfunc, renderable) {
        addLayer(key, priority, renderfunc, renderable);
    };

    this.removeLayer = function(key) {
        removeLayer(key);
    };

    this.render = function() {
        render();
    };
}

var specialRenderer = new SpecialRenderer();

function clearBack() {
    gfx.ctx.fillStyle = "#FFFFFF";
    gfx.ctx.fillRect(0, 0, gfx.width, gfx.height);
}

function drawLine(sx, sy, dx, dy) {
    gfx.ctx.moveTo(sx, sy);
    gfx.ctx.lineTo(dx, dy);
}

function drawMenu() {
    // TODO actually render something for the menu
}

function handleSelectorRendering(selector) {
    specialRenderer.removeLayer("selector");
    assets.spriteManager.getSprite("selector").animate = true;
    specialRenderer.addLayer("selector", 1, drawSelector, selector);
}

function drawWorld() {
    drawEnvironment(app.world);

    drawGrid(app.world);

    drawUnits(app.world);

    specialRenderer.render();
}

function drawEnvironment(world) {
    for (var x = 0; x < world.getWidth(); x++) {
        for (var y = 0; y < world.getHeight(); y++) {
            var current_cell = world.getCell(x, y);
            drawSprite(x, y, current_cell.spriteName);
        }
    }
}

function drawUnits(world) {
    var units = world.getUnits();
    for (var i in units) {
        var position = assets.spriteManager.getSprite(units[i].spriteName).drawPos;
        drawSprite(position.x, position.y, units[i].spriteName);
    }
}

function drawSelector(selector) {
    var position = selector.pos;
    drawSprite(position.x, position.y, selector.spriteName);
}

function drawSprite(x, y, spriteName) {
    var cam_pos = camera.transformToCameraSpace(x, y);
    if (camera.positionVisible(cam_pos.cam_x, cam_pos.cam_y)) {
        var sprite = assets.spriteManager.getSprite(spriteName);
        var img = sprite.getSpriteImg();
        var pos = sprite.getFramePosition(x, y);

        var rel_width = sprite.width / assets.spriteManager.minWidth;
        var rel_height = sprite.height / assets.spriteManager.minHeight;
        var cam_size = camera.multZoomFactor(rel_width, rel_height);
        var centered_offset = camera.multZoomFactor(rel_width - 1.0,
                                                    rel_height - 1.0);
        centered_offset.cam_w = centered_offset.cam_w / 2;
        centered_offset.cam_h = centered_offset.cam_h / 2;

        gfx.ctx.drawImage(img,
                          pos.x, pos.y,
                          sprite.width, sprite.height,
                          cam_pos.cam_x - centered_offset.cam_w,
                          cam_pos.cam_y - centered_offset.cam_h,
                          cam_size.cam_w, cam_size.cam_h);
    }
}

function drawGrid(world) {
    gfx.ctx.strokeStyle = "#000000";
    gfx.ctx.beginPath();
    for (var x = 0; x <= world.getWidth(); x++) {
        var draw_x = camera.transformToCameraSpace(x, 0).cam_x;
        var top = camera.transformToCameraSpace(x, 0).cam_y;
        var bot = camera.transformToCameraSpace(x, world.getHeight()).cam_y;
        drawLine(draw_x, top, draw_x, bot);
    }

    for (var y = 0; y <= world.getHeight(); y++) {
        var draw_y = camera.transformToCameraSpace(0, y).cam_y;
        var left = camera.transformToCameraSpace(0, y).cam_x;
        var right = camera.transformToCameraSpace(world.getWidth(), y).cam_x;
        drawLine(left, draw_y, right, draw_y);
    }
    gfx.ctx.stroke();
}

function render() {
    clearBack();

    renderers[app.currentState]();
}
<commit_msg>Add necessary initialize calls<commit_after>var renderers = {
    "CAMERA_CONTROL": drawWorld,
    "UNIT_CONTROL": drawWorld,
    "MENU_CONTROL" : drawMenu,
    "CELL_PLACEMENT": drawWorld
};

// A cross-browser requestAnimationFrame
// See https://hacks.mozilla.org/2011/08/animating-with-javascript-from-setinterval-to-requestanimationframe/
var requestAnimFrame = (function(){
    return window.requestAnimationFrame    ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame    ||
        window.oRequestAnimationFrame      ||
        window.msRequestAnimationFrame     ||
        function(callback){
            window.setTimeout(callback, 1000 / 60);
        };
})();

function Renderer(width, height, destination) {
    // This contains all the graphics contexts which can render to their specific
    // layers. All contexts are overlapped on the screen, and have the same overall
    // width and height
    var contextLayers = {
        spriteLayer: new LayerRenderer(),
        backgroundLayer: new LayerRenderer(),
        foregroundLayer: new LayerRenderer(),
    };

    var width = width;
    var height = height;

    initializeContexts(width, height, destination);

    function LayerRenderer() {
        this.canvas = null;
        this.ctx = null;
        this.valid = false;
        this.renderingTasks = [];

        this.render = function(width, height) {
            if (!this.valid) {
                this.clearLayer(width, height);

                for (var i = 0; i < this.renderingTasks.length; i++) {
                    this.renderingTasks[i](this.ctx, width, height);
                }
            }
            this.valid = true;
        }

        // Rendering tasks are functions that use a graphics context to render
        // something. As such they must be of the form:
        //      renderTask(bound arguments..., context, width, height)
        this.registerTask = function(renderFunc) {
            this.renderingTasks.push(renderFunc);
        }

        this.invalidate = function() {
            this.valid = false;
        }

        this.clearLayer = function(width, height) {
            this.ctx.clearRect(0, 0, width, height);
        }
    }

    function initializeContexts(width, height, destination) {
        // Some CSS fudging will have to happen here to get the canvases to overlap
        var canvas = document.createElement("canvas");
        canvas.id = "spriteLayer";
        contextLayers.spriteLayer.canvas = canvas;
        contextLayers.spriteLayer.ctx = setupContext(canvas.getContext("2d"));
        document.getElementById(destination).appendChild(canvas);

        canvas = document.createElement("canvas");
        canvas.id = "backgroundLayer";
        contextLayers.backgroundLayer.canvas = canvas;
        contextLayers.backgroundLayer.ctx = setupContext(canvas.getContext("2d"));
        document.getElementById(destination).appendChild(canvas);

        canvas = document.createElement("canvas");
        canvas.id = "foregroundLayer";
        contextLayers.foregroundLayer.canvas = canvas;
        contextLayers.foregroundLayer.ctx = setupContext(canvas.getContext("2d"));
        document.getElementById(destination).appendChild(canvas);

        width = width;
        height = height;
    }

    // Intelligent rendering function. Makes rendering calls only for layers
    // that require it
    function render() {
        contextLayers.backgroundLayer.render(width, height);
        contextLayers.spriteLayer.render(width, height);
        contextLayers.foregroundLayer.render(width, height);
    }

}

function SpecialRenderer() {
    function addLayer(key, priority, renderfunc, renderable) {
        renderer = {
            key: key,
            priority: priority,
            rfunc: renderfunc.bind(null, renderable)
        };
        renderers.push(renderer);
    }

    function removeLayer(key) {
        // renderers are wrapped in objects which contain a key, so an
        // object needs to be created and passed here to delete
        renderers.remove({key: key});
    }

    function render() {
        for (var i = renderers.content.length - 1; i >= 0 ; i--) {
            renderers.content[i].rfunc();
        }
    }

    function rendererScore(r) {
        return r.priority;
    }

    function rendererEquality(r1, r2) {
        return r1.key == r2.key;
    }

    var renderers = new BinaryHeap(rendererScore, rendererEquality);

    this.addLayer = function(key, priority, renderfunc, renderable) {
        addLayer(key, priority, renderfunc, renderable);
    };

    this.removeLayer = function(key) {
        removeLayer(key);
    };

    this.render = function() {
        render();
    };
}

var specialRenderer = new SpecialRenderer();

function clearBack() {
    gfx.ctx.fillStyle = "#FFFFFF";
    gfx.ctx.fillRect(0, 0, gfx.width, gfx.height);
}

function drawLine(sx, sy, dx, dy) {
    gfx.ctx.moveTo(sx, sy);
    gfx.ctx.lineTo(dx, dy);
}

function drawMenu() {
    // TODO actually render something for the menu
}

function handleSelectorRendering(selector) {
    specialRenderer.removeLayer("selector");
    assets.spriteManager.getSprite("selector").animate = true;
    specialRenderer.addLayer("selector", 1, drawSelector, selector);
}

function drawWorld() {
    drawEnvironment(app.world);

    drawGrid(app.world);

    drawUnits(app.world);

    specialRenderer.render();
}

function drawEnvironment(world) {
    for (var x = 0; x < world.getWidth(); x++) {
        for (var y = 0; y < world.getHeight(); y++) {
            var current_cell = world.getCell(x, y);
            drawSprite(x, y, current_cell.spriteName);
        }
    }
}

function drawUnits(world) {
    var units = world.getUnits();
    for (var i in units) {
        var position = assets.spriteManager.getSprite(units[i].spriteName).drawPos;
        drawSprite(position.x, position.y, units[i].spriteName);
    }
}

function drawSelector(selector) {
    var position = selector.pos;
    drawSprite(position.x, position.y, selector.spriteName);
}

function drawSprite(x, y, spriteName) {
    var cam_pos = camera.transformToCameraSpace(x, y);
    if (camera.positionVisible(cam_pos.cam_x, cam_pos.cam_y)) {
        var sprite = assets.spriteManager.getSprite(spriteName);
        var img = sprite.getSpriteImg();
        var pos = sprite.getFramePosition(x, y);

        var rel_width = sprite.width / assets.spriteManager.minWidth;
        var rel_height = sprite.height / assets.spriteManager.minHeight;
        var cam_size = camera.multZoomFactor(rel_width, rel_height);
        var centered_offset = camera.multZoomFactor(rel_width - 1.0,
                                                    rel_height - 1.0);
        centered_offset.cam_w = centered_offset.cam_w / 2;
        centered_offset.cam_h = centered_offset.cam_h / 2;

        gfx.ctx.drawImage(img,
                          pos.x, pos.y,
                          sprite.width, sprite.height,
                          cam_pos.cam_x - centered_offset.cam_w,
                          cam_pos.cam_y - centered_offset.cam_h,
                          cam_size.cam_w, cam_size.cam_h);
    }
}

function drawGrid(world) {
    gfx.ctx.strokeStyle = "#000000";
    gfx.ctx.beginPath();
    for (var x = 0; x <= world.getWidth(); x++) {
        var draw_x = camera.transformToCameraSpace(x, 0).cam_x;
        var top = camera.transformToCameraSpace(x, 0).cam_y;
        var bot = camera.transformToCameraSpace(x, world.getHeight()).cam_y;
        drawLine(draw_x, top, draw_x, bot);
    }

    for (var y = 0; y <= world.getHeight(); y++) {
        var draw_y = camera.transformToCameraSpace(0, y).cam_y;
        var left = camera.transformToCameraSpace(0, y).cam_x;
        var right = camera.transformToCameraSpace(world.getWidth(), y).cam_x;
        drawLine(left, draw_y, right, draw_y);
    }
    gfx.ctx.stroke();
}

function render() {
    clearBack();

    renderers[app.currentState]();
}
<|endoftext|>


<commit_before>var modal = "";
var ulElement = "";
var selElement = "";
var videoModal = "";
var player = "";
var myFrame = "";
var frameDiv = "";
var vidModalStatus=false;
var autoSwitchEpisode = false;
var isFullscreen = 1;

document.addEventListener("resize", rezHandler);
document.addEventListener("fullscreenchange", FShandler);
document.addEventListener("webkitfullscreenchange", FShandler);
document.addEventListener("mozfullscreenchange", FShandler);
document.addEventListener("MSFullscreenChange", FShandler);
document.addEventListener("keydown", function (e) {
if (e.keyCode === 70) {
	e.preventDefault();
	e.stopPropagation();
	if (isFullscreen % 2 === 0) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
                rezHandler();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
                rezHandler();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
                rezHandler();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
                rezHandler();
            }
        } else {
            if (player.requestFullscreen) {
                player.requestFullscreen();
            } else if (player.msRequestFullscreen) {
                player.msRequestFullscreen();
            } else if (player.mozRequestFullScreen) {
                player.mozRequestFullScreen();
            } else if (player.webkitRequestFullscreen) {
                player.webkitRequestFullscreen();
            }
        }
    } else if (e.keyCode === 37) {
		e.preventDefault();
		e.stopPropagation();
        player.currentTime -= 5;
    } else if (e.keyCode === 39) {
		e.preventDefault();
		e.stopPropagation();
        player.currentTime += 5;
		if (player.currentTime >= player.duration){
			nextEp();
		}
    } else if (e.keyCode === 32) {
		e.preventDefault();
		e.stopPropagation();
        if(player.paused){
        	player.play();
    	} else {
        	player.pause();
    	}
    }
}, false);

function rezHandler() {
    if (vidModalStatus===true){
        var tempHeight=videoModal.firstElementChild.offsetHeight+20;
        parent.frameDiv.style.height=String(tempHeight)+"px";
		document.body.style.overflow="hidden";
    }
}

function FShandler() {
    isFullscreen++;
}

function changeSeason(elem) {
    ulElement.style.display = "none";
    var e = document.getElementById(elem.id);
    var myVal = e.options[e.selectedIndex].value;
    var tempStr = elem.id.replace("selector", "C");
    tempStr = tempStr.split("C").pop();
    tempStr = "C" + tempStr + String(myVal);
    ulElement = document.getElementById(String(tempStr));
    ulElement.style.display = "block";
    parent.resizeFrame();
}

function showModal(id) {
    var tempStr = id;
    selElement = document.getElementById(String(id));
    var myVal = selElement.value;
    tempStr = tempStr.replace("selector", "C");
    tempStr = tempStr.split("C").pop();
    tempStr = "C" + tempStr + String(myVal);
    ulElement = document.getElementById(String(tempStr));
    ulElement.style.display = "block";
}

function showVideoModal(elem) {
    var tempStr = elem.id;
    tempStr = tempStr.replace("D", "E");
    videoModal = document.getElementById(String(tempStr));
    tempStr = tempStr.replace("E", "F");
    player = document.getElementById(String(tempStr));
    videoModal.style.cssText = "background-color: white; display: block;";
    videoModal.firstElementChild.style.cssText = "width: auto; height: auto; margin: 0; padding: 0; border: 0;";
    var tempHeight=(videoModal.firstElementChild.offsetHeight)+18;
    parent.frameDiv.style.height=String(tempHeight)+"px";
    vidModalStatus=true;
	document.body.style.overflow="hidden";
}

function showVideoModalsetSubs(elem, srcStr) {
    var tempStr = elem.id;
    tempStr = tempStr.replace("D", "E");
    videoModal = document.getElementById(String(tempStr));
    tempStr = tempStr.replace("E", "F");
    player = document.getElementById(String(tempStr));
    videoModal.style.cssText = "background-color: white; display: block;";
    videoModal.firstElementChild.style.cssText = "width: auto; height: auto; margin: 0; padding: 0; border: 0;";
    var tempHeight=(videoModal.firstElementChild.offsetHeight)+18;
    parent.frameDiv.style.height=String(tempHeight)+"px";
    vidModalStatus=true;
	document.body.style.overflow="hidden";
    var subNum = parseInt(player.childElementCount) - 1;
    var array = srcStr.split(',');
    for (var i = 1, j = 0; i <= subNum; i++, j++) {
        player.children[i].src = array[j];
    }
}

function hideModal() {
    parent.modal.style.display = "none";
    parent.frameDiv.style.display = "none";
}

function hideVideoModal() {
    videoModal.style.display = "none";
	document.body.style.overflow="auto";
    player.pause();
    player = "";
    vidModalStatus=false;
    parent.resizeFrame();
}

function resetPlayer(){
    var myTime = player.currentTime;
	var mySrc = player.children[0].src;
	player.children[0].src="";
    player.load();
	player.children[0].src=mySrc;
    player.currentTime = myTime;
	player.load();
    player.play();
}

function prevEp() {
    var index = videoModal.id.indexOf("_");
    var myID = videoModal.id.substr(0, index + 1);
    var currentNum = parseInt(videoModal.id.substr(index + 1));
    if (currentNum !== 0) {
        videoModal.style.display = "none";
        player.pause();
        player = "";
        currentNum -= 1;
        tempStr = String(myID) + String(currentNum);
        videoModal = document.getElementById(tempStr);
        videoModal.style.display = "block";
        if (isDescendant(ulElement, videoModal) === false && selElement.value !== 1) {
            selElement.selectedIndex = parseInt(parseInt(selElement.value) - 2);
            changeSeason(selElement);
        }
        tempStr = tempStr.replace("E", "F");
        player = document.getElementById(String(tempStr));
        player.play();
    }
}

function nextEp() {
    var index = videoModal.id.indexOf("_");
    var myID = videoModal.id.substr(0, index + 1);
    var currentNum = parseInt(videoModal.id.substr(index + 1));
    currentNum += 1;
    var tempStr = String(myID) + String(currentNum);
	tempStr = tempStr.replace("E", "D");
	var btnElem = document.getElementById(tempStr);
	oldVolume = player.volume;
    if (document.getElementById(tempStr) !== null) {
		hideVideoModal();
		btnElem.click();
        if (isDescendant(ulElement, videoModal) === false) {
            selElement.selectedIndex = parseInt(parseInt(selElement.value));
            changeSeason(selElement);
        }
        if (autoSwitchEpisode === true) {
            player.addEventListener('ended', nextEp);
        }
        if (isFullscreen % 2 === 0) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        }
        player.volume = oldVolume;
        player.play();
    }
}

function autoSwitch() {
    if (autoSwitchEpisode === false) {
        autoSwitchEpisode = true;
        var e = document.getElementsByClassName("autoButton");
        player.addEventListener('ended', nextEp);
        for (var i = 0; i < e.length; i++) {
            e[i].checked = true;
        }
    } else {
        autoSwitchEpisode = false;
        player.removeEventListener('ended', nextEp);
        var e = document.getElementsByClassName("autoButton");
        for (var i = 0; i < e.length; i++) {
            e[i].checked = false;
        }
    }
}

window.parent.onclick = function (event) {
    if (event.target === parent.modal) {
        if (player==""){
            parent.modal.style.display = "none";
            parent.myFrame="";
        } else {
            hideVideoModal();
        }
    }
};

parent.window.onresize=rezHandler;
<commit_msg>Update TVScript.js<commit_after>var modal = "";
var ulElement = "";
var selElement = "";
var videoModal = "";
var player = "";
var myFrame = "";
var frameDiv = "";
var vidModalStatus=false;
var autoSwitchEpisode = false;
var isFullscreen = 1;

document.addEventListener("resize", rezHandler);
document.addEventListener("fullscreenchange", FShandler);
document.addEventListener("webkitfullscreenchange", FShandler);
document.addEventListener("mozfullscreenchange", FShandler);
document.addEventListener("MSFullscreenChange", FShandler);
document.addEventListener("keydown", function (e) {
if (e.keyCode === 70) {
	e.preventDefault();
	e.stopPropagation();
	if (isFullscreen % 2 === 0) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
                rezHandler();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
                rezHandler();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
                rezHandler();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
                rezHandler();
            }
        } else {
            if (player.requestFullscreen) {
                player.requestFullscreen();
            } else if (player.msRequestFullscreen) {
                player.msRequestFullscreen();
            } else if (player.mozRequestFullScreen) {
                player.mozRequestFullScreen();
            } else if (player.webkitRequestFullscreen) {
                player.webkitRequestFullscreen();
            }
        }
    } else if (e.keyCode === 37) {
		e.preventDefault();
		e.stopPropagation();
        player.currentTime -= 5;
    } else if (e.keyCode === 39) {
		e.preventDefault();
		e.stopPropagation();
        player.currentTime += 5;
		if (player.currentTime >= player.duration){
			nextEp();
		}
    } else if (e.keyCode === 32) {
		e.preventDefault();
		e.stopPropagation();
        if(player.paused){
        	player.play();
    	} else {
        	player.pause();
    	}
    }
}, false);

function rezHandler() {
    if (vidModalStatus===true){
        var tempHeight=videoModal.firstElementChild.offsetHeight+20;
        parent.frameDiv.style.height=String(tempHeight)+"px";
		document.body.style.overflow="hidden";
    }
}

function FShandler() {
    isFullscreen++;
}

function isDescendant(parent, child) {
    var node = child.parentNode;
    while (node !== null) {
        if (node === parent) {
            return true;
        }
        node = node.parentNode;
    }
    return false;
}

function changeSeason(elem) {
    ulElement.style.display = "none";
    var e = document.getElementById(elem.id);
    var myVal = e.options[e.selectedIndex].value;
    var tempStr = elem.id.replace("selector", "C");
    tempStr = tempStr.split("C").pop();
    tempStr = "C" + tempStr + String(myVal);
    ulElement = document.getElementById(String(tempStr));
    ulElement.style.display = "block";
    parent.resizeFrame();
}

function showModal(id) {
    var tempStr = id;
    selElement = document.getElementById(String(id));
    var myVal = selElement.value;
    tempStr = tempStr.replace("selector", "C");
    tempStr = tempStr.split("C").pop();
    tempStr = "C" + tempStr + String(myVal);
    ulElement = document.getElementById(String(tempStr));
    ulElement.style.display = "block";
}

function showVideoModal(elem) {
    var tempStr = elem.id;
    tempStr = tempStr.replace("D", "E");
    videoModal = document.getElementById(String(tempStr));
    tempStr = tempStr.replace("E", "F");
    player = document.getElementById(String(tempStr));
    videoModal.style.cssText = "background-color: white; display: block;";
    videoModal.firstElementChild.style.cssText = "width: auto; height: auto; margin: 0; padding: 0; border: 0;";
    var tempHeight=(videoModal.firstElementChild.offsetHeight)+18;
    parent.frameDiv.style.height=String(tempHeight)+"px";
    vidModalStatus=true;
	document.body.style.overflow="hidden";
}

function showVideoModalsetSubs(elem, srcStr) {
    var tempStr = elem.id;
    tempStr = tempStr.replace("D", "E");
    videoModal = document.getElementById(String(tempStr));
    tempStr = tempStr.replace("E", "F");
    player = document.getElementById(String(tempStr));
    videoModal.style.cssText = "background-color: white; display: block;";
    videoModal.firstElementChild.style.cssText = "width: auto; height: auto; margin: 0; padding: 0; border: 0;";
    var tempHeight=(videoModal.firstElementChild.offsetHeight)+18;
    parent.frameDiv.style.height=String(tempHeight)+"px";
    vidModalStatus=true;
	document.body.style.overflow="hidden";
    var subNum = parseInt(player.childElementCount) - 1;
    var array = srcStr.split(',');
    for (var i = 1, j = 0; i <= subNum; i++, j++) {
        player.children[i].src = array[j];
    }
}

function hideModal() {
    parent.modal.style.display = "none";
    parent.frameDiv.style.display = "none";
}

function hideVideoModal() {
    videoModal.style.display = "none";
	document.body.style.overflow="auto";
    player.pause();
    player = "";
    vidModalStatus=false;
    parent.resizeFrame();
}

function resetPlayer(){
    var myTime = player.currentTime;
	var mySrc = player.children[0].src;
	player.children[0].src="";
    player.load();
	player.children[0].src=mySrc;
    player.currentTime = myTime;
	player.load();
    player.play();
}

function prevEp() {
    var index = videoModal.id.indexOf("_");
    var myID = videoModal.id.substr(0, index + 1);
    var currentNum = parseInt(videoModal.id.substr(index + 1));
    if (currentNum !== 0) {
        videoModal.style.display = "none";
        player.pause();
        player = "";
        currentNum -= 1;
        tempStr = String(myID) + String(currentNum);
        videoModal = document.getElementById(tempStr);
        videoModal.style.display = "block";
        if (isDescendant(ulElement, videoModal) === false && selElement.value !== 1) {
            selElement.selectedIndex = parseInt(parseInt(selElement.value) - 2);
            changeSeason(selElement);
        }
        tempStr = tempStr.replace("E", "F");
        player = document.getElementById(String(tempStr));
        player.play();
    }
}

function nextEp() {
    var index = videoModal.id.indexOf("_");
    var myID = videoModal.id.substr(0, index + 1);
    var currentNum = parseInt(videoModal.id.substr(index + 1));
    currentNum += 1;
    var tempStr = String(myID) + String(currentNum);
	tempStr = tempStr.replace("E", "D");
	var btnElem = document.getElementById(tempStr);
	oldVolume = player.volume;
    if (document.getElementById(tempStr) !== null) {
		hideVideoModal();
		btnElem.click();
        if (isDescendant(ulElement, videoModal) === false) {
            selElement.selectedIndex = parseInt(parseInt(selElement.value));
            changeSeason(selElement);
        }
        if (autoSwitchEpisode === true) {
            player.addEventListener('ended', nextEp);
        }
        if (isFullscreen % 2 === 0) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        }
        player.volume = oldVolume;
        player.play();
    }
}

function autoSwitch() {
    if (autoSwitchEpisode === false) {
        autoSwitchEpisode = true;
        var e = document.getElementsByClassName("autoButton");
        player.addEventListener('ended', nextEp);
        for (var i = 0; i < e.length; i++) {
            e[i].checked = true;
        }
    } else {
        autoSwitchEpisode = false;
        player.removeEventListener('ended', nextEp);
        var e = document.getElementsByClassName("autoButton");
        for (var i = 0; i < e.length; i++) {
            e[i].checked = false;
        }
    }
}

window.parent.onclick = function (event) {
    if (event.target === parent.modal) {
        if (player==""){
            parent.modal.style.display = "none";
            parent.myFrame="";
        } else {
            hideVideoModal();
        }
    }
};

parent.window.onresize=rezHandler;
<|endoftext|>


<commit_before>/**
 * Created with IntelliJ IDEA.
 * User: tparmer
 * Date: 11/27/13
 * Time: 12:21 PM
 * To change this template use File | Settings | File Templates.
 */

var serviceURL = "http://216.74.49.91:8080/tssvc/resourcesS/stories/";
//var serviceURL = "http://localhost:8080/tssvc/resourcesS/stories";
//var serviceURL = "http://localhost:8080/tssvc/getstorylist2.html";

//var employees;
//var stories;

$('#mediaPage').bind('pagebeforecreate', function(event) {
    //alert('bind: pagebeforecreate');
    //getEmployeeList();
});
$('#mediaPage').bind('pagecreate', function(event) {
   // alert('bind: pagecreate');
    //getEmployeeList();
});

$('#mediaPage').bind('pageinit', function(event) {
    //alert('bind: pageinit');
    //getEmployeeList();
});

$('#mediaPage').live('pageinit', function(event) {
    alert('live: pageinit');
    app.initialize();
    alert('live: after app.init');
    //getEmployeeList();
});
$('#mediaPage').bind('pagebeforeload', function(event) {
   // alert('bind: pagebeforeload');
    //getEmployeeList();
});

$('#mediaPage').bind('pageload', function(event) {
   // alert('bind: pageload');
    //getEmployeeList();
});

$('#mediaPage').bind('pagebeforeshow', function(event) {
   // alert('bind: pagebeforeshow');
    //getEmployeeList();
});

$('#mediaPage').bind('pageshow', function(event) {
    //alert('bind: pageshow');
    //getEmployeeList();
});
$('#mediaPage').bind('pagebeforechange', function(event) {
    //alert('bind: pagebeforeshow');
    //getEmployeeList();
});

$('#mediaPage').bind('pagechange', function(event) {
   // alert('bind: pageshow');
    //getEmployeeList();
});

var app = {
    // Application Constructor
    initialize: function() {
        this.bindEvents();
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // `load`, `deviceready`, `offline`, and `online`.
    bindEvents: function() {
        alert('before binding events');
// document.addEventListener('deviceready', this.onDeviceReady, false);
// document.getElementById('scan').addEventListener('click', this.scan, false);
// document.getElementById('encode').addEventListener('click', this.encode, false);
// document.getElementById('whitelist').addEventListener('click', this.whitelist, false);
        document.getElementById('camera').addEventListener('click', this.camera, false);
        document.getElementById('video').addEventListener('click', this.captureVideo, false);
        document.getElementById('audio').addEventListener('click', this.captureAudio, false);
        document.getElementById('getphoto').addEventListener('click', this.getphoto, false);
        alert('after binding events');
    },

// // deviceready Event Handler
// //
// // The scope of `this` is the event. In order to call the `receivedEvent`
// // function, we must explicity call `app.receivedEvent(...);`
// onDeviceReady: function() {
// app.receivedEvent('deviceready');
// console.log('CORDOVA VERSION: ' + window.device.cordova);
// window.addEventListener('batterystatus', app.onBatteryStatus, false);
// },
// // Update DOM on a Received Event
// receivedEvent: function(id) {
// var parentElement = document.getElementById(id);
// var listeningElement = parentElement.querySelector('.listening');
// var receivedElement = parentElement.querySelector('.received');
//
// listeningElement.setAttribute('style', 'display:none;');
// receivedElement.setAttribute('style', 'display:block;');
//
// console.log('Received Event: ' + id);
// },
// onBatteryStatus: function(info) {
// console.log("Level: " + info.level + " isPlugged: " + info.isPlugged);
// },
// scan: function() {
// console.log('scanning');
// var scanner = cordova.require("cordova/plugin/BarcodeScanner");
//
// scanner.scan( function (result) {
//
// alert("We got a barcode\n" +
// "Result: " + result.text + "\n" +
// "Format: " + result.format + "\n" +
// "Cancelled: " + result.cancelled);
//
// console.log("Scanner result: \n" +
// "text: " + result.text + "\n" +
// "format: " + result.format + "\n" +
// "cancelled: " + result.cancelled + "\n");
// document.getElementById("info").innerHTML = result.text;
// console.log(result);
// /*
// if (args.format == "QR_CODE") {
// window.plugins.childBrowser.showWebPage(args.text, { showLocationBar: false });
// }
// */
//
// }, function (error) {
// console.log("Scanning failed: ", error);
// } );
// },
//
// encode: function() {
// var scanner = cordova.require("cordova/plugin/BarcodeScanner");
//
// scanner.encode(scanner.Encode.TEXT_TYPE, "http://www.nhl.com", function(success) {
// alert("encode success: " + success);
// }, function(fail) {
// alert("encoding failed: " + fail);
// }
// );
//
// },
//
// whitelist: function() {
//
// app.xhr("https://tv.eurosport.com/", function(xhr) {
// console.log("eurosport is invalid " + xhr.status);
// console.log("eurosport: " + xhr.responseText.substring(0, 100));
// });
// /*
// app.xhr("http://ajax.googleapis.com/ajax/libs/prototype/1.7.1.0/prototype.js", function(xhr) {
// console.log("googleapis: should succeed: " + xhr.status);
// console.log("googleapis: " + xhr.responseText.substring(0, 100));
// });
//
// app.xhr("http://code.jquery.com/jquery-1.10.2.min.js", function(xhr) {
// console.log("jquery: should fail: " + xhr.status);
// console.log("jquery: " + xhr.responseText.substring(0, 100));
// });
//
// app.xhr("http://phonegap.com", function(xhr) {
// console.log("phonegap: should fail: " + xhr.status);
// console.log("phonegap: " + xhr.responseText.substring(0, 100));
// });
//
// app.xhr("http://googleapis.com", function(xhr) {
// console.log("googleapis.com: should succeed: " + xhr.status);
// console.log("googleapis.com: " + xhr.responseText.substring(0, 100));
// });
//
// app.xhr("http://jquery.com", function(xhr) {
// console.log("jquery.com: should succeed: " + xhr.status);
// console.log("jquery.com: " + xhr.responseText.substring(0, 100));
// });
// */
//
// },

    camera: function() {

        function onSuccess(imageData) {
            //console.log('success');

            var options = new FileUploadOptions();
            options.fileKey="file";
            options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
            options.mimeType="image/jpeg";

            var params = {};
            params.value1 = "test";
            params.value2 = "param";

            options.params = params;

            var ft = new FileTransfer();
            ft.upload(imageURI, encodeURI("http://216.74.49.91:8080/tssvc/resourcesS/upload"), fileok, filefail, options);

            // AT: the old code
            //
//            document.getElementById('testMsg').value = "in onSuccess";
//
//            //Anna
//            //var image = document.getElementById('myImage');
//            //image.src = "data:image/jpeg;base64," + imageData;
//
//            var smallImage = document.getElementById('smallImage');
//
//            // Unhide image elements
//            //
//            smallImage.style.display = 'block';
//
//            // Show the captured photo
//            // The inline CSS rules are used to resize the image
//            //
//            smallImage.src = "data:image/jpeg;base64," + imageData;
//
//            // Get image handle
//            //
//            var largeImage = document.getElementById('largeImage');
//
//            // Unhide image elements
//            //
//            largeImage.style.display = 'block';
//            largeImage.src = "data:image/jpeg;base64," + imageData;

        }

        function onFail(message) {
            console.log('failed');
        }
        var cameraPopoverOptions = new CameraPopoverOptions(220, 600, 320, 480, Camera.PopoverArrowDirection.ARROW_DOWN) ;
        var cameraHandle = navigator.camera.getPicture(onSuccess, onFail, { quality: 50, saveToPhotoAlbum: true,
            destinationType: Camera.DestinationType.FILE_URI, popoverOptions:cameraPopoverOptions
        });
        //cameraHandle.setPosition(cameraPopoverOptions);
        function fileok(r) {
            document.getElementById('testMsg').value = "Success. Code = " + r.responseCode + " Resposne = " + r.response + " sent = " + r.byteSent;
            //console.log("Response = " + r.response);
            //console.log("Sent = " + r.bytesSent);
        }

        function filefail(error) {
            document.getElementById('testMsg').value = "Error. Code = " + error.code + " source = " + error.source + " target = " + error.target;
            //alert("An error has occurred: Code = " + error.code);
            //console.log("upload error source " + error.source);
            //console.log("upload error target " + error.target);
        }

    },

    getphoto: function() {

        function onSuccess(imageData) {
            //console.log('success');

            document.getElementById('testMsg').value = "in onSuccess";

            //Anna
            //var image = document.getElementById('myImage');
            //image.src = "data:image/jpeg;base64," + imageData;

            var smallImage = document.getElementById('smallImage');

            // Unhide image elements
            //
            smallImage.style.display = 'block';

            // Show the captured photo
            // The inline CSS rules are used to resize the image
            //
            smallImage.src = "data:image/jpeg;base64," + imageData;

            // Get image handle
            //
            var largeImage = document.getElementById('largeImage');

            // Unhide image elements
            //
            largeImage.style.display = 'block';
            largeImage.src = "data:image/jpeg;base64," + imageData;

        }

        function onFail(message) {
            console.log('failed');
        }

        navigator.camera.getPicture(onSuccess, onFail, { quality: 50, saveToPhotoAlbum: true,
            destinationType: Camera.DestinationType.DATA_URL,sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
            mediaType: Camera.MediaType.ALLMEDIA
        });

    },

    xhr: function(url, cb) {
        var xhr1 = new XMLHttpRequest();
        xhr1.onreadystatechange = function(args) {
            if(xhr1.readyState==4)
                cb(xhr1);
        };
        xhr1.open("GET", url, true);
        xhr1.send();
    },

    captureVideo: function() {
        navigator.device.capture.captureVideo(function(mediaFiles)
            {
                console.log('CALLBACK!');
                console.log(JSON.stringify(mediaFiles));
            }, function(error)
            {
                console.log('Video capture failed');
                alert ('video failed');
            },
            {
                limit: 1,
                duration: 12
            });

    },

 /*   // Record audio
//
     recordAudio: function() {
    var src = "myrecording.wav";
    var mediaRec = new Media(src,
        // success callback
        function() {
            console.log("recordAudio():Audio Success");
            alert('audio success');
        },

        // error callback
        function(err) {
            console.log("recordAudio():Audio Error: "+ err.code);
        }
    );

    // Record audio
    mediaRec.startRecord();

    // Stop recording after 10 seconds
    setTimeout(function() {
        mediaRec.stopRecord();
    }, 10000);
}*/

    captureAudio: function() {

        // Called when capture operation is finished
        //
        function captureSuccess(mediaFiles) {

            alert ('audio success');
            var i, len;
            for (i = 0, len = mediaFiles.length; i < len; i += 1) {
                uploadFile(mediaFiles[i]);
            }

        }

        // Called if something bad happens.
        //
        function captureError(error) {
            var msg = 'An error occurred during capture: ' + error.code;
            navigator.notification.alert(msg, null, 'Uh oh!');
        }

        navigator.device.capture.captureAudio(function(mediaFiles)
            {
                console.log('CALLBACK!');
                console.log(JSON.stringify(mediaFiles));
            }, function(error)
            {
                console.log('Audio capture failed');
            },
            {
                limit: 1,
                duration: 12
            });

        // Upload files to server
//        function uploadFile(mediaFile) {
//            var ft = new FileTransfer(),
//                path = mediaFile.fullPath,
//                name = mediaFile.name;
//
//            ft.upload(path,
//                "http://my.domain.com/upload.php",
//                function(result) {
//                    console.log('Upload success: ' + result.responseCode);
//                    console.log(result.bytesSent + ' bytes sent');
//                },
//                function(error) {
//                    console.log('Error uploading file ' + path + ': ' + error.code);
//                },
//                { fileName: name });
//        }

    }
};

<commit_msg>first pass at file upload thru addmedia.js<commit_after>/**
 * Created with IntelliJ IDEA.
 * User: tparmer
 * Date: 11/27/13
 * Time: 12:21 PM
 * To change this template use File | Settings | File Templates.
 */

var serviceURL = "http://216.74.49.91:8080/tssvc/resourcesS/stories/";
//var serviceURL = "http://localhost:8080/tssvc/resourcesS/stories";
//var serviceURL = "http://localhost:8080/tssvc/getstorylist2.html";

//var employees;
//var stories;

$('#mediaPage').bind('pagebeforecreate', function(event) {
    //alert('bind: pagebeforecreate');
    //getEmployeeList();
});
$('#mediaPage').bind('pagecreate', function(event) {
   // alert('bind: pagecreate');
    //getEmployeeList();
});

$('#mediaPage').bind('pageinit', function(event) {
    //alert('bind: pageinit');
    //getEmployeeList();
});

$('#mediaPage').live('pageinit', function(event) {
    alert('live: pageinit');
    app.initialize();
    alert('live: after app.init');
    //getEmployeeList();
});
$('#mediaPage').bind('pagebeforeload', function(event) {
   // alert('bind: pagebeforeload');
    //getEmployeeList();
});

$('#mediaPage').bind('pageload', function(event) {
   // alert('bind: pageload');
    //getEmployeeList();
});

$('#mediaPage').bind('pagebeforeshow', function(event) {
   // alert('bind: pagebeforeshow');
    //getEmployeeList();
});

$('#mediaPage').bind('pageshow', function(event) {
    //alert('bind: pageshow');
    //getEmployeeList();
});
$('#mediaPage').bind('pagebeforechange', function(event) {
    //alert('bind: pagebeforeshow');
    //getEmployeeList();
});

$('#mediaPage').bind('pagechange', function(event) {
   // alert('bind: pageshow');
    //getEmployeeList();
});

var app = {
    // Application Constructor
    initialize: function() {
        this.bindEvents();
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // `load`, `deviceready`, `offline`, and `online`.
    bindEvents: function() {
        alert('before binding events');
// document.addEventListener('deviceready', this.onDeviceReady, false);
// document.getElementById('scan').addEventListener('click', this.scan, false);
// document.getElementById('encode').addEventListener('click', this.encode, false);
// document.getElementById('whitelist').addEventListener('click', this.whitelist, false);
        document.getElementById('camera').addEventListener('click', this.camera, false);
        document.getElementById('video').addEventListener('click', this.captureVideo, false);
        document.getElementById('audio').addEventListener('click', this.captureAudio, false);
        document.getElementById('getphoto').addEventListener('click', this.getphoto, false);
        alert('after binding events');
    },

// // deviceready Event Handler
// //
// // The scope of `this` is the event. In order to call the `receivedEvent`
// // function, we must explicity call `app.receivedEvent(...);`
// onDeviceReady: function() {
// app.receivedEvent('deviceready');
// console.log('CORDOVA VERSION: ' + window.device.cordova);
// window.addEventListener('batterystatus', app.onBatteryStatus, false);
// },
// // Update DOM on a Received Event
// receivedEvent: function(id) {
// var parentElement = document.getElementById(id);
// var listeningElement = parentElement.querySelector('.listening');
// var receivedElement = parentElement.querySelector('.received');
//
// listeningElement.setAttribute('style', 'display:none;');
// receivedElement.setAttribute('style', 'display:block;');
//
// console.log('Received Event: ' + id);
// },
// onBatteryStatus: function(info) {
// console.log("Level: " + info.level + " isPlugged: " + info.isPlugged);
// },
// scan: function() {
// console.log('scanning');
// var scanner = cordova.require("cordova/plugin/BarcodeScanner");
//
// scanner.scan( function (result) {
//
// alert("We got a barcode\n" +
// "Result: " + result.text + "\n" +
// "Format: " + result.format + "\n" +
// "Cancelled: " + result.cancelled);
//
// console.log("Scanner result: \n" +
// "text: " + result.text + "\n" +
// "format: " + result.format + "\n" +
// "cancelled: " + result.cancelled + "\n");
// document.getElementById("info").innerHTML = result.text;
// console.log(result);
// /*
// if (args.format == "QR_CODE") {
// window.plugins.childBrowser.showWebPage(args.text, { showLocationBar: false });
// }
// */
//
// }, function (error) {
// console.log("Scanning failed: ", error);
// } );
// },
//
// encode: function() {
// var scanner = cordova.require("cordova/plugin/BarcodeScanner");
//
// scanner.encode(scanner.Encode.TEXT_TYPE, "http://www.nhl.com", function(success) {
// alert("encode success: " + success);
// }, function(fail) {
// alert("encoding failed: " + fail);
// }
// );
//
// },
//
// whitelist: function() {
//
// app.xhr("https://tv.eurosport.com/", function(xhr) {
// console.log("eurosport is invalid " + xhr.status);
// console.log("eurosport: " + xhr.responseText.substring(0, 100));
// });
// /*
// app.xhr("http://ajax.googleapis.com/ajax/libs/prototype/1.7.1.0/prototype.js", function(xhr) {
// console.log("googleapis: should succeed: " + xhr.status);
// console.log("googleapis: " + xhr.responseText.substring(0, 100));
// });
//
// app.xhr("http://code.jquery.com/jquery-1.10.2.min.js", function(xhr) {
// console.log("jquery: should fail: " + xhr.status);
// console.log("jquery: " + xhr.responseText.substring(0, 100));
// });
//
// app.xhr("http://phonegap.com", function(xhr) {
// console.log("phonegap: should fail: " + xhr.status);
// console.log("phonegap: " + xhr.responseText.substring(0, 100));
// });
//
// app.xhr("http://googleapis.com", function(xhr) {
// console.log("googleapis.com: should succeed: " + xhr.status);
// console.log("googleapis.com: " + xhr.responseText.substring(0, 100));
// });
//
// app.xhr("http://jquery.com", function(xhr) {
// console.log("jquery.com: should succeed: " + xhr.status);
// console.log("jquery.com: " + xhr.responseText.substring(0, 100));
// });
// */
//
// },

    camera: function() {
        function onSuccessURI(imageURI) {

            var options = new FileUploadOptions();
            options.fileKey="file";
            options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
            options.mimeType="image/jpeg";

            var params = {};
            params.value1 = "test";
            params.value2 = "param";

            options.params = params;

            var ft = new FileTransfer();
            ft.upload(imageURI, encodeURI("http://216.74.49.91:8080/tssvc/resourcesS/upload"), fileok, filefail, options);

        }
        function onSuccess(imageData) {
            //console.log('success');

            // AT: the old code
            //
            document.getElementById('testMsg').value = "in onSuccess";

            //Anna
            //var image = document.getElementById('myImage');
            //image.src = "data:image/jpeg;base64," + imageData;

            var smallImage = document.getElementById('smallImage');

            // Unhide image elements
            //
            smallImage.style.display = 'block';

            // Show the captured photo
            // The inline CSS rules are used to resize the image
            //
            smallImage.src = "data:image/jpeg;base64," + imageData;

            // Get image handle
            //
            var largeImage = document.getElementById('largeImage');

            // Unhide image elements
            //
            largeImage.style.display = 'block';
            largeImage.src = "data:image/jpeg;base64," + imageData;

        }

        function onFail(message) {
            console.log('failed');
        }
        var cameraPopoverOptions = new CameraPopoverOptions(220, 600, 320, 480, Camera.PopoverArrowDirection.ARROW_DOWN) ;
        var cameraHandle = navigator.camera.getPicture(onSuccessURI, onFail, { quality: 50, saveToPhotoAlbum: true,
            destinationType: Camera.DestinationType.FILE_URI, popoverOptions:cameraPopoverOptions
        });
        //cameraHandle.setPosition(cameraPopoverOptions);
        function fileok(r) {
            document.getElementById('testMsg').value = "Success. Code = " + r.responseCode + " Resposne = " + r.response + " sent = " + r.byteSent;
            //console.log("Response = " + r.response);
            //console.log("Sent = " + r.bytesSent);
        }

        function filefail(error) {
            document.getElementById('testMsg').value = "Error. Code = " + error.code + " source = " + error.source + " target = " + error.target;
            //alert("An error has occurred: Code = " + error.code);
            //console.log("upload error source " + error.source);
            //console.log("upload error target " + error.target);
        }

    },

    getphoto: function() {

        function onSuccess(imageData) {
            //console.log('success');

            document.getElementById('testMsg').value = "in onSuccess";

            //Anna
            //var image = document.getElementById('myImage');
            //image.src = "data:image/jpeg;base64," + imageData;

            var smallImage = document.getElementById('smallImage');

            // Unhide image elements
            //
            smallImage.style.display = 'block';

            // Show the captured photo
            // The inline CSS rules are used to resize the image
            //
            smallImage.src = "data:image/jpeg;base64," + imageData;

            // Get image handle
            //
            var largeImage = document.getElementById('largeImage');

            // Unhide image elements
            //
            largeImage.style.display = 'block';
            largeImage.src = "data:image/jpeg;base64," + imageData;

        }

        function onFail(message) {
            console.log('failed');
        }

        navigator.camera.getPicture(onSuccess, onFail, { quality: 50, saveToPhotoAlbum: true,
            destinationType: Camera.DestinationType.DATA_URL,sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
            mediaType: Camera.MediaType.ALLMEDIA
        });

    },

    xhr: function(url, cb) {
        var xhr1 = new XMLHttpRequest();
        xhr1.onreadystatechange = function(args) {
            if(xhr1.readyState==4)
                cb(xhr1);
        };
        xhr1.open("GET", url, true);
        xhr1.send();
    },

    captureVideo: function() {
        navigator.device.capture.captureVideo(function(mediaFiles)
            {
                console.log('CALLBACK!');
                console.log(JSON.stringify(mediaFiles));
            }, function(error)
            {
                console.log('Video capture failed');
                alert ('video failed');
            },
            {
                limit: 1,
                duration: 12
            });

    },

 /*   // Record audio
//
     recordAudio: function() {
    var src = "myrecording.wav";
    var mediaRec = new Media(src,
        // success callback
        function() {
            console.log("recordAudio():Audio Success");
            alert('audio success');
        },

        // error callback
        function(err) {
            console.log("recordAudio():Audio Error: "+ err.code);
        }
    );

    // Record audio
    mediaRec.startRecord();

    // Stop recording after 10 seconds
    setTimeout(function() {
        mediaRec.stopRecord();
    }, 10000);
}*/

    captureAudio: function() {

        // Called when capture operation is finished
        //
        function captureSuccess(mediaFiles) {

            alert ('audio success');
            var i, len;
            for (i = 0, len = mediaFiles.length; i < len; i += 1) {
                uploadFile(mediaFiles[i]);
            }

        }

        // Called if something bad happens.
        //
        function captureError(error) {
            var msg = 'An error occurred during capture: ' + error.code;
            navigator.notification.alert(msg, null, 'Uh oh!');
        }

        navigator.device.capture.captureAudio(function(mediaFiles)
            {
                console.log('CALLBACK!');
                console.log(JSON.stringify(mediaFiles));
            }, function(error)
            {
                console.log('Audio capture failed');
            },
            {
                limit: 1,
                duration: 12
            });

        // Upload files to server
//        function uploadFile(mediaFile) {
//            var ft = new FileTransfer(),
//                path = mediaFile.fullPath,
//                name = mediaFile.name;
//
//            ft.upload(path,
//                "http://my.domain.com/upload.php",
//                function(result) {
//                    console.log('Upload success: ' + result.responseCode);
//                    console.log(result.bytesSent + ' bytes sent');
//                },
//                function(error) {
//                    console.log('Error uploading file ' + path + ': ' + error.code);
//                },
//                { fileName: name });
//        }

    }
};

<|endoftext|>