import Location from '../../geom/Location'
import CGAlgorithms from '../CGAlgorithms'
import Polygon from '../../geom/Polygon'
import PointOnGeometryLocator from './PointOnGeometryLocator'
import GeometryCollectionIterator from '../../geom/GeometryCollectionIterator'
import GeometryCollection from '../../geom/GeometryCollection'

export default class SimplePointInAreaLocator {
  constructor () {
    this._geom = null
    const geom = arguments[0]
    this._geom = geom
  }
  locate (p) {
    return SimplePointInAreaLocator.locate(p, this._geom)
  }
  interfaces_ () {
    return [PointOnGeometryLocator]
  }
  getClass () {
    return SimplePointInAreaLocator
  }
  static isPointInRing (p, ring) {
    if (!ring.getEnvelopeInternal().intersects(p)) return false
    return CGAlgorithms.isPointInRing(p, ring.getCoordinates())
  }
  static containsPointInPolygon (p, poly) {
    if (poly.isEmpty()) return false
    const shell = poly.getExteriorRing()
    if (!SimplePointInAreaLocator.isPointInRing(p, shell)) return false
    for (let i = 0; i < poly.getNumInteriorRing(); i++) {
      const hole = poly.getInteriorRingN(i)
      if (SimplePointInAreaLocator.isPointInRing(p, hole)) return false
    }
    return true
  }
  static containsPoint (p, geom) {
    if (geom instanceof Polygon) {
      return SimplePointInAreaLocator.containsPointInPolygon(p, geom)
    } else if (geom instanceof GeometryCollection) {
      const geomi = new GeometryCollectionIterator(geom)
      while (geomi.hasNext()) {
        const g2 = geomi.next()
        if (g2 !== geom) if (SimplePointInAreaLocator.containsPoint(p, g2)) return true
      }
    }
    return false
  }
  static locate (p, geom) {
    if (geom.isEmpty()) return Location.EXTERIOR
    if (SimplePointInAreaLocator.containsPoint(p, geom)) return Location.INTERIOR
    return Location.EXTERIOR
  }
}
