/*
All material copyright Esri, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/5.0/esri/copyright.txt for details.
*/
import{Evented as e}from"../../../core/Evented.js";import{makeHandle as t}from"../../../core/handleUtils.js";import{clone as r}from"../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{isMeshEditGeometry as s,Part as i,EditGeometry as o,haveCompatibleTopologies as a}from"./EditGeometry.js";import{AppendVertex as n}from"./operations/AppendVertex.js";import{UpdateVertices as p}from"./operations/UpdateVertices.js";import{RemoveVertices as d}from"./operations/RemoveVertices.js";import{SplitSegment as h}from"./operations/SplitSegment.js";import{SetVertexPosition as c}from"./operations/SetVertexPosition.js";import{ClosePart as l}from"./operations/ClosePart.js";import{MoveMesh as u}from"./operations/MoveMesh.js";import{MoveVertex as m}from"./operations/MoveVertex.js";import{OffsetEdgeVertex as v}from"./operations/OffsetEdgeVertex.js";import{RotateVertex as y}from"./operations/RotateVertex.js";import{ScaleVertex as V}from"./operations/ScaleVertex.js";import{SetAllVertexPositions as f}from"./operations/SetAllVertexPositions.js";import{UndoGroup as _}from"./operations/UndoGroup.js";class g extends e{constructor(e,t,r=!1){super(),this.data=e,this.viewingMode=t,this.allowCurves=r,this._undoStack=[],this._redoStack=[],this._listener=this.data.on("change",e=>{e.addedVertices&&this.emit("vertex-add",{type:"vertex-add",vertices:e.addedVertices,operation:e.operation}),e.removedVertices&&this.emit("vertex-remove",{type:"vertex-remove",vertices:e.removedVertices,operation:e.operation}),e.updatedVertices&&this.emit("vertex-update",{type:"vertex-update",vertices:e.updatedVertices,operation:e.operation})})}destroy(){super.destroy(),this._listener.remove()}splitSegment(e,t){return this._apply(new h(this.data,e,t))}updateVertices(e,t,r=1){return this._apply(new p(this.data,e,t),r)}move(e,t,r,i=1){return s(this.data)?this._apply(new u(this.data,e,t,r),i):this.moveVertices(this.data.allVerticesUnordered,e,t,r,i)}moveVertices(e,t,r,i,o=1){return s(this.data)?this._apply(new u(this.data,t,r,i),o):this.updateVertices(e,new m(this.data.coordinateHelper,t,r,i),o)}scale(e,t,r,s,i=1,o=0){return this.scaleVertices(this.data.allVerticesUnordered,e,t,r,s,i,o)}scaleVertices(e,t,r,s,i,o=1,a=0){return this.updateVertices(e,new V(t,r,s,i,a),o)}rotate(e,t,r=1,s=0){return this.rotateVertices(this.data.allVerticesUnordered,e,t,r,s)}rotateVertices(e,t,r,s=1,i=0){return this.updateVertices(e,new y(t,r,i),s)}removeVertices(e){return this._apply(new d(this.data,e,this._minNumVerticesPerType))}appendVertex(e,t){return t??=new i(this.data.spatialReference,this.viewingMode),this._apply(new n(this.data,t,e))}appendVertexToFirstPart(e){const t=this.data.parts.at(0);return t?this._apply(new n(this.data,t,e)):null}setVertexPosition(e,t){return this._apply(new c(this.data,e,t))}offsetEdge(e,t,r,s=1){return this.updateVertices([t.leftVertex,t.rightVertex],new v(this.data.coordinateHelper,e,t,r),s)}trySetGeometry(e,t=1){const{data:r}=this,{coordinateHelper:i}=r;if(r.type!==e.type||!r.spatialReference.equals(e.spatialReference)||i.hasZ()!==e.hasZ||i.hasM()!==e.hasM||s(r))return;const n=o.fromGeometry(e,this.viewingMode,{allowCurves:this.allowCurves});return a(r,n)?this.overwriteGeometryDataInPlace(n,t):void 0}overwriteGeometryDataInPlace(e,t=1){return this._apply(new f(this.data,e),t)}createResetState(){if(s(this.data))return this._createResetStateMesh();const e=this.data.geometry.clone();return t(()=>this.trySetGeometry(e))}closePart(e){return this.data.parts.includes(e)?this._apply(new l(this.data,e)):null}canRemoveVertex(e){return e.vertices.length>this._minNumVerticesPerType}createUndoGroup(){const e=new _;return this._apply(e),t(()=>e.close())}recordUndo(e){this._undoStack.push(e),this._redoStack=[]}undo(){if(this._undoStack.length>0){const e=this._undoStack.pop();return e.undo(),this._redoStack.push(e),e}return null}redo(){if(this._redoStack.length>0){const e=this._redoStack.pop();return e.apply(),this._undoStack.push(e),e}return null}get canUndo(){return this._undoStack.length>0}get canRedo(){return this._redoStack.length>0}get lastOperation(){return this._undoStack.length>0?this._undoStack[this._undoStack.length-1]:null}get _minNumVerticesPerType(){switch(this.data.type){case"point":return 1;case"polyline":return 2;case"polygon":return 3;default:return 0}}_apply(e,t=1){return 0!==t&&null!=this.lastOperation&&this.lastOperation.accumulate(e)||(e.apply(),this.recordUndo(e)),e}_createResetStateMesh(){if(!s(this.data))return t();const e=this.data.geometry,{vertexSpace:i}=e;if(i.origin){const s=r(i.origin);return t(()=>{e.vertexSpace.origin=s})}const o=e.vertexAttributes.clonePositional();return t(()=>{e.vertexAttributes=o,e.vertexAttributesChanged()})}static fromGeometry(e,t,r){return new g(o.fromGeometry(e,t,r),t,!!r?.allowCurves)}}export{g as EditGeometryOperations};
