text: /*global defineSuite*/
  defineSuite([
          'DataSources/LabelVisualizer',
          'Core/BoundingSphere',
          'Core/Cartesian2',
          'Core/Cartesian3',
          'Core/Color',
          'Core/DistanceDisplayCondition',
          'Core/JulianDate',
          'Core/NearFarScalar',
          'DataSources/BoundingSphereState',
          'DataSources/ConstantProperty',
          'DataSources/EntityCluster',
          'DataSources/EntityCollection',
          'DataSources/LabelGraphics',
          'Scene/HorizontalOrigin',
          'Scene/LabelStyle',
          'Scene/VerticalOrigin',
          'Specs/createGlobe',
          'Specs/createScene'
      ], function(
          LabelVisualizer,
          BoundingSphere,
          Cartesian2,
          Cartesian3,
          Color,
          DistanceDisplayCondition,
          JulianDate,
          NearFarScalar,
          BoundingSphereState,
          ConstantProperty,
          EntityCluster,
          EntityCollection,
          LabelGraphics,
          HorizontalOrigin,
          LabelStyle,
          VerticalOrigin,
          createGlobe,
          createScene) {
      'use strict';
  
      var scene;
      var entityCluster;
      var visualizer;
  
      beforeAll(function() {
          scene = createScene();
          scene.globe = createGlobe();
      });
  
      afterAll(function() {
          scene.destroyForSpecs();
      });
  
      beforeEach(function() {
          entityCluster = new EntityCluster();
          entityCluster._initialize(scene);
      });
  
      afterEach(function() {
          visualizer = visualizer && visualizer.destroy();
          entityCluster.destroy();
      });
  
      it('constructor throws if no scene is passed.', function() {
          expect(function() {
              return new LabelVisualizer();
          }).toThrowDeveloperError();
      });
  
      it('update throws if no time specified.', function() {
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
          expect(function() {
              visualizer.update();
          }).toThrowDeveloperError();
      });
  
      it('isDestroy returns false until destroyed.', function() {
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
          expect(visualizer.isDestroyed()).toEqual(false);
          visualizer.destroy();
          expect(visualizer.isDestroyed()).toEqual(true);
          visualizer = undefined;
      });
  
      it('removes the listener from the entity collection when destroyed', function() {
          var entityCollection = new EntityCollection();
          var visualizer = new LabelVisualizer(entityCluster, entityCollection);
          expect(entityCollection.collectionChanged.numberOfListeners).toEqual(1);
          visualizer = visualizer.destroy();
          expect(entityCollection.collectionChanged.numberOfListeners).toEqual(0);
      });
  
      it('object with no label does not create a label.', function() {
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
  
          var testObject = entityCollection.getOrCreateEntity('test');
          testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112));
          visualizer.update(JulianDate.now());
          expect(scene.primitives.get(0)).toBeUndefined();
      });
  
      it('object with no position does not create a label.', function() {
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
  
          var testObject = entityCollection.getOrCreateEntity('test');
          var label = testObject.label = new LabelGraphics();
          label.show = new ConstantProperty(true);
          label.text = new ConstantProperty('lorum ipsum');
  
          visualizer.update(JulianDate.now());
          expect(scene.primitives.get(0)).toBeUndefined();
      });
  
      it('object with no text does not create a label.', function() {
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
  
          var testObject = entityCollection.getOrCreateEntity('test');
          testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112));
          var label = testObject.label = new LabelGraphics();
          label.show = new ConstantProperty(true);
  
          visualizer.update(JulianDate.now());
          expect(scene.primitives.get(0)).toBeUndefined();
      });
  
      it('A LabelGraphics causes a label to be created and updated.', function() {
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
  
          var testObject = entityCollection.getOrCreateEntity('test');
  
          var time = JulianDate.now();
          var label = testObject.label = new LabelGraphics();
          var l;
  
          testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112));
          label.text = new ConstantProperty('a');
          label.font = new ConstantProperty('sans serif');
          label.style = new ConstantProperty(LabelStyle.FILL);
          label.fillColor = new ConstantProperty(new Color(0.5, 0.8, 0.6, 0.7));
          label.outlineColor = new ConstantProperty(new Color(0.4, 0.3, 0.2, 0.1));
          label.outlineWidth = new ConstantProperty(4.5);
          label.horizontalOrigin = new ConstantProperty(HorizontalOrigin.RIGHT);
          label.verticalOrigin = new ConstantProperty(VerticalOrigin.TOP);
          label.eyeOffset = new ConstantProperty(new Cartesian3(1.0, 2.0, 3.0));
          label.pixelOffset = new ConstantProperty(new Cartesian2(3, 2));
          label.scale = new ConstantProperty(12.5);
          label.show = new ConstantProperty(true);
          label.translucencyByDistance = new ConstantProperty(new NearFarScalar());
          label.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar());
          label.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition());
  
          visualizer.update(time);
  
          var labelCollection = entityCluster._labelCollection;
          expect(labelCollection.length).toEqual(1);
  
          l = labelCollection.get(0);
  
          visualizer.update(time);
          expect(l.position).toEqual(testObject.position.getValue(time));
          expect(l.text).toEqual(testObject.label.text.getValue(time));
          expect(l.font).toEqual(testObject.label.font.getValue(time));
          expect(l.style).toEqual(testObject.label.style.getValue(time));
          expect(l.fillColor).toEqual(testObject.label.fillColor.getValue(time));
          expect(l.outlineColor).toEqual(testObject.label.outlineColor.getValue(time));
          expect(l.outlineWidth).toEqual(testObject.label.outlineWidth.getValue(time));
          expect(l.horizontalOrigin).toEqual(testObject.label.horizontalOrigin.getValue(time));
          expect(l.verticalOrigin).toEqual(testObject.label.verticalOrigin.getValue(time));
          expect(l.eyeOffset).toEqual(testObject.label.eyeOffset.getValue(time));
          expect(l.pixelOffset).toEqual(testObject.label.pixelOffset.getValue(time));
          expect(l.scale).toEqual(testObject.label.scale.getValue(time));
          expect(l.show).toEqual(testObject.label.show.getValue(time));
          expect(l.translucencyByDistance).toEqual(testObject.label.translucencyByDistance.getValue(time));
          expect(l.pixelOffsetScaleByDistance).toEqual(testObject.label.pixelOffsetScaleByDistance.getValue(time));
          expect(l.distanceDisplayCondition).toEqual(testObject.label.distanceDisplayCondition.getValue(time));
  
          testObject.position = new ConstantProperty(new Cartesian3(5678, 1234, 1293434));
          label.text = new ConstantProperty('b');
          label.font = new ConstantProperty('serif');
          label.style = new ConstantProperty(LabelStyle.FILL_AND_OUTLINE);
          label.fillColor = new ConstantProperty(new Color(0.1, 0.2, 0.3, 0.4));
          label.outlineColor = new ConstantProperty(new Color(0.8, 0.7, 0.6, 0.5));
          label.outlineWidth = new ConstantProperty(0.5);
          label.horizontalOrigin = new ConstantProperty(HorizontalOrigin.CENTER);
          label.verticalOrigin = new ConstantProperty(VerticalOrigin.BOTTOM);
          label.eyeOffset = new ConstantProperty(new Cartesian3(3.0, 1.0, 2.0));
          label.pixelOffset = new ConstantProperty(new Cartesian2(2, 3));
          label.scale = new ConstantProperty(2.5);
          label.show = new ConstantProperty(true);
          label.translucencyByDistance = new ConstantProperty(new NearFarScalar());
          label.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar());
          label.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition());
  
          visualizer.update(time);
          expect(l.position).toEqual(testObject.position.getValue(time));
          expect(l.text).toEqual(testObject.label.text.getValue(time));
          expect(l.font).toEqual(testObject.label.font.getValue(time));
          expect(l.style).toEqual(testObject.label.style.getValue(time));
          expect(l.fillColor).toEqual(testObject.label.fillColor.getValue(time));
          expect(l.outlineColor).toEqual(testObject.label.outlineColor.getValue(time));
          expect(l.outlineWidth).toEqual(testObject.label.outlineWidth.getValue(time));
          expect(l.horizontalOrigin).toEqual(testObject.label.horizontalOrigin.getValue(time));
          expect(l.verticalOrigin).toEqual(testObject.label.verticalOrigin.getValue(time));
          expect(l.eyeOffset).toEqual(testObject.label.eyeOffset.getValue(time));
          expect(l.pixelOffset).toEqual(testObject.label.pixelOffset.getValue(time));
          expect(l.scale).toEqual(testObject.label.scale.getValue(time));
          expect(l.show).toEqual(testObject.label.show.getValue(time));
          expect(l.translucencyByDistance).toEqual(testObject.label.translucencyByDistance.getValue(time));
          expect(l.pixelOffsetScaleByDistance).toEqual(testObject.label.pixelOffsetScaleByDistance.getValue(time));
          expect(l.distanceDisplayCondition).toEqual(testObject.label.distanceDisplayCondition.getValue(time));
  
          label.show = new ConstantProperty(false);
          visualizer.update(time);
      });
  
      it('Reuses primitives when hiding one and showing another', function() {
          var time = JulianDate.now();
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
  
          var testObject = entityCollection.getOrCreateEntity('test');
          testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112));
          testObject.label = new LabelGraphics();
          testObject.label.text = new ConstantProperty('a');
          testObject.label.show = new ConstantProperty(true);
  
          visualizer.update(time);
  
          var labelCollection = entityCluster._labelCollection;
          expect(labelCollection.length).toEqual(1);
  
          testObject.label.show = new ConstantProperty(false);
  
          visualizer.update(time);
  
          expect(labelCollection.length).toEqual(1);
  
          var testObject2 = entityCollection.getOrCreateEntity('test2');
          testObject2.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112));
          testObject2.label = new LabelGraphics();
          testObject2.label.text = new ConstantProperty('b');
          testObject2.label.show = new ConstantProperty(true);
  
          visualizer.update(time);
          expect(labelCollection.length).toEqual(1);
      });
  
      it('clear hides labels.', function() {
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
  
          var testObject = entityCollection.getOrCreateEntity('test');
          var time = JulianDate.now();
          var label = testObject.label = new LabelGraphics();
  
          testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112));
          label.show = new ConstantProperty(true);
          label.text = new ConstantProperty('lorum ipsum');
          visualizer.update(time);
  
          var labelCollection = entityCluster._labelCollection;
          expect(labelCollection.length).toEqual(1);
          var l = labelCollection.get(0);
          expect(l.show).toEqual(true);
  
          //Clearing won't actually remove the label because of the
          //internal cache used by the visualizer, instead it just hides it.
          entityCollection.removeAll();
          visualizer.update(time);
          expect(l.show).toEqual(false);
          expect(l.id).toBeUndefined();
      });
  
      it('Visualizer sets entity property.', function() {
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
  
          var testObject = entityCollection.getOrCreateEntity('test');
          var time = JulianDate.now();
          var label = testObject.label = new LabelGraphics();
  
          testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112));
          label.show = new ConstantProperty(true);
          label.text = new ConstantProperty('lorum ipsum');
          visualizer.update(time);
  
          var labelCollection = entityCluster._labelCollection;
          expect(labelCollection.length).toEqual(1);
          var l = labelCollection.get(0);
          expect(l.id).toEqual(testObject);
      });
  
      it('Computes bounding sphere.', function() {
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
  
          var testObject = entityCollection.getOrCreateEntity('test');
          var time = JulianDate.now();
          var label = testObject.label = new LabelGraphics();
  
          testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112));
          label.show = new ConstantProperty(true);
          label.text = new ConstantProperty('lorum ipsum');
          visualizer.update(time);
  
          var result = new BoundingSphere();
          var state = visualizer.getBoundingSphere(testObject, result);
  
          expect(state).toBe(BoundingSphereState.DONE);
          expect(result.center).toEqual(testObject.position.getValue());
          expect(result.radius).toEqual(0);
      });
  
      it('Fails bounding sphere for entity without billboard.', function() {
          var entityCollection = new EntityCollection();
          var testObject = entityCollection.getOrCreateEntity('test');
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
          visualizer.update(JulianDate.now());
          var result = new BoundingSphere();
          var state = visualizer.getBoundingSphere(testObject, result);
          expect(state).toBe(BoundingSphereState.FAILED);
      });
  
      it('Compute bounding sphere throws without entity.', function() {
          var entityCollection = new EntityCollection();
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
          var result = new BoundingSphere();
          expect(function() {
              visualizer.getBoundingSphere(undefined, result);
          }).toThrowDeveloperError();
      });
  
      it('Compute bounding sphere throws without result.', function() {
          var entityCollection = new EntityCollection();
          var testObject = entityCollection.getOrCreateEntity('test');
          visualizer = new LabelVisualizer(entityCluster, entityCollection);
          expect(function() {
              visualizer.getBoundingSphere(testObject, undefined);
          }).toThrowDeveloperError();
      });
  }, 'WebGL');
  