1919using SIL . LCModel . Core . WritingSystems ;
2020using SIL . LCModel . DomainServices ;
2121using SIL . LCModel . Infrastructure ;
22+ using CollectionExtensions = SIL . Extensions . CollectionExtensions ;
2223
2324namespace FwDataMiniLcmBridge . Api ;
2425
@@ -94,7 +95,7 @@ public Task<WritingSystems> GetWritingSystems()
9495 {
9596 Vernacular = WritingSystemContainer . CurrentVernacularWritingSystems . Select ( ( definition , index ) =>
9697 FromLcmWritingSystem ( definition , index , WritingSystemType . Vernacular ) ) . ToArray ( ) ,
97- Analysis = Cache . ServiceLocator . WritingSystems . CurrentAnalysisWritingSystems . Select ( ( definition , index ) =>
98+ Analysis = WritingSystemContainer . CurrentAnalysisWritingSystems . Select ( ( definition , index ) =>
9899 FromLcmWritingSystem ( definition , index , WritingSystemType . Analysis ) ) . ToArray ( )
99100 } ;
100101 CompleteExemplars ( writingSystems ) ;
@@ -117,15 +118,15 @@ private WritingSystem FromLcmWritingSystem(CoreWritingSystemDefinition ws, int i
117118 } ;
118119 }
119120
120- public async Task < WritingSystem > GetWritingSystem ( WritingSystemId id , WritingSystemType type )
121+ public async Task < WritingSystem ? > GetWritingSystem ( WritingSystemId id , WritingSystemType type )
121122 {
122123 var writingSystems = await GetWritingSystems ( ) ;
123124 return type switch
124125 {
125126 WritingSystemType . Vernacular => writingSystems . Vernacular . FirstOrDefault ( ws => ws . WsId == id ) ,
126127 WritingSystemType . Analysis => writingSystems . Analysis . FirstOrDefault ( ws => ws . WsId == id ) ,
127128 _ => throw new ArgumentOutOfRangeException ( nameof ( type ) , type , null )
128- } ?? throw new NullReferenceException ( $ "unable to find writing system with id { id } " ) ;
129+ } ;
129130 }
130131
131132 internal void CompleteExemplars ( WritingSystems writingSystems )
@@ -149,7 +150,7 @@ internal void CompleteExemplars(WritingSystems writingSystems)
149150 }
150151 }
151152
152- public async Task < WritingSystem > CreateWritingSystem ( WritingSystem writingSystem )
153+ public async Task < WritingSystem > CreateWritingSystem ( WritingSystem writingSystem , BetweenPosition < WritingSystemId ? > ? between = null )
153154 {
154155 var type = writingSystem . Type ;
155156 var exitingWs = type == WritingSystemType . Analysis ? Cache . ServiceLocator . WritingSystems . AnalysisWritingSystems : Cache . ServiceLocator . WritingSystems . VernacularWritingSystems ;
@@ -158,10 +159,9 @@ public async Task<WritingSystem> CreateWritingSystem(WritingSystem writingSystem
158159 throw new DuplicateObjectException ( $ "Writing system { writingSystem . WsId . Code } already exists") ;
159160 }
160161 CoreWritingSystemDefinition ? ws = null ;
161- UndoableUnitOfWorkHelper . DoUsingNewOrCurrentUOW ( "Create Writing System" ,
162+ await Cache . DoUsingNewOrCurrentUOW ( "Create Writing System" ,
162163 "Remove writing system" ,
163- Cache . ServiceLocator . ActionHandler ,
164- ( ) =>
164+ async ( ) =>
165165 {
166166 Cache . ServiceLocator . WritingSystemManager . GetOrSet ( writingSystem . WsId . Code , out ws ) ;
167167 ws . Abbreviation = writingSystem . Abbreviation ;
@@ -176,6 +176,9 @@ public async Task<WritingSystem> CreateWritingSystem(WritingSystem writingSystem
176176 default :
177177 throw new ArgumentOutOfRangeException ( nameof ( type ) , type , null ) ;
178178 }
179+
180+ if ( between is not null && ( between . Previous is not null || between . Next is not null ) )
181+ await MoveWritingSystem ( writingSystem . WsId , type , between ) ;
179182 } ) ;
180183 if ( ws is null ) throw new InvalidOperationException ( "Writing system not found" ) ;
181184 var index = type switch
@@ -205,7 +208,7 @@ await Cache.DoUsingNewOrCurrentUOW("Update WritingSystem",
205208 update . Apply ( updateProxy ) ;
206209 return ValueTask . CompletedTask ;
207210 } ) ;
208- return await GetWritingSystem ( id , type ) ;
211+ return await GetWritingSystem ( id , type ) ?? throw new NullReferenceException ( $ "unable to find writing system with id { id } " ) ;
209212 }
210213
211214 public async Task < WritingSystem > UpdateWritingSystem ( WritingSystem before , WritingSystem after , IMiniLcmApi ? api = null )
@@ -219,6 +222,61 @@ await Cache.DoUsingNewOrCurrentUOW("Update WritingSystem",
219222 return await GetWritingSystem ( after . WsId , after . Type ) ?? throw new NullReferenceException ( $ "unable to find { after . Type } writing system with id { after . WsId } ") ;
220223 }
221224
225+ public async Task MoveWritingSystem ( WritingSystemId id , WritingSystemType type , BetweenPosition < WritingSystemId ? > between )
226+ {
227+ var wsToUpdate = GetLexWritingSystem ( id , type ) ;
228+ if ( wsToUpdate is null ) throw new NullReferenceException ( $ "unable to find writing system with id { id } ") ;
229+ var previousWs = between . Previous is null ? null : GetLexWritingSystem ( between . Previous . Value , type ) ;
230+ var nextWs = between . Next is null ? null : GetLexWritingSystem ( between . Next . Value , type ) ;
231+ if ( nextWs is null && previousWs is null ) throw new NullReferenceException ( $ "unable to find writing system with id { between . Previous } or { between . Next } ") ;
232+ await Cache . DoUsingNewOrCurrentUOW ( "Move WritingSystem" ,
233+ "Revert Move WritingSystem" ,
234+ ( ) =>
235+ {
236+ var exitingWs = type == WritingSystemType . Analysis
237+ ? WritingSystemContainer . AnalysisWritingSystems
238+ : WritingSystemContainer . VernacularWritingSystems ;
239+ var currentExistingWs = type == WritingSystemType . Analysis
240+ ? WritingSystemContainer . CurrentAnalysisWritingSystems
241+ : WritingSystemContainer . CurrentVernacularWritingSystems ;
242+ MoveWs ( wsToUpdate , previousWs , nextWs , exitingWs ) ;
243+ MoveWs ( wsToUpdate , previousWs , nextWs , currentExistingWs ) ;
244+
245+ void MoveWs ( CoreWritingSystemDefinition ws ,
246+ CoreWritingSystemDefinition ? previous ,
247+ CoreWritingSystemDefinition ? next ,
248+ ICollection < CoreWritingSystemDefinition > list )
249+ {
250+ var index = - 1 ;
251+ if ( previous is not null )
252+ {
253+ index = CollectionExtensions . IndexOf ( list , previous ) ;
254+ if ( index >= 0 ) index ++ ;
255+ }
256+
257+ if ( index < 0 && next is not null )
258+ {
259+ index = CollectionExtensions . IndexOf ( list , next ) ;
260+ }
261+
262+ if ( index < 0 )
263+ throw new InvalidOperationException ( "unable to find writing system with id " + between . Previous + " or " + between . Next ) ;
264+
265+ LcmHelpers . AddOrMoveInList ( list , index , ws ) ;
266+ }
267+
268+ return ValueTask . CompletedTask ;
269+ } ) ;
270+ }
271+
272+ private CoreWritingSystemDefinition ? GetLexWritingSystem ( WritingSystemId id , WritingSystemType type )
273+ {
274+ var exitingWs = type == WritingSystemType . Analysis
275+ ? WritingSystemContainer . AnalysisWritingSystems
276+ : WritingSystemContainer . VernacularWritingSystems ;
277+ return exitingWs . FirstOrDefault ( ws => ws . Id == id ) ;
278+ }
279+
222280 public IAsyncEnumerable < PartOfSpeech > GetPartsOfSpeech ( )
223281 {
224282 return PartOfSpeechRepository
0 commit comments