'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _index = require('../../index.js');

var _index2 = _interopRequireDefault(_index);

var _array = require('../../array.js');

var _array2 = _interopRequireDefault(_array);

var _color = require('../../color.js');

var _color2 = _interopRequireDefault(_color);

var _extent = require('../../extent.js');

var _extent2 = _interopRequireDefault(_extent);

var _orient = require('../../geom/flat/orient.js');

var _orient2 = _interopRequireDefault(_orient);

var _transform = require('../../geom/flat/transform.js');

var _transform2 = _interopRequireDefault(_transform);

var _topology = require('../../geom/flat/topology.js');

var _topology2 = _interopRequireDefault(_topology);

var _obj = require('../../obj.js');

var _obj2 = _interopRequireDefault(_obj);

var _webgl = require('../webgl.js');

var _webgl2 = _interopRequireDefault(_webgl);

var _replay = require('../webgl/replay.js');

var _replay2 = _interopRequireDefault(_replay);

var _defaultshader = require('../webgl/linestringreplay/defaultshader.js');

var _defaultshader2 = _interopRequireDefault(_defaultshader);

var _locations = require('../webgl/linestringreplay/defaultshader/locations.js');

var _locations2 = _interopRequireDefault(_locations);

var _webgl3 = require('../../webgl.js');

var _webgl4 = _interopRequireDefault(_webgl3);

var _buffer = require('../../webgl/buffer.js');

var _buffer2 = _interopRequireDefault(_buffer);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

/**
 * @constructor
 * @extends {ol.render.webgl.Replay}
 * @param {number} tolerance Tolerance.
 * @param {ol.Extent} maxExtent Max extent.
 * @struct
 */
var _ol_render_webgl_LineStringReplay_ = function (tolerance, maxExtent) {
  _replay2.default.call(this, tolerance, maxExtent);

  /**
   * @private
   * @type {ol.render.webgl.linestringreplay.defaultshader.Locations}
   */
  this.defaultLocations_ = null;

  /**
   * @private
   * @type {Array.<Array.<?>>}
   */
  this.styles_ = [];

  /**
   * @private
   * @type {Array.<number>}
   */
  this.styleIndices_ = [];

  /**
   * @private
   * @type {{strokeColor: (Array.<number>|null),
   *         lineCap: (string|undefined),
   *         lineDash: Array.<number>,
   *         lineDashOffset: (number|undefined),
   *         lineJoin: (string|undefined),
   *         lineWidth: (number|undefined),
   *         miterLimit: (number|undefined),
   *         changed: boolean}|null}
   */
  this.state_ = {
    strokeColor: null,
    lineCap: undefined,
    lineDash: null,
    lineDashOffset: undefined,
    lineJoin: undefined,
    lineWidth: undefined,
    miterLimit: undefined,
    changed: false
  };
};

_index2.default.inherits(_ol_render_webgl_LineStringReplay_, _replay2.default);

/**
 * Draw one segment.
 * @private
 * @param {Array.<number>} flatCoordinates Flat coordinates.
 * @param {number} offset Offset.
 * @param {number} end End.
 * @param {number} stride Stride.
 */
_ol_render_webgl_LineStringReplay_.prototype.drawCoordinates_ = function (flatCoordinates, offset, end, stride) {

  var i, ii;
  var numVertices = this.vertices.length;
  var numIndices = this.indices.length;
  //To save a vertex, the direction of a point is a product of the sign (1 or -1), a prime from
  //ol.render.webgl.LineStringReplay.Instruction_, and a rounding factor (1 or 2). If the product is even,
  //we round it. If it is odd, we don't.
  var lineJoin = this.state_.lineJoin === 'bevel' ? 0 : this.state_.lineJoin === 'miter' ? 1 : 2;
  var lineCap = this.state_.lineCap === 'butt' ? 0 : this.state_.lineCap === 'square' ? 1 : 2;
  var closed = _topology2.default.lineStringIsClosed(flatCoordinates, offset, end, stride);
  var startCoords, sign, n;
  var lastIndex = numIndices;
  var lastSign = 1;
  //We need the adjacent vertices to define normals in joins. p0 = last, p1 = current, p2 = next.
  var p0, p1, p2;

  for (i = offset, ii = end; i < ii; i += stride) {

    n = numVertices / 7;

    p0 = p1;
    p1 = p2 || [flatCoordinates[i], flatCoordinates[i + 1]];
    //First vertex.
    if (i === offset) {
      p2 = [flatCoordinates[i + stride], flatCoordinates[i + stride + 1]];
      if (end - offset === stride * 2 && _array2.default.equals(p1, p2)) {
        break;
      }
      if (closed) {
        //A closed line! Complete the circle.
        p0 = [flatCoordinates[end - stride * 2], flatCoordinates[end - stride * 2 + 1]];

        startCoords = p2;
      } else {
        //Add the first two/four vertices.

        if (lineCap) {
          numVertices = this.addVertices_([0, 0], p1, p2, lastSign * _ol_render_webgl_LineStringReplay_.Instruction_.BEGIN_LINE_CAP * lineCap, numVertices);

          numVertices = this.addVertices_([0, 0], p1, p2, -lastSign * _ol_render_webgl_LineStringReplay_.Instruction_.BEGIN_LINE_CAP * lineCap, numVertices);

          this.indices[numIndices++] = n + 2;
          this.indices[numIndices++] = n;
          this.indices[numIndices++] = n + 1;

          this.indices[numIndices++] = n + 1;
          this.indices[numIndices++] = n + 3;
          this.indices[numIndices++] = n + 2;
        }

        numVertices = this.addVertices_([0, 0], p1, p2, lastSign * _ol_render_webgl_LineStringReplay_.Instruction_.BEGIN_LINE * (lineCap || 1), numVertices);

        numVertices = this.addVertices_([0, 0], p1, p2, -lastSign * _ol_render_webgl_LineStringReplay_.Instruction_.BEGIN_LINE * (lineCap || 1), numVertices);

        lastIndex = numVertices / 7 - 1;

        continue;
      }
    } else if (i === end - stride) {
      //Last vertex.
      if (closed) {
        //Same as the first vertex.
        p2 = startCoords;
        break;
      } else {
        p0 = p0 || [0, 0];

        numVertices = this.addVertices_(p0, p1, [0, 0], lastSign * _ol_render_webgl_LineStringReplay_.Instruction_.END_LINE * (lineCap || 1), numVertices);

        numVertices = this.addVertices_(p0, p1, [0, 0], -lastSign * _ol_render_webgl_LineStringReplay_.Instruction_.END_LINE * (lineCap || 1), numVertices);

        this.indices[numIndices++] = n;
        this.indices[numIndices++] = lastIndex - 1;
        this.indices[numIndices++] = lastIndex;

        this.indices[numIndices++] = lastIndex;
        this.indices[numIndices++] = n + 1;
        this.indices[numIndices++] = n;

        if (lineCap) {
          numVertices = this.addVertices_(p0, p1, [0, 0], lastSign * _ol_render_webgl_LineStringReplay_.Instruction_.END_LINE_CAP * lineCap, numVertices);

          numVertices = this.addVertices_(p0, p1, [0, 0], -lastSign * _ol_render_webgl_LineStringReplay_.Instruction_.END_LINE_CAP * lineCap, numVertices);

          this.indices[numIndices++] = n + 2;
          this.indices[numIndices++] = n;
          this.indices[numIndices++] = n + 1;

          this.indices[numIndices++] = n + 1;
          this.indices[numIndices++] = n + 3;
          this.indices[numIndices++] = n + 2;
        }

        break;
      }
    } else {
      p2 = [flatCoordinates[i + stride], flatCoordinates[i + stride + 1]];
    }

    // We group CW and straight lines, thus the not so inituitive CCW checking function.
    sign = _webgl2.default.triangleIsCounterClockwise(p0[0], p0[1], p1[0], p1[1], p2[0], p2[1]) ? -1 : 1;

    numVertices = this.addVertices_(p0, p1, p2, sign * _ol_render_webgl_LineStringReplay_.Instruction_.BEVEL_FIRST * (lineJoin || 1), numVertices);

    numVertices = this.addVertices_(p0, p1, p2, sign * _ol_render_webgl_LineStringReplay_.Instruction_.BEVEL_SECOND * (lineJoin || 1), numVertices);

    numVertices = this.addVertices_(p0, p1, p2, -sign * _ol_render_webgl_LineStringReplay_.Instruction_.MITER_BOTTOM * (lineJoin || 1), numVertices);

    if (i > offset) {
      this.indices[numIndices++] = n;
      this.indices[numIndices++] = lastIndex - 1;
      this.indices[numIndices++] = lastIndex;

      this.indices[numIndices++] = n + 2;
      this.indices[numIndices++] = n;
      this.indices[numIndices++] = lastSign * sign > 0 ? lastIndex : lastIndex - 1;
    }

    this.indices[numIndices++] = n;
    this.indices[numIndices++] = n + 2;
    this.indices[numIndices++] = n + 1;

    lastIndex = n + 2;
    lastSign = sign;

    //Add miter
    if (lineJoin) {
      numVertices = this.addVertices_(p0, p1, p2, sign * _ol_render_webgl_LineStringReplay_.Instruction_.MITER_TOP * lineJoin, numVertices);

      this.indices[numIndices++] = n + 1;
      this.indices[numIndices++] = n + 3;
      this.indices[numIndices++] = n;
    }
  }

  if (closed) {
    n = n || numVertices / 7;
    sign = _orient2.default.linearRingIsClockwise([p0[0], p0[1], p1[0], p1[1], p2[0], p2[1]], 0, 6, 2) ? 1 : -1;

    numVertices = this.addVertices_(p0, p1, p2, sign * _ol_render_webgl_LineStringReplay_.Instruction_.BEVEL_FIRST * (lineJoin || 1), numVertices);

    numVertices = this.addVertices_(p0, p1, p2, -sign * _ol_render_webgl_LineStringReplay_.Instruction_.MITER_BOTTOM * (lineJoin || 1), numVertices);

    this.indices[numIndices++] = n;
    this.indices[numIndices++] = lastIndex - 1;
    this.indices[numIndices++] = lastIndex;

    this.indices[numIndices++] = n + 1;
    this.indices[numIndices++] = n;
    this.indices[numIndices++] = lastSign * sign > 0 ? lastIndex : lastIndex - 1;
  }
};

/**
 * @param {Array.<number>} p0 Last coordinates.
 * @param {Array.<number>} p1 Current coordinates.
 * @param {Array.<number>} p2 Next coordinates.
 * @param {number} product Sign, instruction, and rounding product.
 * @param {number} numVertices Vertex counter.
 * @return {number} Vertex counter.
 * @private
 */
_ol_render_webgl_LineStringReplay_.prototype.addVertices_ = function (p0, p1, p2, product, numVertices) {
  this.vertices[numVertices++] = p0[0];
  this.vertices[numVertices++] = p0[1];
  this.vertices[numVertices++] = p1[0];
  this.vertices[numVertices++] = p1[1];
  this.vertices[numVertices++] = p2[0];
  this.vertices[numVertices++] = p2[1];
  this.vertices[numVertices++] = product;

  return numVertices;
};

/**
 * Check if the linestring can be drawn (i. e. valid).
 * @param {Array.<number>} flatCoordinates Flat coordinates.
 * @param {number} offset Offset.
 * @param {number} end End.
 * @param {number} stride Stride.
 * @return {boolean} The linestring can be drawn.
 * @private
 */
_ol_render_webgl_LineStringReplay_.prototype.isValid_ = function (flatCoordinates, offset, end, stride) {
  var range = end - offset;
  if (range < stride * 2) {
    return false;
  } else if (range === stride * 2) {
    var firstP = [flatCoordinates[offset], flatCoordinates[offset + 1]];
    var lastP = [flatCoordinates[offset + stride], flatCoordinates[offset + stride + 1]];
    return !_array2.default.equals(firstP, lastP);
  }

  return true;
};

/**
 * @inheritDoc
 */
_ol_render_webgl_LineStringReplay_.prototype.drawLineString = function (lineStringGeometry, feature) {
  var flatCoordinates = lineStringGeometry.getFlatCoordinates();
  var stride = lineStringGeometry.getStride();
  if (this.isValid_(flatCoordinates, 0, flatCoordinates.length, stride)) {
    flatCoordinates = _transform2.default.translate(flatCoordinates, 0, flatCoordinates.length, stride, -this.origin[0], -this.origin[1]);
    if (this.state_.changed) {
      this.styleIndices_.push(this.indices.length);
      this.state_.changed = false;
    }
    this.startIndices.push(this.indices.length);
    this.startIndicesFeature.push(feature);
    this.drawCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);
  }
};

/**
 * @inheritDoc
 */
_ol_render_webgl_LineStringReplay_.prototype.drawMultiLineString = function (multiLineStringGeometry, feature) {
  var indexCount = this.indices.length;
  var ends = multiLineStringGeometry.getEnds();
  ends.unshift(0);
  var flatCoordinates = multiLineStringGeometry.getFlatCoordinates();
  var stride = multiLineStringGeometry.getStride();
  var i, ii;
  if (ends.length > 1) {
    for (i = 1, ii = ends.length; i < ii; ++i) {
      if (this.isValid_(flatCoordinates, ends[i - 1], ends[i], stride)) {
        var lineString = _transform2.default.translate(flatCoordinates, ends[i - 1], ends[i], stride, -this.origin[0], -this.origin[1]);
        this.drawCoordinates_(lineString, 0, lineString.length, stride);
      }
    }
  }
  if (this.indices.length > indexCount) {
    this.startIndices.push(indexCount);
    this.startIndicesFeature.push(feature);
    if (this.state_.changed) {
      this.styleIndices_.push(indexCount);
      this.state_.changed = false;
    }
  }
};

/**
 * @param {Array.<number>} flatCoordinates Flat coordinates.
 * @param {Array.<Array.<number>>} holeFlatCoordinates Hole flat coordinates.
 * @param {number} stride Stride.
 */
_ol_render_webgl_LineStringReplay_.prototype.drawPolygonCoordinates = function (flatCoordinates, holeFlatCoordinates, stride) {
  if (!_topology2.default.lineStringIsClosed(flatCoordinates, 0, flatCoordinates.length, stride)) {
    flatCoordinates.push(flatCoordinates[0]);
    flatCoordinates.push(flatCoordinates[1]);
  }
  this.drawCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);
  if (holeFlatCoordinates.length) {
    var i, ii;
    for (i = 0, ii = holeFlatCoordinates.length; i < ii; ++i) {
      if (!_topology2.default.lineStringIsClosed(holeFlatCoordinates[i], 0, holeFlatCoordinates[i].length, stride)) {
        holeFlatCoordinates[i].push(holeFlatCoordinates[i][0]);
        holeFlatCoordinates[i].push(holeFlatCoordinates[i][1]);
      }
      this.drawCoordinates_(holeFlatCoordinates[i], 0, holeFlatCoordinates[i].length, stride);
    }
  }
};

/**
 * @param {ol.Feature|ol.render.Feature} feature Feature.
 * @param {number=} opt_index Index count.
 */
_ol_render_webgl_LineStringReplay_.prototype.setPolygonStyle = function (feature, opt_index) {
  var index = opt_index === undefined ? this.indices.length : opt_index;
  this.startIndices.push(index);
  this.startIndicesFeature.push(feature);
  if (this.state_.changed) {
    this.styleIndices_.push(index);
    this.state_.changed = false;
  }
};

/**
 * @return {number} Current index.
 */
_ol_render_webgl_LineStringReplay_.prototype.getCurrentIndex = function () {
  return this.indices.length;
};

/**
 * @inheritDoc
 **/
_ol_render_webgl_LineStringReplay_.prototype.finish = function (context) {
  // create, bind, and populate the vertices buffer
  this.verticesBuffer = new _buffer2.default(this.vertices);

  // create, bind, and populate the indices buffer
  this.indicesBuffer = new _buffer2.default(this.indices);

  this.startIndices.push(this.indices.length);

  //Clean up, if there is nothing to draw
  if (this.styleIndices_.length === 0 && this.styles_.length > 0) {
    this.styles_ = [];
  }

  this.vertices = null;
  this.indices = null;
};

/**
 * @inheritDoc
 */
_ol_render_webgl_LineStringReplay_.prototype.getDeleteResourcesFunction = function (context) {
  var verticesBuffer = this.verticesBuffer;
  var indicesBuffer = this.indicesBuffer;
  return function () {
    context.deleteBuffer(verticesBuffer);
    context.deleteBuffer(indicesBuffer);
  };
};

/**
 * @inheritDoc
 */
_ol_render_webgl_LineStringReplay_.prototype.setUpProgram = function (gl, context, size, pixelRatio) {
  // get the program
  var fragmentShader, vertexShader;
  fragmentShader = _defaultshader2.default.fragment;
  vertexShader = _defaultshader2.default.vertex;
  var program = context.getProgram(fragmentShader, vertexShader);

  // get the locations
  var locations;
  if (!this.defaultLocations_) {
    locations = new _locations2.default(gl, program);
    this.defaultLocations_ = locations;
  } else {
    locations = this.defaultLocations_;
  }

  context.useProgram(program);

  // enable the vertex attrib arrays
  gl.enableVertexAttribArray(locations.a_lastPos);
  gl.vertexAttribPointer(locations.a_lastPos, 2, _webgl4.default.FLOAT, false, 28, 0);

  gl.enableVertexAttribArray(locations.a_position);
  gl.vertexAttribPointer(locations.a_position, 2, _webgl4.default.FLOAT, false, 28, 8);

  gl.enableVertexAttribArray(locations.a_nextPos);
  gl.vertexAttribPointer(locations.a_nextPos, 2, _webgl4.default.FLOAT, false, 28, 16);

  gl.enableVertexAttribArray(locations.a_direction);
  gl.vertexAttribPointer(locations.a_direction, 1, _webgl4.default.FLOAT, false, 28, 24);

  // Enable renderer specific uniforms.
  gl.uniform2fv(locations.u_size, size);
  gl.uniform1f(locations.u_pixelRatio, pixelRatio);

  return locations;
};

/**
 * @inheritDoc
 */
_ol_render_webgl_LineStringReplay_.prototype.shutDownProgram = function (gl, locations) {
  gl.disableVertexAttribArray(locations.a_lastPos);
  gl.disableVertexAttribArray(locations.a_position);
  gl.disableVertexAttribArray(locations.a_nextPos);
  gl.disableVertexAttribArray(locations.a_direction);
};

/**
 * @inheritDoc
 */
_ol_render_webgl_LineStringReplay_.prototype.drawReplay = function (gl, context, skippedFeaturesHash, hitDetection) {
  //Save GL parameters.
  var tmpDepthFunc = /** @type {number} */gl.getParameter(gl.DEPTH_FUNC);
  var tmpDepthMask = /** @type {boolean} */gl.getParameter(gl.DEPTH_WRITEMASK);

  if (!hitDetection) {
    gl.enable(gl.DEPTH_TEST);
    gl.depthMask(true);
    gl.depthFunc(gl.NOTEQUAL);
  }

  if (!_obj2.default.isEmpty(skippedFeaturesHash)) {
    this.drawReplaySkipping_(gl, context, skippedFeaturesHash);
  } else {
    //Draw by style groups to minimize drawElements() calls.
    var i, start, end, nextStyle;
    end = this.startIndices[this.startIndices.length - 1];
    for (i = this.styleIndices_.length - 1; i >= 0; --i) {
      start = this.styleIndices_[i];
      nextStyle = this.styles_[i];
      this.setStrokeStyle_(gl, nextStyle[0], nextStyle[1], nextStyle[2]);
      this.drawElements(gl, context, start, end);
      gl.clear(gl.DEPTH_BUFFER_BIT);
      end = start;
    }
  }
  if (!hitDetection) {
    gl.disable(gl.DEPTH_TEST);
    gl.clear(gl.DEPTH_BUFFER_BIT);
    //Restore GL parameters.
    gl.depthMask(tmpDepthMask);
    gl.depthFunc(tmpDepthFunc);
  }
};

/**
 * @private
 * @param {WebGLRenderingContext} gl gl.
 * @param {ol.webgl.Context} context Context.
 * @param {Object} skippedFeaturesHash Ids of features to skip.
 */
_ol_render_webgl_LineStringReplay_.prototype.drawReplaySkipping_ = function (gl, context, skippedFeaturesHash) {
  var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex, featureStart;
  featureIndex = this.startIndices.length - 2;
  end = start = this.startIndices[featureIndex + 1];
  for (i = this.styleIndices_.length - 1; i >= 0; --i) {
    nextStyle = this.styles_[i];
    this.setStrokeStyle_(gl, nextStyle[0], nextStyle[1], nextStyle[2]);
    groupStart = this.styleIndices_[i];

    while (featureIndex >= 0 && this.startIndices[featureIndex] >= groupStart) {
      featureStart = this.startIndices[featureIndex];
      feature = this.startIndicesFeature[featureIndex];
      featureUid = _index2.default.getUid(feature).toString();

      if (skippedFeaturesHash[featureUid]) {
        if (start !== end) {
          this.drawElements(gl, context, start, end);
          gl.clear(gl.DEPTH_BUFFER_BIT);
        }
        end = featureStart;
      }
      featureIndex--;
      start = featureStart;
    }
    if (start !== end) {
      this.drawElements(gl, context, start, end);
      gl.clear(gl.DEPTH_BUFFER_BIT);
    }
    start = end = groupStart;
  }
};

/**
 * @inheritDoc
 */
_ol_render_webgl_LineStringReplay_.prototype.drawHitDetectionReplayOneByOne = function (gl, context, skippedFeaturesHash, featureCallback, opt_hitExtent) {
  var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex;
  featureIndex = this.startIndices.length - 2;
  end = this.startIndices[featureIndex + 1];
  for (i = this.styleIndices_.length - 1; i >= 0; --i) {
    nextStyle = this.styles_[i];
    this.setStrokeStyle_(gl, nextStyle[0], nextStyle[1], nextStyle[2]);
    groupStart = this.styleIndices_[i];

    while (featureIndex >= 0 && this.startIndices[featureIndex] >= groupStart) {
      start = this.startIndices[featureIndex];
      feature = this.startIndicesFeature[featureIndex];
      featureUid = _index2.default.getUid(feature).toString();

      if (skippedFeaturesHash[featureUid] === undefined && feature.getGeometry() && (opt_hitExtent === undefined || _extent2.default.intersects(
      /** @type {Array<number>} */opt_hitExtent, feature.getGeometry().getExtent()))) {
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        this.drawElements(gl, context, start, end);

        var result = featureCallback(feature);

        if (result) {
          return result;
        }
      }
      featureIndex--;
      end = start;
    }
  }
  return undefined;
};

/**
 * @private
 * @param {WebGLRenderingContext} gl gl.
 * @param {Array.<number>} color Color.
 * @param {number} lineWidth Line width.
 * @param {number} miterLimit Miter limit.
 */
_ol_render_webgl_LineStringReplay_.prototype.setStrokeStyle_ = function (gl, color, lineWidth, miterLimit) {
  gl.uniform4fv(this.defaultLocations_.u_color, color);
  gl.uniform1f(this.defaultLocations_.u_lineWidth, lineWidth);
  gl.uniform1f(this.defaultLocations_.u_miterLimit, miterLimit);
};

/**
 * @inheritDoc
 */
_ol_render_webgl_LineStringReplay_.prototype.setFillStrokeStyle = function (fillStyle, strokeStyle) {
  var strokeStyleLineCap = strokeStyle.getLineCap();
  this.state_.lineCap = strokeStyleLineCap !== undefined ? strokeStyleLineCap : _webgl2.default.defaultLineCap;
  var strokeStyleLineDash = strokeStyle.getLineDash();
  this.state_.lineDash = strokeStyleLineDash ? strokeStyleLineDash : _webgl2.default.defaultLineDash;
  var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
  this.state_.lineDashOffset = strokeStyleLineDashOffset ? strokeStyleLineDashOffset : _webgl2.default.defaultLineDashOffset;
  var strokeStyleLineJoin = strokeStyle.getLineJoin();
  this.state_.lineJoin = strokeStyleLineJoin !== undefined ? strokeStyleLineJoin : _webgl2.default.defaultLineJoin;
  var strokeStyleColor = strokeStyle.getColor();
  if (!(strokeStyleColor instanceof CanvasGradient) && !(strokeStyleColor instanceof CanvasPattern)) {
    strokeStyleColor = _color2.default.asArray(strokeStyleColor).map(function (c, i) {
      return i != 3 ? c / 255 : c;
    }) || _webgl2.default.defaultStrokeStyle;
  } else {
    strokeStyleColor = _webgl2.default.defaultStrokeStyle;
  }
  var strokeStyleWidth = strokeStyle.getWidth();
  strokeStyleWidth = strokeStyleWidth !== undefined ? strokeStyleWidth : _webgl2.default.defaultLineWidth;
  var strokeStyleMiterLimit = strokeStyle.getMiterLimit();
  strokeStyleMiterLimit = strokeStyleMiterLimit !== undefined ? strokeStyleMiterLimit : _webgl2.default.defaultMiterLimit;
  if (!this.state_.strokeColor || !_array2.default.equals(this.state_.strokeColor, strokeStyleColor) || this.state_.lineWidth !== strokeStyleWidth || this.state_.miterLimit !== strokeStyleMiterLimit) {
    this.state_.changed = true;
    this.state_.strokeColor = strokeStyleColor;
    this.state_.lineWidth = strokeStyleWidth;
    this.state_.miterLimit = strokeStyleMiterLimit;
    this.styles_.push([strokeStyleColor, strokeStyleWidth, strokeStyleMiterLimit]);
  }
};

/**
 * @enum {number}
 * @private
 */
_ol_render_webgl_LineStringReplay_.Instruction_ = {
  ROUND: 2,
  BEGIN_LINE: 3,
  END_LINE: 5,
  BEGIN_LINE_CAP: 7,
  END_LINE_CAP: 11,
  BEVEL_FIRST: 13,
  BEVEL_SECOND: 17,
  MITER_BOTTOM: 19,
  MITER_TOP: 23
};
exports.default = _ol_render_webgl_LineStringReplay_;
module.exports = exports['default'];