/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 ĠSeb astian ĠK as par i Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġre compose . composer . ext Ċ Ċ import Ġre compose . ast . Node Ċ import Ġre compose . ast . values . Constraints Ċ import Ġre compose . ast . view group . Constraint Layout Node Ċ import Ġre compose . composer . model . Chain Ċ Ċ /** Ċ Ġ* ĠFinds Ġall Ġreferences Ġused Ġin Ġconstraints . Ċ Ġ*/ Ċ internal Ġfun ĠConstraint Layout Node . find Refs (): ĠSet < String > Ġ{ ĊĠĠĠ Ġreturn Ġview Group . children ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġnode Ġ-> Ġnode . view . constraints . collect Refs (). map Ġ{ Ġit . id Ġ} Ġ+ Ġnode . get Ref () Ġ} ĊĠĠĠĠĠĠĠ Ġ. flatten () ĊĠĠĠĠĠĠĠ Ġ. toSet () Ċ } Ċ Ċ /** Ċ Ġ* ĠFinds Ġall Ġhorizontal Ġand Ġvertical Ġchains Ġin Ġthe ĠConstraint Layout . Ċ Ġ*/ Ċ internal Ġfun ĠConstraint Layout Node . find Ch ains (): ĠSet < Chain > Ġ{ ĊĠĠĠ Ġreturn Ġfind Ch ains In ( Chain . Direction . HORIZONTAL ) Ġ+ Ġfind Ch ains In ( Chain . Direction . VERTICAL ) Ċ } Ċ Ċ /** Ċ Ġ* ĠFinds Ġall Ġchains Ġin Ġthe Ġprovided Ġ[ direction ]. Ċ Ġ*/ Ċ private Ġfun ĠConstraint Layout Node . find Ch ains In ( direction : ĠChain . Direction ): ĠSet < Chain > Ġ{ ĊĠĠĠ Ġval Ġlookup Map Ġ= Ġmutable Map Of < String , ĠNode >() ĊĠĠĠ Ġview Group . children . forEach Ġ{ Ġnode Ġ-> ĊĠĠĠĠĠĠĠ Ġlookup Map [ node . get Ref ()] Ġ= Ġnode ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġchain Builder Ġ= ĠChain Builder ( direction ) ĊĊĠĠĠ Ġview Group . children . forEach Ġ{ Ġnode Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġtail Node Ġ= Ġnode . find Tail Node In ( direction , Ġlookup Map ) ĊĠĠĠĠĠĠĠ Ġif Ġ( tail Node Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Builder . add Link ( node , Ġtail Node ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġchain Builder . build () Ċ } Ċ Ċ /** Ċ Ġ* ĠFinds Ġthe Ġtail Ġnode Ġof Ġthis Ġnode . Ċ Ġ* Ċ Ġ* ĠTail Ġnode Ġhere Ġmeans Ġthe Ġnode Ġfollowing Ġthis Ġnode Ġin Ġa Ġchain . Ċ Ġ*/ Ċ @ Suppress (" Return Count ") Ċ private Ġfun ĠNode . find Tail Node In ( ĊĠĠĠ Ġdirection : ĠChain . Direction , ĊĠĠĠ Ġlookup Map : ĠMap < String , ĠNode > Ċ ): ĠNode ? Ġ{ ĊĠĠĠ Ġval Ġid Ġ= Ġview . constraints . tail Id ( direction ) Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġif Ġ( id Ġ== ĠConstraints . Id . Parent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġtail Ref Ġ= Ġ( id Ġas ĠConstraints . Id . View ). id ĊĠĠĠ Ġval Ġtail Ġ= Ġlookup Map [ tail Ref ] ĊĊĠĠĠ Ġval Ġhead Id Ġ= Ġtail ?. view ?. constraints ?. head Id ( direction ) Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġif Ġ( head Id Ġ! is ĠConstraints . Id . View ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġif Ġ( head Id . id Ġ== Ġthis . get Ref ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġtail ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠConstraints . tail Id ( direction : ĠChain . Direction ): ĠConstraints . Id ? Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠ ĠChain . Direction . HORIZONTAL Ġ-> Ġhorizontal Tail Id () ĊĠĠĠĠĠĠĠ ĠChain . Direction . VERTICAL Ġ-> Ġvertical Tail Id () ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠConstraints . head Id ( direction : ĠChain . Direction ): ĠConstraints . Id ? Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠ ĠChain . Direction . HORIZONTAL Ġ-> Ġhorizontal Head Id () ĊĠĠĠĠĠĠĠ ĠChain . Direction . VERTICAL Ġ-> Ġvertical Head Id () ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠConstraints . horizontal Tail Id (): ĠConstraints . Id ? Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġrelative . end To Start Ġ!= Ġnull Ġ-> Ġrelative . end To Start ĊĠĠĠĠĠĠĠ Ġrelative . right To Left Ġ!= Ġnull Ġ-> Ġrelative . right To Left ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠConstraints . vertical Tail Id (): ĠConstraints . Id ? Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġrelative . bottom To Top Ġ!= Ġnull Ġ-> Ġrelative . bottom To Top ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠConstraints . horizontal Head Id (): ĠConstraints . Id ? Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġrelative . start ToEnd Ġ!= Ġnull Ġ-> Ġrelative . start ToEnd ĊĠĠĠĠĠĠĠ Ġrelative . left To Right Ġ!= Ġnull Ġ-> Ġrelative . left To Right ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠConstraints . vertical Head Id (): ĠConstraints . Id ? Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġrelative . top To Bottom Ġ!= Ġnull Ġ-> Ġrelative . top To Bottom ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠBuilds Ġa Ġ[ Set ] Ġof Ġ[ Chain ] s Ġfrom Ġthe Ġprovided Ġlinks Ġvia Ġ[ add Link ]. Ċ Ġ*/ Ċ private Ġclass ĠChain Builder ( ĊĠĠĠ Ġprivate Ġval Ġdirection : ĠChain . Direction Ċ ) Ġ{ ĊĠĠĠ Ġval Ġchains Ġ= Ġmutable Map Of < Node , ĠSet < Node >>() ĊĊĠĠĠ Ġprivate Ġfun Ġhead With Tail ( chains : ĠMap < Node , ĠSet < Node >>, Ġtail : ĠNode ): ĠNode ? Ġ{ ĊĠĠĠĠĠĠĠ Ġchains . forEach Ġ{ Ġ( head , Ġchain ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( chain . last () Ġ== Ġtail ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġhead ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Link ( head : ĠNode , Ġtail : ĠNode ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( tail Ġin Ġchains ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġtail Ġof Ġthe Ġnew Ġchain Ġis Ġthe Ġhead Ġof Ġanother Ġchain . ĠLet 's Ġremove Ġit Ġand Ġmake Ġthe Ġnew Ġhead Ġthe Ġhead ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġof Ġthe Ġcombined Ġchain ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexisting Chain Ġ= Ġchains [ tail ] !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchains . remove ( tail ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchains [ head ] Ġ= Ġset Of ( tail ) Ġ+ Ġexisting Chain ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġexisting Head Ġ= Ġhead With Tail ( chains , Ġhead ) ĊĠĠĠĠĠĠĠ Ġif Ġ( existing Head Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġhead Ġof Ġthe Ġnew Ġchain Ġmatches Ġthe Ġtail Ġof Ġan Ġalready Ġexisting Ġchain . ĠAdd Ġthis Ġchain Ġto Ġit . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Chain Ġ= Ġchains [ existing Head ] !! Ġ+ Ġtail ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchains [ existing Head ] Ġ= Ġnew Chain ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠThis Ġis Ġa Ġcompletely Ġnew Ġchain , Ġlet 's Ġjust Ġadd Ġit . ĊĠĠĠĠĠĠĠ Ġchains [ head ] Ġ= Ġset Of ( tail ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġbuild (): ĠSet < Chain > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġchains . map Ġ{ Ġ( head , Ġelements ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstyle Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠChain . Direction . HORIZONTAL Ġ-> Ġhead . view . constraints . chain . horizontal Style ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠChain . Direction . VERTICAL Ġ-> Ġhead . view . constraints . chain . vertical Style ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠChain ( direction , Ġhead , Ġelements , Ġstyle ) ĊĠĠĠĠĠĠĠ Ġ}. toSet () ĊĠĠĠ Ġ} Ċ } Ċ