#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# DESCRIPTION: 2013 welcome script
#
# Run the script with
#   klayout -r path_to_script/2013.rb ...
# (it is important to specify a path, i.e. ".")
# or drag and drop the script to the KLayout window.

include RBA

if ! RBA.const_defined?("QDialog")
  raise "KLayout must be compiled with --with-qtbinding"
end

if Application::instance.version.split(/\./)[1].to_i < 22 
  raise "At least KLayout 0.22.x required"
end

# The script
# A brief descrption: 
# The arena has the size of 1000x1000 micron.
# "launch" launches a rocket. Parameters of "launch" are
#   :a => The angle in degree
#   :v => The initial velocity in micron/sec 
#   :t => The burn time until the rocket explodes in seconds
#   :p => The "power": this is the initial velocity of the sparks in micron/sec
#   :c => The colors used by the sparks after the rocket exploded
#         (this is an array of layer indices). Four adjacent layers
#         will be used for the intensity of the sparks
#   :sparks => The number of sparks into which the rocket will dissolve
#   :st => The spark's burn time
#   :stay => If set to 1, the traces the sparks leave will not disappear
# "put_polygons" will put the polygons (given as arrays of Point objects)
# to the specified layer.
# "stop" will stop the show

Script = <<END

  # Intro
  at(0.5)  { launch(:a => -15, :v => 500, :t => 2.4, :p => 120, :c => White) }
  at(0.9)  { launch(:a => 15,  :v => 500, :t => 2.4, :p => 120, :c => Red) }
  at(2.0)  { launch(:a => 10,  :v => 700, :t => 1.4, :p => 200, :c => [ Red, Yellow ]) }
  at(3.9)  { launch(:a => 5,   :v => 500, :t => 3.0, :p => 300, :c => [ Red, Green, Yellow, Magenta ]) }
  at(4.0)  { launch(:a => 10,  :v => 600, :t => 2.8, :p => 130, :c => [ Red, Green, Yellow ]) }
  at(4.1)  { launch(:a => -5,  :v => 600, :t => 2.6, :p => 150, :c => [ Red, Green, Yellow ]) }
  at(4.2)  { launch(:a => 5,   :v => 650, :t => 2.4, :p => 140, :c => [ Red, Green, Yellow ]) }
  at(7.4)  { launch(:a => 12,  :v => 500, :t => 2.8, :p => 130, :c => [ Yellow, Magenta ]) }
  at(7.6)  { launch(:a => -7,  :v => 550, :t => 2.6, :p => 160, :c => Red) }
  at(7.7)  { launch(:a => -3,  :v => 550, :t => 2.6, :p => 150, :c => Yellow )
             launch(:a => -4,  :v => 560, :t => 2.4, :p => 130, :c => [ Red, Yellow ]) }
  at(7.8)  { launch(:a => 9,   :v => 540, :t => 2.4, :p => 140, :c => Green) 
             launch(:a => 5,   :v => 550, :t => 2.6, :p => 150, :c => [ Red, Magenta ]) }
  at(12.5) { launch(:a => 5,   :v => 700, :t => 1.2, :p => 600, :c => White) }
  at(12.6) { launch(:a => 6,   :v => 750, :t => 1.1, :p => 300, :c => Red) }

  # Big Bang
  at(12.7) { launch(:a => 3,   :v => 780, :t => 1.0, :p => 300, :c => [ Red, Yellow ]) 
             launch(:a => 7,   :v => 770, :t => 1.1, :p => 350, :c => [ Green, Magenta ]) 
             launch(:a => 1,   :v => 760, :t => 1.2, :p => 300, :c => Green) }

  # Finale furioso
  t = 16

  at(t) { put_polygons(MaskLayer, BannerPolygons) }

  at(t + 0.1) { launch(:a => -20, :v => 500, :t => 1.25, :p => 120, :c => AllColors,                    :st => 0.2, :sparks => 20) 
                launch(:a => -18, :v => 500, :t => 2.1,  :p => 120, :c => [ RedMasked, MagentaMasked ], :st => 0.5, :sparks => 50) }
  at(t + 1.2) { launch(:a =>  7,  :v => 500, :t => 1.7,  :p => 120, :c => AllColorsMasked,              :st => 0.5, :sparks => 50) 
                launch(:a =>  16, :v => 550, :t => 1.5,  :p => 120, :c => AllColors,                    :st => 0.5, :sparks => 50) }
  at(t + 1.7) { launch(:a =>  0,  :v => 550, :t => 0.9,  :p => 120, :c => WhiteMasked,                  :st => 0.5, :sparks => 50) 
                launch(:a =>  0,  :v => 550, :t => 1.25, :p => 120, :c => AllColorsMasked,              :st => 0.5, :sparks => 50) }
  at(t + 2.2) { launch(:a => -5,  :v => 500, :t => 1.7,  :p => 120, :c => RedMasked,                    :st => 0.5, :sparks => 50) }
  at(t + 2.8) { launch(:a => -12, :v => 500, :t => 1.9,  :p => 120, :c => AllColorsMasked,              :st => 0.5, :sparks => 50) }
  at(t + 3.5) { launch(:a =>  7,  :v => 500, :t => 1.7,  :p => 120, :c => AllColors,                    :st => 0.5, :sparks => 50) 
                launch(:a =>  16, :v => 550, :t => 1.5,  :p => 120, :c => AllColorsMasked,              :st => 0.5, :sparks => 50) }
  at(t + 4.0) { launch(:a =>  7,  :v => 500, :t => 1.7,  :p => 120, :c => AllColorsMasked,              :st => 0.5, :sparks => 50) 
                launch(:a =>  16, :v => 550, :t => 1.5,  :p => 120, :c => AllColors,                    :st => 0.5, :sparks => 50) }
  at(t + 5.0) { launch(:a =>  0,  :v => 550, :t => 0.9,  :p => 120, :c => AllColorsMasked,              :st => 0.5, :sparks => 50) 
                launch(:a =>  0,  :v => 550, :t => 1.25, :p => 120, :c => AllColors,                    :st => 0.5, :sparks => 50) }

  # Banner message
  at(t + 6.9) { launch(:a => -17, :v => 500, :t => 2.2,  :p => 100, :c => AllColorsMasked,              :st => 0.5, :sparks => 40, :stay => 1) }
  at(t + 7.3) { launch(:a =>  7,  :v => 500, :t => 1.8,  :p => 100, :c => AllColorsMasked,              :st => 0.5, :sparks => 40, :stay => 1) }
  at(t + 7.5) { launch(:a =>  16, :v => 550, :t => 1.6,  :p => 100, :c => AllColorsMasked,              :st => 0.5, :sparks => 40, :stay => 1) }
  at(t + 7.7) { launch(:a =>  0,  :v => 550, :t => 1.35, :p => 100, :c => AllColorsMasked,              :st => 0.5, :sparks => 40, :stay => 1) }
  at(t + 7.4) { launch(:a => -5,  :v => 500, :t => 1.8,  :p => 100, :c => AllColorsMasked,              :st => 0.5, :sparks => 40, :stay => 1) }
  at(t + 7.1) { launch(:a => -12, :v => 500, :t => 2.0,  :p => 100, :c => AllColorsMasked,              :st => 0.5, :sparks => 40, :stay => 1) }
  at(t + 7.3) { launch(:a =>  18, :v => 550, :t => 1.7,  :p => 100, :c => AllColorsMasked,              :st => 0.5, :sparks => 40, :stay => 1) }

  # Show Message
  at(t + 11) { put_polygons(MessageLayer, MessagePolygons) }

  # Done
  at(30) { stop }

END

# The banner ("KLayout")
BannerPolygons = [
  [ Point::new(103500,503398), Point::new(96510,503788), Point::new(90090,504913), Point::new(84240,506788), Point::new(78975,509353), Point::new(74280,512533), Point::new(70185,516298), Point::new(66735,520648), 
    Point::new(63900,525523), Point::new(61665,530938), Point::new(60060,536863), Point::new(59100,543178), Point::new(58770,549868), Point::new(59085,556363), Point::new(59985,562513), Point::new(61500,568303), 
    Point::new(63690,573733), Point::new(66495,578638), Point::new(69945,583033), Point::new(74010,586858), Point::new(78720,590083), Point::new(84075,592708), Point::new(90075,594628), Point::new(96720,595783), 
    Point::new(104010,596173), Point::new(111660,595783), Point::new(118515,594628), Point::new(124590,592708), Point::new(129915,590083), Point::new(134550,586858), Point::new(138480,583033), Point::new(140625,580213), 
    Point::new(104340,580213), Point::new(98025,579403), Point::new(92790,576988), Point::new(88620,572938), Point::new(85590,567148), Point::new(83775,559453), Point::new(83175,549868), Point::new(83325,544768), 
    Point::new(83790,540163), Point::new(84570,536068), Point::new(85695,532438), Point::new(87075,529258), Point::new(88710,526558), Point::new(90585,524293), Point::new(92715,522433), Point::new(95070,521008), 
    Point::new(97635,520048), Point::new(100365,519478), Point::new(103260,519283), Point::new(106545,519478), Point::new(109575,520048), Point::new(112350,521008), Point::new(114915,522433), Point::new(117165,524293), 
    Point::new(119130,526558), Point::new(120810,529258), Point::new(122190,532438), Point::new(123270,536068), Point::new(124050,540163), Point::new(124515,544768), Point::new(124680,549868), Point::new(124095,559543), 
    Point::new(122355,567253), Point::new(119460,573028), Point::new(115470,577018), Point::new(110430,579418), Point::new(104340,580213), Point::new(140625,580213), Point::new(141795,578683), Point::new(144435,573808), 
    Point::new(146415,568393), Point::new(147840,562588), Point::new(148695,556408), Point::new(148980,549868), Point::new(148665,543223), Point::new(147690,536968), Point::new(146085,531103), Point::new(143895,525688), 
    Point::new(141060,520783), Point::new(137580,516388), Point::new(133455,512593), Point::new(128715,509398), Point::new(123345,506788), Point::new(117360,504913), Point::new(110745,503788) ],
  [ Point::new(293925,503563), Point::new(287610,504178), Point::new(282345,506038), Point::new(278130,509113), Point::new(275055,513493), Point::new(273210,519148), Point::new(272595,526063), Point::new(272595,578803), 
    Point::new(261270,578803), Point::new(261270,594523), Point::new(273750,594523), Point::new(281025,615523), Point::new(295575,615523), Point::new(295575,594523), Point::new(312525,594523), Point::new(312525,578803), 
    Point::new(295575,578803), Point::new(295575,532348), Point::new(295860,528358), Point::new(296685,525133), Point::new(298065,522673), Point::new(300015,520963), Point::new(302580,519943), Point::new(305745,519613), 
    Point::new(307140,519643), Point::new(308430,519763), Point::new(309630,519943), Point::new(310845,520183), Point::new(312135,520453), Point::new(313515,520768), Point::new(313515,506383), Point::new(310605,505528), 
    Point::new(307560,504838), Point::new(304425,504313), Point::new(301125,503893), Point::new(297630,503653) ],
  [ Point::new(195615,503398), Point::new(190530,503698), Point::new(185985,504583), Point::new(181980,506053), Point::new(178455,508018), Point::new(175395,510418), Point::new(172800,513238), Point::new(170685,516508), 
    Point::new(169005,520153), Point::new(167745,524158), Point::new(166875,528463), Point::new(166350,532978), Point::new(166185,537718), Point::new(166185,594523), Point::new(189420,594523), Point::new(189420,544333), 
    Point::new(189510,540958), Point::new(189780,537748), Point::new(190245,534748), Point::new(190905,532003), Point::new(191820,529528), Point::new(192975,527293), Point::new(194355,525403), Point::new(195990,523813), 
    Point::new(197850,522508), Point::new(200040,521533), Point::new(202515,520963), Point::new(205290,520768), Point::new(208005,520963), Point::new(210540,521578), Point::new(212895,522583), Point::new(215100,524023), 
    Point::new(217080,525778), Point::new(218850,527878), Point::new(220380,530338), Point::new(221640,533053), Point::new(222660,536068), Point::new(223440,539368), Point::new(223905,542863), Point::new(224055,546568), 
    Point::new(224055,594523), Point::new(247290,594523), Point::new(247290,519118), Point::new(247350,517108), Point::new(247395,515143), Point::new(247455,513238), Point::new(247560,511483), Point::new(247635,509833), 
    Point::new(247710,508288), Point::new(247800,506968), Point::new(247890,505888), Point::new(247950,505063), Point::new(225795,505063), Point::new(225720,505843), Point::new(225615,506893), Point::new(225465,508198), 
    Point::new(225360,509728), Point::new(225240,511363), Point::new(225135,513073), Point::new(225075,514843), Point::new(224985,516613), Point::new(224880,518368), Point::new(224835,520048), Point::new(224805,521533), 
    Point::new(224805,522838), Point::new(224385,522838), Point::new(221025,516673), Point::new(217080,511738), Point::new(212565,508033), Point::new(207525,505468), Point::new(201870,503923) ],
  [ Point::new(-103860,503398), Point::new(-108015,503593), Point::new(-111870,504178), Point::new(-115440,505138), Point::new(-118635,506533), Point::new(-121500,508258), Point::new(-124035,510343), 
    Point::new(-126225,512833), Point::new(-128040,515683), Point::new(-129495,518863), Point::new(-130545,522388), Point::new(-131175,526213), Point::new(-131400,530353), Point::new(-131085,535363), Point::new(-130185,539803), 
    Point::new(-128670,543673), Point::new(-126570,547063), Point::new(-124035,549988), Point::new(-121065,552433), Point::new(-117675,554488), Point::new(-113925,556108), Point::new(-109815,557308), Point::new(-105420,558193), 
    Point::new(-100845,558748), Point::new(-96090,558973), Point::new(-76830,559303), Point::new(-76830,563848), Point::new(-76920,566908), Point::new(-77220,569608), Point::new(-77730,571948), Point::new(-78375,574018), 
    Point::new(-79200,575803), Point::new(-80220,577318), Point::new(-81405,578563), Point::new(-82785,579523), Point::new(-84345,580213), Point::new(-86025,580723), Point::new(-87870,581023), Point::new(-89880,581128), 
    Point::new(-91755,581068), Point::new(-93495,580873), Point::new(-95100,580543), Point::new(-96525,580063), Point::new(-97815,579373), Point::new(-98985,578473), Point::new(-100020,577423), Point::new(-100935,576133), 
    Point::new(-101715,574588), Point::new(-102300,572848), Point::new(-102780,570808), Point::new(-103110,568468), Point::new(-127335,569638), Point::new(-126495,573433), Point::new(-125280,576988), Point::new(-123705,580303), 
    Point::new(-121725,583408), Point::new(-119295,586213), Point::new(-116430,588733), Point::new(-113055,590923), Point::new(-109230,592738), Point::new(-104940,594193), Point::new(-100095,595288), Point::new(-94755,595948), 
    Point::new(-88890,596173), Point::new(-83535,595948), Point::new(-78570,595258), Point::new(-74010,594103), Point::new(-69870,592498), Point::new(-66180,590428), Point::new(-62925,587908), Point::new(-60135,584998), 
    Point::new(-57825,581653), Point::new(-55980,577903), Point::new(-54660,573718), Point::new(-53850,569113), Point::new(-53595,564088), Point::new(-53595,546478), Point::new(-76830,546478), Point::new(-88725,546313), 
    Point::new(-91170,546163), Point::new(-93540,545953), Point::new(-95835,545653), Point::new(-97965,545263), Point::new(-99915,544633), Point::new(-101715,543748), Point::new(-103260,542668), Point::new(-104580,541288), 
    Point::new(-105675,539623), Point::new(-106500,537583), Point::new(-106995,535093), Point::new(-107160,532183), Point::new(-106845,528298), Point::new(-105885,525118), Point::new(-104280,522673), Point::new(-102075,520963), 
    Point::new(-99465,519943), Point::new(-96420,519613), Point::new(-93540,519823), Point::new(-90840,520453), Point::new(-88320,521518), Point::new(-86025,522913), Point::new(-83985,524563), Point::new(-82200,526468), 
    Point::new(-80610,528673), Point::new(-79290,531073), Point::new(-78225,533668), Point::new(-77445,536383), Point::new(-76980,539143), Point::new(-76830,541933), Point::new(-76830,546478), Point::new(-53595,546478), 
    Point::new(-53595,531523), Point::new(-53565,529498), Point::new(-53475,527623), Point::new(-53340,525898), Point::new(-53070,524323), Point::new(-52710,522913), Point::new(-52260,521683), Point::new(-51645,520663), 
    Point::new(-50910,519808), Point::new(-50040,519118), Point::new(-48945,518653), Point::new(-47685,518383), Point::new(-46230,518293), Point::new(-44490,518338), Point::new(-42780,518503), Point::new(-41100,518788), 
    Point::new(-41100,506218), Point::new(-42435,505888), Point::new(-43680,505588), Point::new(-44820,505303), Point::new(-45930,505048), Point::new(-47025,504823), Point::new(-48135,504643), Point::new(-49260,504493), 
    Point::new(-50445,504343), Point::new(-51690,504238), Point::new(-52980,504133), Point::new(-54405,504088), Point::new(-55980,504073), Point::new(-61320,504538), Point::new(-65655,505978), Point::new(-68970,508363), 
    Point::new(-71355,511678), Point::new(-73005,515893), Point::new(-73935,521008), Point::new(-74430,521008), Point::new(-77805,515863), Point::new(-81780,511528), Point::new(-86325,508033), Point::new(-91470,505468), 
    Point::new(-97320,503923) ],
  [ Point::new(-228540,505063), Point::new(-228540,621553), Point::new(-204150,621553), Point::new(-204150,523903), Point::new(-141645,523903), Point::new(-141645,505063) ],
  [ Point::new(-350910,505063), Point::new(-350910,621553), Point::new(-326520,621553), Point::new(-326520,568723), Point::new(-274020,621553), Point::new(-245580,621553), Point::new(-295350,572278), 
    Point::new(-241530,505063), Point::new(-270300,505063), Point::new(-312135,558553), Point::new(-326520,547558), Point::new(-326520,505063) ],
  [ Point::new(-18690,469918), Point::new(-24030,470038), Point::new(-28920,470398), Point::new(-33330,470998), Point::new(-33330,487528), Point::new(-30510,487168), Point::new(-27900,486943), Point::new(-25470,486868), 
    Point::new(-23205,486943), Point::new(-21135,487198), Point::new(-19275,487618), Point::new(-17565,488218), Point::new(-15975,489043), Point::new(-14475,490093), Point::new(-11760,492958), Point::new(-9225,496933), 
    Point::new(-6870,502003), Point::new(-5385,505963), Point::new(-40770,594523), Point::new(-16215,594523), Point::new(6195,524983), Point::new(26865,594523), Point::new(51165,594523), Point::new(15780,500338), Point::new(11265,490543), 
    Point::new(6630,482848), Point::new(1890,477283), Point::new(-3885,473188), Point::new(-10755,470728) ],
]

# The message below the banner
MessagePolygons = [
  [ Point::new(405195,395188), Point::new(401775,395338), Point::new(398730,395773), Point::new(396060,396508), Point::new(393750,397513), Point::new(391725,398698), Point::new(389985,400063), Point::new(388530,401623), 
    Point::new(387330,403303), Point::new(386385,405103), Point::new(385680,407023), Point::new(385155,408988), Point::new(384825,410983), Point::new(392505,411673), Point::new(392790,410188), Point::new(393195,408778), 
    Point::new(393705,407458), Point::new(394380,406258), Point::new(395205,405163), Point::new(396150,404203), Point::new(397245,403363), Point::new(398505,402658), Point::new(399915,402088), Point::new(401490,401668), 
    Point::new(403260,401428), Point::new(405195,401338), Point::new(408675,401653), Point::new(411615,402583), Point::new(414015,404113), Point::new(415800,406258), Point::new(416880,409003), Point::new(417225,412348), 
    Point::new(417075,414343), Point::new(416595,416068), Point::new(415785,417508), Point::new(414765,418738), Point::new(413580,419758), Point::new(412230,420568), Point::new(410775,421228), Point::new(409230,421723), 
    Point::new(407595,422053), Point::new(405990,422263), Point::new(404460,422383), Point::new(403005,422428), Point::new(398790,422428), Point::new(398790,428878), Point::new(402840,428878), Point::new(404265,428923), 
    Point::new(405735,429058), Point::new(407235,429298), Point::new(408705,429673), Point::new(410070,430198), Point::new(411360,430858), Point::new(412545,431728), Point::new(413580,432748), Point::new(414465,433963), 
    Point::new(415155,435373), Point::new(415560,437038), Point::new(415710,438928), Point::new(415395,441823), Point::new(414465,444268), Point::new(412935,446278), Point::new(410820,447793), Point::new(408105,448708), 
    Point::new(404790,449008), Point::new(401715,448738), Point::new(399060,447883), Point::new(396810,446488), Point::new(395085,444583), Point::new(393900,442213), Point::new(393300,439378), Point::new(385815,439963), 
    Point::new(386250,442408), Point::new(386955,444643), Point::new(387915,446653), Point::new(389115,448453), Point::new(390510,450013), Point::new(392100,451363), Point::new(393885,452518), Point::new(395820,453463), 
    Point::new(397920,454183), Point::new(400155,454708), Point::new(402465,455023), Point::new(404865,455128), Point::new(407970,454993), Point::new(410775,454573), Point::new(413265,453883), Point::new(415470,452983), 
    Point::new(417375,451888), Point::new(419010,450583), Point::new(420360,449128), Point::new(421455,447493), Point::new(422280,445708), Point::new(422880,443788), Point::new(423225,441793), Point::new(423345,439708), 
    Point::new(423270,438043), Point::new(423045,436438), Point::new(422655,434908), Point::new(422085,433483), Point::new(421365,432133), Point::new(420450,430903), Point::new(419370,429778), Point::new(418110,428758), 
    Point::new(416655,427843), Point::new(415035,427063), Point::new(413205,426418), Point::new(411150,425908), Point::new(411150,425743), Point::new(413400,425398), Point::new(415440,424858), Point::new(417270,424123), 
    Point::new(418905,423253), Point::new(420345,422248), Point::new(421575,421108), Point::new(422610,419833), Point::new(423450,418453), Point::new(424095,416968), Point::new(424575,415408), Point::new(424860,413773), 
    Point::new(424965,412093), Point::new(424815,409513), Point::new(424380,407128), Point::new(423645,404938), Point::new(422655,402958), Point::new(421380,401173), Point::new(419835,399613), Point::new(418050,398278), 
    Point::new(415980,397183), Point::new(413640,396298), Point::new(411060,395683), Point::new(408255,395308) ],
  [ Point::new(-310365,395188), Point::new(-316470,395848), Point::new(-321510,397813), Point::new(-325500,401098), Point::new(-328380,405673), Point::new(-330090,411538), Point::new(-330675,418663), 
    Point::new(-330495,422638), Point::new(-329970,426178), Point::new(-329100,429298), Point::new(-327930,432028), Point::new(-326490,434398), Point::new(-324795,436408), Point::new(-322875,438058), Point::new(-320760,439363), 
    Point::new(-318435,440323), Point::new(-315960,441013), Point::new(-313365,441433), Point::new(-310665,441568), Point::new(-307125,441373), Point::new(-303990,440758), Point::new(-301275,439753), Point::new(-298905,438388), 
    Point::new(-296880,436708), Point::new(-296355,436078), Point::new(-310785,436078), Point::new(-312045,436003), Point::new(-313350,435793), Point::new(-314715,435448), Point::new(-316035,434953), Point::new(-317280,434263), 
    Point::new(-318480,433348), Point::new(-319575,432193), Point::new(-320550,430813), Point::new(-321405,429163), Point::new(-322095,427273), Point::new(-322545,425053), Point::new(-322770,422518), Point::new(-298635,422518), 
    Point::new(-299310,426793), Point::new(-300510,430228), Point::new(-302235,432808), Point::new(-304500,434623), Point::new(-307350,435703), Point::new(-310785,436078), Point::new(-296355,436078), Point::new(-295200,434713), 
    Point::new(-293805,432463), Point::new(-292725,429943), Point::new(-291930,427183), Point::new(-291375,424213), Point::new(-291045,421078), Point::new(-290940,417793), Point::new(-290940,416803), Point::new(-322860,416803), 
    Point::new(-322785,414523), Point::new(-322545,412363), Point::new(-322155,410323), Point::new(-321570,408448), Point::new(-320835,406753), Point::new(-319920,405238), Point::new(-318810,403933), Point::new(-317520,402823), 
    Point::new(-316035,401923), Point::new(-314355,401278), Point::new(-312465,400888), Point::new(-310365,400768), Point::new(-307365,400978), Point::new(-304785,401623), Point::new(-302640,402703), Point::new(-300900,404113), 
    Point::new(-299565,405763), Point::new(-298665,407623), Point::new(-292140,405763), Point::new(-292680,404518), Point::new(-293340,403273), Point::new(-294120,402013), Point::new(-295050,400798), Point::new(-296160,399673), 
    Point::new(-297480,398623), Point::new(-298995,397678), Point::new(-300765,396853), Point::new(-302760,396133), Point::new(-305010,395608), Point::new(-307545,395293) ],
  [ Point::new(14565,395188), Point::new(8475,395848), Point::new(3435,397813), Point::new(-555,401098), Point::new(-3435,405673), Point::new(-5160,411538), Point::new(-5730,418663), Point::new(-5550,422638), 
    Point::new(-5025,426178), Point::new(-4155,429298), Point::new(-2985,432028), Point::new(-1545,434398), Point::new(135,436408), Point::new(2055,438058), Point::new(4185,439363), Point::new(6510,440323), Point::new(8985,441013), 
    Point::new(11580,441433), Point::new(14280,441568), Point::new(17820,441373), Point::new(20955,440758), Point::new(23670,439753), Point::new(26025,438388), Point::new(28050,436708), Point::new(28590,436078), 
    Point::new(14160,436078), Point::new(12900,436003), Point::new(11580,435793), Point::new(10230,435448), Point::new(8910,434953), Point::new(7650,434263), Point::new(6465,433348), Point::new(5370,432193), 
    Point::new(4395,430813), Point::new(3525,429163), Point::new(2850,427273), Point::new(2385,425053), Point::new(2160,422518), Point::new(26310,422518), Point::new(25635,426793), Point::new(24435,430228), 
    Point::new(22710,432808), Point::new(20445,434623), Point::new(17595,435703), Point::new(14160,436078), Point::new(28590,436078), Point::new(29745,434713), Point::new(31140,432463), Point::new(32220,429943), 
    Point::new(33015,427183), Point::new(33555,424213), Point::new(33885,421078), Point::new(34005,417793), Point::new(34005,416803), Point::new(2085,416803), Point::new(2160,414523), Point::new(2400,412363), 
    Point::new(2790,410323), Point::new(3360,408448), Point::new(4110,406753), Point::new(5025,405238), Point::new(6135,403933), Point::new(7425,402823), Point::new(8910,401923), Point::new(10590,401278), 
    Point::new(12465,400888), Point::new(14565,400768), Point::new(17580,400978), Point::new(20160,401623), Point::new(22305,402703), Point::new(24045,404113), Point::new(25365,405763), Point::new(26265,407623), 
    Point::new(32805,405763), Point::new(32265,404518), Point::new(31605,403273), Point::new(30810,402013), Point::new(29895,400798), Point::new(28770,399673), Point::new(27465,398623), Point::new(25950,397678), 
    Point::new(24180,396853), Point::new(22170,396133), Point::new(19935,395608), Point::new(17400,395293) ],
  [ Point::new(310785,395188), Point::new(308010,395353), Point::new(305355,395863), Point::new(302835,396718), Point::new(300495,397948), Point::new(298365,399643), Point::new(296430,401758), 
    Point::new(294765,404338), Point::new(293340,407413), Point::new(292170,410983), Point::new(291330,415108), Point::new(290820,419833), Point::new(290640,425158), Point::new(290820,430693), Point::new(291330,435538), 
    Point::new(292170,439708), Point::new(293355,443308), Point::new(294780,446383), Point::new(296475,448933), Point::new(298410,450988), Point::new(300555,452578), Point::new(302925,453718), Point::new(305475,454498), 
    Point::new(308175,454978), Point::new(311025,455128), Point::new(313755,454978), Point::new(316350,454498), Point::new(318840,453718), Point::new(321195,452578), Point::new(323325,450988), Point::new(325095,449098), 
    Point::new(311025,449098), Point::new(309015,448963), Point::new(307170,448573), Point::new(305490,447943), Point::new(303975,446983), Point::new(302625,445678), Point::new(301440,444013), Point::new(300450,441973), 
    Point::new(299640,439528), Point::new(298995,436648), Point::new(298530,433333), Point::new(298260,429508), Point::new(298170,425158), Point::new(298260,420928), Point::new(298530,417163), Point::new(298995,413878), 
    Point::new(299655,411013), Point::new(300480,408538), Point::new(301470,406468), Point::new(302655,404788), Point::new(303990,403453), Point::new(305490,402463), Point::new(307125,401788), Point::new(308925,401398), 
    Point::new(310860,401263), Point::new(312750,401398), Point::new(314520,401788), Point::new(316155,402463), Point::new(317640,403453), Point::new(318960,404788), Point::new(320115,406468), Point::new(321135,408538), 
    Point::new(321975,411013), Point::new(322650,413878), Point::new(323145,417163), Point::new(323445,420928), Point::new(323550,425158), Point::new(323460,429523), Point::new(323190,433363), Point::new(322725,436693), 
    Point::new(322095,439573), Point::new(321270,442018), Point::new(320280,444043), Point::new(319125,445708), Point::new(317805,447013), Point::new(316320,447943), Point::new(314700,448573), Point::new(312945,448963), 
    Point::new(311025,449098), Point::new(325095,449098), Point::new(325245,448933), Point::new(326940,446383), Point::new(328365,443308), Point::new(329550,439708), Point::new(330420,435538), Point::new(330945,430693), 
    Point::new(331125,425158), Point::new(330945,419863), Point::new(330405,415138), Point::new(329505,411013), Point::new(328320,407458), Point::new(326880,404368), Point::new(325170,401758), Point::new(323235,399643), 
    Point::new(321090,397948), Point::new(318720,396718), Point::new(316185,395863), Point::new(313530,395353) ],
  [ Point::new(192960,395188), Point::new(189960,395338), Point::new(187170,395803), Point::new(184605,396583), Point::new(182280,397693), Point::new(180195,399133), Point::new(178365,400888), 
    Point::new(176805,402973), Point::new(175515,405388), Point::new(174480,408118), Point::new(173745,411223), Point::new(173295,414643), Point::new(173160,418423), Point::new(175380,431278), Point::new(182070,439003), 
    Point::new(193200,441568), Point::new(196515,441403), Point::new(199500,440923), Point::new(202170,440128), Point::new(204555,439003), Point::new(206625,437548), Point::new(208080,436078), Point::new(193335,436078), 
    Point::new(191490,435973), Point::new(189765,435688), Point::new(188160,435208), Point::new(186720,434518), Point::new(185430,433543), Point::new(184275,432313), Point::new(183285,430813), Point::new(182460,428998), 
    Point::new(181800,426898), Point::new(181335,424438), Point::new(181065,421618), Point::new(180975,418423), Point::new(181065,415138), Point::new(181365,412258), Point::new(181875,409783), Point::new(182550,407668), 
    Point::new(183390,405868), Point::new(184365,404368), Point::new(185490,403138), Point::new(186750,402193), Point::new(188115,401503), Point::new(189615,401053), Point::new(191205,400768), Point::new(192870,400678), 
    Point::new(194715,400768), Point::new(196440,401038), Point::new(198045,401473), Point::new(199500,402148), Point::new(200820,403108), Point::new(201975,404323), Point::new(202965,405823), Point::new(203790,407653), 
    Point::new(204450,409783), Point::new(204930,412258), Point::new(205215,415138), Point::new(205320,418423), Point::new(205230,421693), Point::new(204945,424558), Point::new(204495,427018), Point::new(203880,429133), 
    Point::new(203100,430933), Point::new(202140,432433), Point::new(201030,433648), Point::new(199785,434578), Point::new(198375,435238), Point::new(196815,435703), Point::new(195135,435973), Point::new(193335,436078), 
    Point::new(208080,436078), Point::new(208380,435778), Point::new(209865,433693), Point::new(211065,431278), Point::new(211980,428548), Point::new(212610,425488), Point::new(213000,422113), Point::new(213135,418423), 
    Point::new(212550,411253), Point::new(210840,405433), Point::new(207960,400933), Point::new(204000,397738), Point::new(198990,395818) ],
  [ Point::new(-405165,395188), Point::new(-408165,395338), Point::new(-410955,395803), Point::new(-413520,396583), Point::new(-415845,397693), Point::new(-417930,399133), Point::new(-419760,400888), 
    Point::new(-421320,402973), Point::new(-422610,405388), Point::new(-423645,408118), Point::new(-424380,411223), Point::new(-424815,414643), Point::new(-424965,418423), Point::new(-422745,431278), Point::new(-416055,439003), 
    Point::new(-404925,441568), Point::new(-401610,441403), Point::new(-398610,440923), Point::new(-395955,440128), Point::new(-393570,439003), Point::new(-391500,437548), Point::new(-390045,436078), Point::new(-404790,436078), 
    Point::new(-406635,435973), Point::new(-408360,435688), Point::new(-409965,435208), Point::new(-411405,434518), Point::new(-412695,433543), Point::new(-413850,432313), Point::new(-414840,430813), Point::new(-415665,428998), 
    Point::new(-416325,426898), Point::new(-416790,424438), Point::new(-417060,421618), Point::new(-417150,418423), Point::new(-417060,415138), Point::new(-416745,412258), Point::new(-416250,409783), Point::new(-415560,407668), 
    Point::new(-414735,405868), Point::new(-413760,404368), Point::new(-412635,403138), Point::new(-411375,402193), Point::new(-410010,401503), Point::new(-408495,401053), Point::new(-406920,400768), Point::new(-405255,400678), 
    Point::new(-403410,400768), Point::new(-401685,401038), Point::new(-400080,401473), Point::new(-398610,402148), Point::new(-397305,403108), Point::new(-396150,404323), Point::new(-395160,405823), Point::new(-394335,407653), 
    Point::new(-393675,409783), Point::new(-393195,412258), Point::new(-392895,415138), Point::new(-392805,418423), Point::new(-392895,421693), Point::new(-393180,424558), Point::new(-393630,427018), Point::new(-394245,429133), 
    Point::new(-395025,430933), Point::new(-395985,432433), Point::new(-397080,433648), Point::new(-398340,434578), Point::new(-399750,435238), Point::new(-401310,435703), Point::new(-402990,435973), Point::new(-404790,436078), 
    Point::new(-390045,436078), Point::new(-389745,435778), Point::new(-388260,433693), Point::new(-387060,431278), Point::new(-386145,428548), Point::new(-385500,425488), Point::new(-385125,422113), Point::new(-384990,418423), 
    Point::new(-385560,411253), Point::new(-387285,405433), Point::new(-390165,400933), Point::new(-394125,397738), Point::new(-399120,395818) ],
  [ Point::new(-150840,395188), Point::new(-153840,395338), Point::new(-156630,395803), Point::new(-159180,396583), Point::new(-161520,397693), Point::new(-163590,399133), Point::new(-165435,400888), 
    Point::new(-166980,402973), Point::new(-168285,405388), Point::new(-169320,408118), Point::new(-170055,411223), Point::new(-170490,414643), Point::new(-170640,418423), Point::new(-168405,431278), Point::new(-161730,439003), 
    Point::new(-150585,441568), Point::new(-147270,441403), Point::new(-144285,440923), Point::new(-141615,440128), Point::new(-139245,439003), Point::new(-137175,437548), Point::new(-135720,436078), Point::new(-150465,436078), 
    Point::new(-152310,435973), Point::new(-154035,435688), Point::new(-155625,435208), Point::new(-157080,434518), Point::new(-158370,433543), Point::new(-159525,432313), Point::new(-160515,430813), Point::new(-161340,428998), 
    Point::new(-162000,426898), Point::new(-162465,424438), Point::new(-162735,421618), Point::new(-162825,418423), Point::new(-162720,415138), Point::new(-162420,412258), Point::new(-161910,409783), Point::new(-161235,407668), 
    Point::new(-160410,405868), Point::new(-159435,404368), Point::new(-158295,403138), Point::new(-157050,402193), Point::new(-155670,401503), Point::new(-154170,401053), Point::new(-152580,400768), Point::new(-150915,400678), 
    Point::new(-149070,400768), Point::new(-147360,401038), Point::new(-145755,401473), Point::new(-144285,402148), Point::new(-142980,403108), Point::new(-141825,404323), Point::new(-140835,405823), Point::new(-140010,407653), 
    Point::new(-139350,409783), Point::new(-138855,412258), Point::new(-138570,415138), Point::new(-138480,418423), Point::new(-138570,421693), Point::new(-138840,424558), Point::new(-139305,427018), Point::new(-139920,429133), 
    Point::new(-140700,430933), Point::new(-141660,432433), Point::new(-142755,433648), Point::new(-144015,434578), Point::new(-145425,435238), Point::new(-146970,435703), Point::new(-148650,435973), Point::new(-150465,436078), 
    Point::new(-135720,436078), Point::new(-135420,435778), Point::new(-133935,433693), Point::new(-132735,431278), Point::new(-131820,428548), Point::new(-131175,425488), Point::new(-130785,422113), Point::new(-130665,418423), 
    Point::new(-131235,411253), Point::new(-132960,405433), Point::new(-135825,400933), Point::new(-139800,397738), Point::new(-144795,395818) ],
  [ Point::new(-28800,395188), Point::new(-32130,395383), Point::new(-35100,395968), Point::new(-37725,396958), Point::new(-40035,398293), Point::new(-42030,399928), Point::new(-43725,401848), Point::new(-45105,404053), 
    Point::new(-46200,406513), Point::new(-47025,409198), Point::new(-47610,412123), Point::new(-47940,415183), Point::new(-48060,418423), Point::new(-47985,421303), Point::new(-47730,423943), Point::new(-47325,426358), 
    Point::new(-46755,428563), Point::new(-46065,430588), Point::new(-45255,432388), Point::new(-44295,434038), Point::new(-43230,435478), Point::new(-42075,436738), Point::new(-40830,437833), Point::new(-39510,438778), 
    Point::new(-38145,439543), Point::new(-36690,440188), Point::new(-35175,440698), Point::new(-33630,441073), Point::new(-32055,441343), Point::new(-30480,441508), Point::new(-28875,441568), Point::new(-26460,441448), 
    Point::new(-24225,441103), Point::new(-22185,440533), Point::new(-20325,439753), Point::new(-18630,438808), Point::new(-17145,437683), Point::new(-15795,436423), Point::new(-14640,435013), Point::new(-13665,433468), 
    Point::new(-12870,431803), Point::new(-12255,430048), Point::new(-11805,428218), Point::new(-19455,427633), Point::new(-20040,429943), Point::new(-21015,431923), Point::new(-22395,433543), Point::new(-24180,434773), 
    Point::new(-26415,435493), Point::new(-29085,435748), Point::new(-31095,435628), Point::new(-32865,435268), Point::new(-34425,434668), Point::new(-35745,433858), Point::new(-36885,432793), Point::new(-37845,431488), 
    Point::new(-38655,429958), Point::new(-39285,428173), Point::new(-39750,426148), Point::new(-40050,423883), Point::new(-40230,421348), Point::new(-40290,418588), Point::new(-40230,416083), Point::new(-40050,413728), 
    Point::new(-39750,411508), Point::new(-39285,409468), Point::new(-38655,407608), Point::new(-37845,405928), Point::new(-36870,404503), Point::new(-35715,403303), Point::new(-34380,402343), Point::new(-32805,401623), 
    Point::new(-31020,401203), Point::new(-29010,401053), Point::new(-26505,401293), Point::new(-24300,402013), Point::new(-22395,403198), Point::new(-20835,404893), Point::new(-19725,407098), Point::new(-19080,409813), 
    Point::new(-11565,409318), Point::new(-11895,407503), Point::new(-12435,405718), Point::new(-13170,403993), Point::new(-14100,402358), Point::new(-15225,400843), Point::new(-16560,399478), Point::new(-18075,398278), 
    Point::new(-19800,397228), Point::new(-21735,396343), Point::new(-23880,395698), Point::new(-26235,395308) ],
  [ Point::new(148395,395188), Point::new(145890,395248), Point::new(143535,395458), Point::new(141360,395803), Point::new(139380,396268), Point::new(137565,396913), Point::new(135900,397708), Point::new(134415,398683), 
    Point::new(133095,399838), Point::new(131940,401173), Point::new(130980,402748), Point::new(130215,404518), Point::new(129615,406513), Point::new(136200,407788), Point::new(137055,405613), Point::new(138360,403843), 
    Point::new(140130,402508), Point::new(142365,401578), Point::new(145125,401038), Point::new(148395,400843), Point::new(149940,400888), Point::new(151410,400993), Point::new(152775,401173), Point::new(154065,401443), 
    Point::new(155220,401818), Point::new(156240,402298), Point::new(157140,402898), Point::new(157875,403618), Point::new(158475,404443), Point::new(158940,405418), Point::new(159210,406543), Point::new(159300,407788), 
    Point::new(159195,409063), Point::new(158880,410158), Point::new(158355,411103), Point::new(157635,411928), Point::new(156750,412663), Point::new(155715,413293), Point::new(154500,413848), Point::new(153120,414343), 
    Point::new(151575,414778), Point::new(149925,415228), Point::new(148155,415723), Point::new(146280,416233), Point::new(144495,416713), Point::new(142725,417238), Point::new(140955,417793), Point::new(139245,418438), 
    Point::new(137640,419188), Point::new(136155,420073), Point::new(134835,421108), Point::new(133695,422293), Point::new(132720,423628), Point::new(131985,425158), Point::new(131550,426913), Point::new(131400,428923), 
    Point::new(131880,432673), Point::new(133335,435778), Point::new(135735,438223), Point::new(139110,440008), Point::new(143340,441088), Point::new(148470,441448), Point::new(153060,441163), Point::new(156975,440293), 
    Point::new(160215,438838), Point::new(162780,436753), Point::new(164625,433978), Point::new(165750,430483), Point::new(159060,429658), Point::new(158745,430753), Point::new(158280,431728), Point::new(157695,432553), 
    Point::new(156990,433303), Point::new(156180,433933), Point::new(155295,434458), Point::new(154320,434908), Point::new(153255,435253), Point::new(152115,435493), Point::new(150930,435673), Point::new(149730,435793), 
    Point::new(148470,435823), Point::new(145410,435658), Point::new(142920,435148), Point::new(141030,434293), Point::new(139695,433093), Point::new(138900,431563), Point::new(138630,429658), Point::new(138735,428518), 
    Point::new(139020,427513), Point::new(139500,426643), Point::new(140175,425908), Point::new(141015,425248), Point::new(141990,424663), Point::new(143130,424153), Point::new(144405,423688), Point::new(145830,423253), 
    Point::new(147360,422863), Point::new(149010,422443), Point::new(150750,422008), Point::new(151935,421708), Point::new(153150,421378), Point::new(155610,420658), Point::new(156810,420253), Point::new(157980,419788), 
    Point::new(159135,419278), Point::new(160245,418723), Point::new(161295,418093), Point::new(162285,417403), Point::new(163200,416638), Point::new(164025,415768), Point::new(164730,414808), Point::new(165345,413758), 
    Point::new(165840,412588), Point::new(166230,411313), Point::new(166455,409903), Point::new(166545,408373), Point::new(166395,406348), Point::new(165990,404473), Point::new(165300,402748), Point::new(164370,401203), 
    Point::new(163200,399823), Point::new(161790,398623), Point::new(160125,397603), Point::new(158220,396748), Point::new(156075,396058), Point::new(153735,395578), Point::new(151170,395278) ],
  [ Point::new(-195405,395188), Point::new(-197910,395248), Point::new(-200250,395458), Point::new(-202425,395803), Point::new(-204420,396268), Point::new(-206235,396913), Point::new(-207885,397708), 
    Point::new(-209370,398683), Point::new(-210705,399838), Point::new(-211860,401173), Point::new(-212805,402748), Point::new(-213585,404518), Point::new(-214170,406513), Point::new(-207600,407788), Point::new(-206745,405613), 
    Point::new(-205425,403843), Point::new(-203670,402508), Point::new(-201435,401578), Point::new(-198675,401038), Point::new(-195405,400843), Point::new(-193845,400888), Point::new(-192390,400993), Point::new(-191025,401173), 
    Point::new(-189735,401443), Point::new(-188580,401818), Point::new(-187545,402298), Point::new(-186660,402898), Point::new(-185910,403618), Point::new(-185310,404443), Point::new(-184860,405418), Point::new(-184575,406543), 
    Point::new(-184485,407788), Point::new(-184590,409063), Point::new(-184905,410158), Point::new(-185445,411103), Point::new(-186150,411928), Point::new(-187035,412663), Point::new(-188085,413293), Point::new(-189300,413848), 
    Point::new(-190680,414343), Point::new(-192225,414778), Point::new(-193875,415228), Point::new(-195630,415723), Point::new(-197505,416233), Point::new(-199290,416713), Point::new(-201075,417238), Point::new(-202845,417793), 
    Point::new(-204555,418438), Point::new(-206145,419188), Point::new(-207645,420073), Point::new(-208950,421108), Point::new(-210105,422293), Point::new(-211065,423628), Point::new(-211800,425158), Point::new(-212250,426913), 
    Point::new(-212400,428923), Point::new(-211905,432673), Point::new(-210465,435778), Point::new(-208050,438223), Point::new(-204690,440008), Point::new(-200445,441088), Point::new(-195315,441448), Point::new(-190725,441163), 
    Point::new(-186810,440293), Point::new(-183585,438838), Point::new(-181020,436753), Point::new(-179175,433978), Point::new(-178035,430483), Point::new(-184740,429658), Point::new(-185055,430753), Point::new(-185505,431728), 
    Point::new(-186105,432553), Point::new(-186810,433303), Point::new(-187605,433933), Point::new(-188505,434458), Point::new(-189480,434908), Point::new(-190545,435253), Point::new(-191685,435493), Point::new(-192855,435673), 
    Point::new(-194070,435793), Point::new(-195315,435823), Point::new(-198390,435658), Point::new(-200865,435148), Point::new(-202755,434293), Point::new(-204090,433093), Point::new(-204885,431563), Point::new(-205155,429658), 
    Point::new(-205065,428518), Point::new(-204780,427513), Point::new(-204285,426643), Point::new(-203610,425908), Point::new(-202785,425248), Point::new(-201810,424663), Point::new(-200670,424153), Point::new(-199380,423688), 
    Point::new(-197970,423253), Point::new(-196425,422863), Point::new(-194790,422443), Point::new(-191850,421708), Point::new(-190635,421378), Point::new(-188175,420658), Point::new(-186975,420253), Point::new(-185805,419788), 
    Point::new(-184650,419278), Point::new(-183555,418723), Point::new(-182505,418093), Point::new(-181500,417403), Point::new(-180600,416638), Point::new(-179775,415768), Point::new(-179055,414808), Point::new(-178455,413758), 
    Point::new(-177960,412588), Point::new(-177570,411313), Point::new(-177330,409903), Point::new(-177255,408373), Point::new(-177390,406348), Point::new(-177810,404473), Point::new(-178500,402748), Point::new(-179415,401203), 
    Point::new(-180585,399823), Point::new(-182010,398623), Point::new(-183675,397603), Point::new(-185565,396748), Point::new(-187710,396058), Point::new(-190050,395578), Point::new(-192615,395278) ],
  [ Point::new(-107385,395188), Point::new(-109755,395293), Point::new(-111885,395593), Point::new(-113790,396088), Point::new(-115485,396808), Point::new(-116955,397753), Point::new(-118215,398908), 
    Point::new(-119280,400288), Point::new(-120135,401923), Point::new(-120780,403783), Point::new(-121215,405898), Point::new(-121485,408283), Point::new(-121575,410938), Point::new(-121575,440743), Point::new(-114090,440743), 
    Point::new(-114090,412378), Point::new(-114030,410323), Point::new(-113880,408508), Point::new(-113625,406933), Point::new(-113235,405553), Point::new(-112710,404368), Point::new(-112065,403363), Point::new(-111270,402568), 
    Point::new(-110325,401938), Point::new(-109245,401473), Point::new(-107970,401173), Point::new(-106515,400993), Point::new(-104865,400933), Point::new(-103155,401038), Point::new(-101580,401338), Point::new(-100110,401848), 
    Point::new(-98745,402568), Point::new(-97545,403453), Point::new(-96480,404533), Point::new(-95535,405793), Point::new(-94740,407248), Point::new(-94110,408868), Point::new(-93660,410683), Point::new(-93375,412678), 
    Point::new(-93285,414823), Point::new(-93285,440743), Point::new(-85845,440743), Point::new(-85845,402583), Point::new(-85815,401578), Point::new(-85785,400603), Point::new(-85770,399643), Point::new(-85740,398788), 
    Point::new(-85710,397993), Point::new(-85680,397288), Point::new(-85650,396703), Point::new(-85620,396283), Point::new(-85605,396013), Point::new(-92625,396013), Point::new(-92655,396223), Point::new(-92685,396598), 
    Point::new(-92715,397123), Point::new(-92745,397768), Point::new(-92790,398458), Point::new(-92835,399193), Point::new(-92865,399988), Point::new(-92895,400798), Point::new(-92910,401593), Point::new(-92940,402373), 
    Point::new(-92955,403063), Point::new(-92955,403663), Point::new(-93090,403663), Point::new(-93825,402403), Point::new(-94605,401233), Point::new(-95445,400153), Point::new(-96345,399148), Point::new(-97335,398248), 
    Point::new(-98415,397453), Point::new(-99600,396793), Point::new(-100890,396253), Point::new(-102300,395803), Point::new(-103845,395458), Point::new(-105540,395248) ],
  [ Point::new(78405,395188), Point::new(74280,395578), Point::new(70905,396763), Point::new(68265,398743), Point::new(66390,401398), Point::new(65265,404653), Point::new(64875,408493), Point::new(65070,411268), 
    Point::new(65610,413683), Point::new(66540,415738), Point::new(67770,417493), Point::new(69240,418978), Point::new(70920,420193), Point::new(72825,421168), Point::new(74880,421903), Point::new(77115,422428), Point::new(79455,422788), 
    Point::new(81810,423013), Point::new(84195,423133), Point::new(94230,423298), Point::new(94230,425743), Point::new(94170,427498), Point::new(93975,429058), Point::new(93660,430453), Point::new(93195,431668), Point::new(92610,432703), 
    Point::new(91875,433588), Point::new(91005,434323), Point::new(90000,434893), Point::new(88860,435328), Point::new(87600,435643), Point::new(86190,435838), Point::new(84645,435913), Point::new(83250,435868), Point::new(81960,435763), 
    Point::new(80760,435568), Point::new(79650,435328), Point::new(78645,434953), Point::new(77745,434458), Point::new(76935,433873), Point::new(76245,433138), Point::new(75675,432268), Point::new(75210,431278), Point::new(74865,430123), 
    Point::new(74640,428803), Point::new(66870,429493), Point::new(67230,431218), Point::new(67755,432823), Point::new(68430,434338), Point::new(69315,435748), Point::new(70410,437038), Point::new(71700,438178), Point::new(73245,439168), 
    Point::new(75030,439993), Point::new(77040,440653), Point::new(79335,441163), Point::new(81930,441463), Point::new(84810,441568), Point::new(89970,441133), Point::new(94200,439843), Point::new(97500,437683), Point::new(99870,434728), 
    Point::new(101280,431008), Point::new(101760,426523), Point::new(101760,418093), Point::new(94230,418093), Point::new(86085,417928), Point::new(84300,417853), Point::new(82560,417718), Point::new(80880,417508), Point::new(79320,417208), 
    Point::new(77880,416758), Point::new(76575,416143), Point::new(75420,415363), Point::new(74430,414403), Point::new(73605,413248), Point::new(73005,411883), Point::new(72645,410263), Point::new(72525,408373), Point::new(72750,406138), 
    Point::new(73395,404263), Point::new(74475,402748), Point::new(75975,401653), Point::new(77850,400993), Point::new(80100,400768), Point::new(82365,400903), Point::new(84435,401338), Point::new(86295,402043), Point::new(87975,403003), 
    Point::new(89460,404128), Point::new(90720,405403), Point::new(91800,406783), Point::new(92685,408268), Point::new(93360,409813), Point::new(93855,411388), Point::new(94140,412918), Point::new(94230,414403), Point::new(94230,418093), 
    Point::new(101760,418093), Point::new(101760,407263), Point::new(101850,405238), Point::new(102150,403558), Point::new(102630,402253), Point::new(103380,401338), Point::new(104475,400783), Point::new(105930,400603), 
    Point::new(106350,400603), Point::new(106755,400633), Point::new(107175,400678), Point::new(107580,400738), Point::new(107985,400813), Point::new(108375,400888), Point::new(108375,396253), Point::new(107430,396058), 
    Point::new(106500,395893), Point::new(105555,395758), Point::new(104625,395668), Point::new(103650,395623), Point::new(102630,395593), Point::new(101280,395653), Point::new(100065,395833), Point::new(98985,396133), 
    Point::new(98055,396583), Point::new(97245,397153), Point::new(96555,397828), Point::new(95970,398653), Point::new(95490,399598), Point::new(95100,400648), Point::new(94815,401833), Point::new(94605,403138), Point::new(94485,404563), 
    Point::new(94230,404563), Point::new(93405,403183), Point::new(92520,401893), Point::new(91590,400678), Point::new(90600,399583), Point::new(89490,398593), Point::new(88275,397708), Point::new(86955,396973), Point::new(85500,396343), 
    Point::new(83940,395848), Point::new(82260,395473), Point::new(80415,395263) ],
  [ Point::new(-281265,396013), Point::new(-281265,432148), Point::new(-281280,433123), Point::new(-281310,434128), Point::new(-281310,435148), Point::new(-281325,436138), Point::new(-281355,437068), 
    Point::new(-281385,437953), Point::new(-281415,438748), Point::new(-281430,439468), Point::new(-281460,440038), Point::new(-281490,440473), Point::new(-281520,440743), Point::new(-274485,440743), Point::new(-274455,440533), 
    Point::new(-274440,440158), Point::new(-274410,439633), Point::new(-274380,438988), Point::new(-274350,438283), Point::new(-274320,437518), Point::new(-274275,436738), Point::new(-274230,435943), Point::new(-274200,435118), 
    Point::new(-274170,434368), Point::new(-274155,433693), Point::new(-274155,433093), Point::new(-274035,433093), Point::new(-273300,434353), Point::new(-272505,435523), Point::new(-271680,436603), Point::new(-270780,437608), 
    Point::new(-269790,438478), Point::new(-268695,439258), Point::new(-267510,439933), Point::new(-266220,440503), Point::new(-264810,440953), Point::new(-263280,441298), Point::new(-261585,441508), Point::new(-259725,441568), 
    Point::new(-257370,441463), Point::new(-255225,441163), Point::new(-253320,440653), Point::new(-251640,439948), Point::new(-250155,439003), Point::new(-248895,437848), Point::new(-247845,436453), Point::new(-247005,434818), 
    Point::new(-246375,432928), Point::new(-245910,430813), Point::new(-245640,428443), Point::new(-245550,425818), Point::new(-245550,396013), Point::new(-253035,396013), Point::new(-253035,424378), Point::new(-253080,426433), 
    Point::new(-253245,428248), Point::new(-253530,429823), Point::new(-253905,431188), Point::new(-254415,432358), Point::new(-255060,433348), Point::new(-255855,434158), Point::new(-256800,434788), Point::new(-257910,435238), 
    Point::new(-259170,435568), Point::new(-260610,435763), Point::new(-262245,435823), Point::new(-263955,435718), Point::new(-265560,435403), Point::new(-267045,434878), Point::new(-268395,434173), Point::new(-269595,433273), 
    Point::new(-270690,432178), Point::new(-271605,430933), Point::new(-272370,429478), Point::new(-273000,427843), Point::new(-273465,426043), Point::new(-273735,424078), Point::new(-273825,421933), Point::new(-273825,396013) ],
  [ Point::new(-74070,396013), Point::new(-74070,431263), Point::new(-74085,432223), Point::new(-74115,433183), Point::new(-74115,434158), Point::new(-74130,435103), Point::new(-74145,436033), Point::new(-74175,436918), 
    Point::new(-74205,437773), Point::new(-74235,438598), Point::new(-74265,439363), Point::new(-74295,440083), Point::new(-74310,440743), Point::new(-67290,440743), Point::new(-67260,440083), Point::new(-67230,439348), 
    Point::new(-67200,438553), Point::new(-67155,437743), Point::new(-67110,436918), Point::new(-67080,436078), Point::new(-67035,435223), Point::new(-67005,434398), Point::new(-67005,433588), Point::new(-66975,432853), 
    Point::new(-66960,432193), Point::new(-66960,431608), Point::new(-66795,431608), Point::new(-66255,433243), Point::new(-65700,434713), Point::new(-65130,436033), Point::new(-64500,437218), Point::new(-63795,438253), 
    Point::new(-63030,439138), Point::new(-62175,439888), Point::new(-61230,440488), Point::new(-60180,440953), Point::new(-58995,441298), Point::new(-57660,441508), Point::new(-56160,441568), Point::new(-55575,441553), 
    Point::new(-54990,441493), Point::new(-54435,441403), Point::new(-53925,441328), Point::new(-53490,441238), Point::new(-53145,441163), Point::new(-53145,434338), Point::new(-53670,434458), Point::new(-54255,434548), 
    Point::new(-54885,434623), Point::new(-55575,434698), Point::new(-56310,434728), Point::new(-57120,434743), Point::new(-58740,434623), Point::new(-60210,434233), Point::new(-61500,433588), Point::new(-62610,432718), 
    Point::new(-63600,431638), Point::new(-64440,430363), Point::new(-65115,428923), Point::new(-65670,427303), Point::new(-66090,425488), Point::new(-66390,423553), Point::new(-66570,421498), Point::new(-66630,419323), 
    Point::new(-66630,396013) ],
  [ Point::new(-375690,378448), Point::new(-375690,432673), Point::new(-375705,433708), Point::new(-375735,434713), Point::new(-375735,435673), Point::new(-375750,436558), Point::new(-375765,437398), 
    Point::new(-375795,438178), Point::new(-375825,438883), Point::new(-375855,439498), Point::new(-375885,440023), Point::new(-375915,440443), Point::new(-375930,440743), Point::new(-368745,440743), Point::new(-368715,440593), 
    Point::new(-368685,440308), Point::new(-368655,439873), Point::new(-368610,439348), Point::new(-368565,438733), Point::new(-368535,438058), Point::new(-368490,437353), Point::new(-368445,436603), Point::new(-368415,435823), 
    Point::new(-368370,435043), Point::new(-368340,434278), Point::new(-368325,433543), Point::new(-368160,433543), Point::new(-367440,434908), Point::new(-366660,436123), Point::new(-365805,437188), Point::new(-364890,438148), 
    Point::new(-363885,438973), Point::new(-362790,439663), Point::new(-361620,440263), Point::new(-360360,440728), Point::new(-359025,441073), Point::new(-357570,441328), Point::new(-355995,441478), Point::new(-354315,441523), 
    Point::new(-351390,441343), Point::new(-348810,440788), Point::new(-346545,439873), Point::new(-344565,438628), Point::new(-342870,437068), Point::new(-341895,435778), Point::new(-356220,435778), Point::new(-357840,435703), 
    Point::new(-359400,435463), Point::new(-360885,435073), Point::new(-362295,434473), Point::new(-363570,433573), Point::new(-364740,432388), Point::new(-365730,430903), Point::new(-366585,429073), Point::new(-367290,426898), 
    Point::new(-367830,424348), Point::new(-368145,421333), Point::new(-368250,417838), Point::new(-368160,414838), Point::new(-367905,412138), Point::new(-367455,409783), Point::new(-366855,407743), Point::new(-366105,405973), 
    Point::new(-365190,404488), Point::new(-364095,403258), Point::new(-362835,402283), Point::new(-361425,401548), Point::new(-359865,401068), Point::new(-358155,400783), Point::new(-356295,400678), Point::new(-354345,400813), 
    Point::new(-352650,401218), Point::new(-351180,401878), Point::new(-349890,402808), Point::new(-348810,403963), Point::new(-347910,405358), Point::new(-347160,406978), Point::new(-346590,408823), Point::new(-346170,410893), 
    Point::new(-345900,413203), Point::new(-345735,415708), Point::new(-345675,418423), Point::new(-345735,421078), Point::new(-345900,423523), Point::new(-346170,425773), Point::new(-346590,427813), Point::new(-347160,429643), 
    Point::new(-347910,431233), Point::new(-348795,432598), Point::new(-349875,433738), Point::new(-351135,434623), Point::new(-352590,435268), Point::new(-354285,435658), Point::new(-356220,435778), Point::new(-341895,435778), 
    Point::new(-341460,435208), Point::new(-340290,433078), Point::new(-339360,430663), Point::new(-338685,427963), Point::new(-338235,425053), Point::new(-337950,421918), Point::new(-337860,418588), Point::new(-337950,415288), 
    Point::new(-338235,412153), Point::new(-338685,409198), Point::new(-339360,406468), Point::new(-340290,403993), Point::new(-341460,401803), Point::new(-342870,399883), Point::new(-344565,398248), Point::new(-346545,396928), 
    Point::new(-348810,395953), Point::new(-351390,395383), Point::new(-354315,395188), Point::new(-357375,395383), Point::new(-360180,395998), Point::new(-362715,397003), Point::new(-364920,398473), Point::new(-366750,400453), 
    Point::new(-368205,402958), Point::new(-368415,402958), Point::new(-368385,402838), Point::new(-368370,402583), Point::new(-368370,402208), Point::new(-368355,401728), Point::new(-368340,401188), Point::new(-368325,400558), 
    Point::new(-368310,399868), Point::new(-368295,399133), Point::new(-368295,398323), Point::new(-368265,397528), Point::new(-368250,396733), Point::new(-368250,378448) ],
  [ Point::new(340920,396013), Point::new(340920,402343), Point::new(355755,402343), Point::new(355755,447148), Point::new(342615,437773), Point::new(342615,444793), Point::new(356385,454258), Point::new(363240,454258), 
    Point::new(363240,402343), Point::new(377415,402343), Point::new(377415,396013) ],
  [ Point::new(244470,396013), Point::new(244470,401263), Point::new(245970,404353), Point::new(247680,407203), Point::new(249600,409783), Point::new(251670,412183), Point::new(253800,414403), Point::new(256005,416473), 
    Point::new(258225,418438), Point::new(260430,420298), Point::new(262620,422053), Point::new(264750,423763), Point::new(266730,425473), Point::new(268575,427183), Point::new(270225,428923), Point::new(271635,430708), 
    Point::new(272835,432553), Point::new(273750,434518), Point::new(274305,436633), Point::new(274485,438928), Point::new(274395,440503), Point::new(274155,441958), Point::new(273735,443263), Point::new(273165,444463), 
    Point::new(272445,445528), Point::new(271590,446443), Point::new(270585,447223), Point::new(269460,447868), Point::new(268200,448348), Point::new(266850,448723), Point::new(265410,448933), Point::new(263850,449008), 
    Point::new(262395,448948), Point::new(260985,448738), Point::new(259635,448393), Point::new(258390,447913), Point::new(257235,447283), Point::new(256170,446533), Point::new(255210,445633), Point::new(254370,444598), 
    Point::new(253650,443428), Point::new(253080,442153), Point::new(252675,440728), Point::new(252405,439168), Point::new(244800,439873), Point::new(245160,441928), Point::new(245730,443893), Point::new(246540,445783), 
    Point::new(247560,447553), Point::new(248820,449173), Point::new(250290,450628), Point::new(252000,451933), Point::new(253920,453028), Point::new(256050,453928), Point::new(258420,454603), Point::new(261030,454993), 
    Point::new(263850,455128), Point::new(266640,455008), Point::new(269220,454663), Point::new(271590,454093), Point::new(273735,453298), Point::new(275625,452278), Point::new(277290,451033), Point::new(278745,449578), 
    Point::new(279945,447913), Point::new(280890,446038), Point::new(281580,443953), Point::new(281985,441658), Point::new(282135,439168), Point::new(282015,437248), Point::new(281655,435388), Point::new(281055,433588), 
    Point::new(280290,431848), Point::new(279345,430168), Point::new(278250,428548), Point::new(277020,426973), Point::new(275670,425428), Point::new(274185,423913), Point::new(272625,422443), Point::new(271020,420973), 
    Point::new(269355,419533), Point::new(267675,418123), Point::new(265980,416728), Point::new(264270,415318), Point::new(262590,413938), Point::new(260985,412543), Point::new(259440,411148), Point::new(258000,409723), 
    Point::new(256665,408298), Point::new(255420,406843), Point::new(254325,405388), Point::new(253395,403888), Point::new(252660,402343), Point::new(283035,402343), Point::new(283035,396013) ],
  [ Point::new(114120,396013), Point::new(114120,457363), Point::new(121560,457363), Point::new(121560,396013) ],
]

# Definition of the basic layer numbers
# MaskLayer and MessageLayer are single layers. The color layers are quadruplets 
# starting with the given basic layer number with different intensitites and styles.
# One of those layers is picked randomly to get a "sparkling" effect.
MaskLayer       = 110
MessageLayer    = 111
White           = 10
Red             = 20
Green           = 30
Yellow          = 40
Magenta         = 50
AllColors       = [ Red, Green, Yellow, Magenta ]
WhiteMasked     = 60
RedMasked       = 70
GreenMasked     = 80
YellowMasked    = 90
MagentaMasked   = 100
AllColorsMasked = [ RedMasked, GreenMasked, YellowMasked, MagentaMasked ]

# The layers and their styles
# Definition is:
# [ Number, color, marked, transparent, width, noclear ]
Layers = [

  [ WhiteMasked       , 0xffffff ],
  [ WhiteMasked + 1   , 0xc0c0c0 ],
  [ WhiteMasked + 2   , 0x808080, true ],
  [ WhiteMasked + 3   , 0x404040 ],

  [ RedMasked         , 0xff0000 ],
  [ RedMasked + 1     , 0xc00000 ],
  [ RedMasked + 2     , 0x800000, true ],
  [ RedMasked + 3     , 0x400000 ],

  [ GreenMasked       , 0x00ff00 ],
  [ GreenMasked + 1   , 0x00c000 ],
  [ GreenMasked + 2   , 0x008000, true ],
  [ GreenMasked + 3   , 0x004000 ],

  [ YellowMasked      , 0xffff00 ],
  [ YellowMasked + 1  , 0xc0c000 ],
  [ YellowMasked + 2  , 0x808000, true ],
  [ YellowMasked + 3  , 0x404000 ],

  [ MagentaMasked     , 0xff00ff ],
  [ MagentaMasked + 1 , 0xc000c0 ],
  [ MagentaMasked + 2 , 0x800080, true ],
  [ MagentaMasked + 3 , 0x400040 ],

  [ MaskLayer         , 0x000000, false, false, 1 ],
  [ MessageLayer      , 0x808080, false, false, 0 ],

  [ White             , 0xffffff ],
  [ White + 1         , 0xc0c0c0 ],
  [ White + 2         , 0x808080, true ],
  [ White + 3         , 0x404040 ],
 
  [ Red               , 0xff0000 ],
  [ Red + 1           , 0xc00000 ],
  [ Red + 2           , 0x800000, true ],
  [ Red + 3           , 0x400000 ],

  [ Green             , 0x00ff00 ],
  [ Green + 1         , 0x00c000 ],
  [ Green + 2         , 0x008000, true ],
  [ Green + 3         , 0x004000 ],

  [ Yellow            , 0xffff00 ],
  [ Yellow + 1        , 0xc0c000 ],
  [ Yellow + 2        , 0x808000, true ],
  [ Yellow + 3        , 0x404000 ],

  [ Magenta           , 0xff00ff ],
  [ Magenta + 1       , 0xc000c0 ],
  [ Magenta + 2       , 0x800080, true ],
  [ Magenta + 3       , 0x400040 ],

]

# @brief A class representing a single spark
#
# This is scene object used by the ScriptPlayer to represent an
# object on the scene.
# A scene object must be able to produce itself on the layout.
# The object will receive a "move" call on each tick. When it decides
# it has to disappear it can unregister itself.
#
# A spark is a moving object which has a color (multiple colors
# can be specified and they are picked randomly each iteration).
# A spark can leave a trace, which means it will generate more
# sparks on it's way. After the specified burn time if over, a spark
# will remove itself.
#
# Sparks are subject to gravitation and hence accelerate towards
# negative y.

class Spark

  def initialize(script_runner, args)

    @script_runner = script_runner
    @script_runner.register(self)

    a = args[:a] || 0
    v = args[:v] || 0
    @vx = v * script_runner.tick_val * Math::sin(a / 180.0 * Math::PI)
    @vy = v * script_runner.tick_val * Math::cos(a / 180.0 * Math::PI)

    @x = args[:x] || x
    @y = args[:y] || y

    @color = args[:c] || White  
    if !@color.is_a?(Array)
      @color = [ @color ]
    end

    @burn_time = args[:t]
    @trace = ((args[:trace] || 1) != 0)
    @g = args[:g] || 5
    @tg = args[:tg] || 5
    @stay = ((args[:stay] || 0) != 0)

  end

  def move

    if @burn_time > -0.001

      @x += @vx
      @y += @vy
      @vy -= @g * @script_runner.tick_val 

      @burn_time -= @script_runner.tick_val
      if @burn_time < 0.001
        @stay || @script_runner.unregister(self)
      elsif @trace
        @script_runner.register(Spark::new(@script_runner, 
                                           :x => @x, 
                                           :y => @y, 
                                           :t => 0.01 * rand(100), 
                                           :c => @color, 
                                           :g => @tg, 
                                           :stay => @stay, 
                                           :trace => 0))
      end

    end

  end

  def produce(layout, top)
    f = 1.0 / layout.dbu
    s = 1
    l = @color[rand(@color.size)] + rand(4)
    top.shapes(l).insert(Box::new(Point::new(f * (@x - s), f * (@y - s)), Point::new(f * (@x + s), f * (@y + s))))
  end

end

# @brief A class representing a rocket
#
# This is scene object used by the ScriptPlayer to represent an
# object on the scene. See "Spark" for a brief description of scene objects.
#
# A rocket is a moving object which has a color (multiple colors
# can be specified and they are picked randomly each iteration).
# After a given burn time, the rocket will dissolve into sparks.
#
# Rockets are subject to gravitation and hence accelerate towards
# negative y.

class Rocket

  def initialize(script_runner, args)

    @script_runner = script_runner
    @script_runner.register(self)

    a = args[:a] || 0
    v = args[:v] || 0
    @vx = v * script_runner.tick_val * Math::sin(a / 180.0 * Math::PI)
    @vy = v * script_runner.tick_val * Math::cos(a / 180.0 * Math::PI)

    @x = 0
    @y = 0

    @burn_time = args[:t] || 0.5 
    @color = args[:c]
    @power = args[:p] || 100
    @g = args[:g] || 10 
    @boom = false
    @sparks = args[:sparks] || 50
    @st = args[:st] || 0.5
    @sg = args[:sg] || 0
    @tg = args[:tg] || 10 
    @stay = args[:stay]
    @trace = args[:trace]

  end

  def move

    @x += @vx
    @y += @vy
    @vy -= @g * @script_runner.tick_val 

    @burn_time -= @script_runner.tick_val 
    if @burn_time < 0.001

      if @burn_time < -0.5
        @script_runner.unregister(self)
      elsif !@boom
        @boom = true
        @vx = 0
        @vy = 0
        @sparks.times do |i|
          v = ((rand(100) / 100.0) ** 2) 
          v = (rand(2) == 0 ? @power * (1 - v * 0.25) : @power * (1 + v * 0.25))
          a = rand(360)
          @script_runner.register(Spark::new(@script_runner, :x => @x, :y => @y, :a => a, :v => v, :t => @st * (1 + rand(100) / 100.0), :c => @color, :trace => @trace, :g => @sg, :tg => @tg, :stay => @stay))
        end
      end

    else
      @script_runner.register(Spark::new(@script_runner, :x => @x, :y => @y, :t => 0.2, :c => AllColors))
    end

  end

  def produce(layout, top)

    f = 1.0 / layout.dbu
    if !@boom

      # Produce the rocket as a small rectangle oriented in the flight direction
      l = 10 
      w = 2
      v = Math::sqrt(@vx * @vx + @vy * @vy)
      vx = @vx / v
      vy = @vy / v
      pts = [ Point::new(f * (@x + vx * l * 0.5 + vy * w * 0.5), f * (@y + vy * l * 0.5 - vx * w * 0.5)),
              Point::new(f * (@x + vx * l * 0.5 - vy * w * 0.5), f * (@y + vy * l * 0.5 + vx * w * 0.5)),
              Point::new(f * (@x - vx * l * 0.5 - vy * w * 0.5), f * (@y - vy * l * 0.5 + vx * w * 0.5)),
              Point::new(f * (@x - vx * l * 0.5 + vy * w * 0.5), f * (@y - vy * l * 0.5 - vx * w * 0.5)) ]
      top.shapes(10).insert(Polygon::new(pts))
      text = Text::new("FIZZ!", Trans::new(0, Vector::new(f * @x, f * @y)), 0, 0)
      text.valign = 0
      top.shapes(10).insert(text)

    else

      text = Text::new("BOOM!", Trans::new(0, Vector::new(f * @x, f * @y)), 0, 0)
      text.valign = 0
      top.shapes(10).insert(text)

    end

  end

end

# @brief A class representing a static set of polygons
#
# This is scene object used by the ScriptPlayer to represent an
# object on the scene. See "Spark" for a brief description of scene objects.
#
# This object will simply produce the polygons on the given layer.
# The polygons are given as arrays of Point objects.

class StaticPolygons

  def initialize(script_runner, layer, polygons)
    @layer = layer
    if @layer.is_a?(Array)
      @layer = @layer[0]
    end
    script_runner.register(self)
    @polygons = polygons
  end

  def move
  end

  def produce(layout, top)
    @polygons.each do |p|
      top.shapes(@layer).insert(Polygon::new(p))
    end
  end

end

# @brief The script player
#
# The script player has one basic method, namely "play" which 
# will receive the script and run it. The script is evaluated 
# in the context of the script player's instance and can
# register actions with "at" which itself call various methods,
# in particular "launch" which will launch a rocket.
#
# The script player manages a set of scene objects.
# Internally it keeps a timer that produces ticks in regular intervals.
# On each timer tick, it will look up the script whether new actions
# are to be executed and runs them.
# Next, it will call the "move" method for all objects registered.
# A scene object can use the opportunity to unregister itself
# if it is no longer required. The GC will then delete this object
# later.
# After all objects are moved, the objects which have not been 
# unregistered yet will be asked to produce themselves on the 
# layout which has been cleaned before.

class ScriptPlayer

  def initialize

    mw = Application.instance.main_window

    # Specify the tick value (the time between two steps on the scene)
    @tick = 0.1

    # create a new layout and configure the corresponding view properly
    # with black background and some features disabled
    @ly = mw.create_layout("", 0).layout
    @lv = mw.current_view
    @lv.set_config("background-color", "#000000")
    @lv.set_config("bitmap-oversampling", "1")
    @lv.set_config("text-visible", "true")
    @lv.set_config("sel-transient-mode", "false")
    @lv.set_config("grid-visible", "false")
    @lv.set_config("hide-empty-layers", "false") # saves time
    @lv.clear_layers

    # defines the arena (1000x1000 micron)
    arena = DBox::new(DPoint::new(-500, -100), DPoint::new(500, 1100))

    # create and select the new top cell
    @top = @ly.cell(@ly.add_cell("TOP"))
    @lv.select_cell(@lv.active_cellview_index, @top.cell_index)
    @lv.zoom_box(arena)

    # create the layers from the layer list
    Layers.each do |v|
      @ly.insert_layer_at(v[0], LayerInfo.new(v[0], 0))
      lp = LayerProperties.new
      lp.fill_color = lp.frame_color = v[1] || 0xffffff
      lp.marked = v[2] || false
      lp.source_layer = v[0]
      lp.source_datatype = 0
      lp.dither_pattern = 0
      lp.transparent = (v[3] == nil ? true : v[3])
      lp.width = v[4] || 1
      @lv.insert_layer(@lv.end_layers, lp)
    end

    # Set up the timer
    @timer = QTimer.new
    @timer.interval = @tick * 1000
    @timer.singleShot = false
    @timer.timeout do 
      self.tick
    end

  end

  # Play the script: this method will evaluate the script in the context of 
  # "self" and start the timer
  def play(script)
    stop
    instance_eval(script)
    @time = 0.0
    @clear = true
    @timer.start 
  end

  # Stop the script execution
  def stop
    @clear = false
    @timer.stop
    @actions = { }
    @objects = { }
  end

  # Adds the given object to the scene
  def register(obj)
    @objects[obj.object_id] = obj
  end

  # Removes the given object from the scene
  def unregister(obj)
    @objects.delete(obj.object_id)
  end

  # Gets the tick value (the time between two calls of "move" or "produce")
  # in seconds
  def tick_val
    @tick
  end

  # Put polygons on the scene 
  def put_polygons(color, polygons)
    StaticPolygons::new(self, color, polygons)
  end

  # Launch a rocket
  def launch(args)
    Rocket::new(self, args)
  end

  # Register an action at the given time
  def at(time, &action)
    @actions[(time / @tick + 0.5).to_i] ||= []
    @actions[(time / @tick + 0.5).to_i].push(action)
  end

  # Timer callback: perform the next action
  def tick

    # stop if the view was closed
    if @lv.destroyed?
      stop
      return
    end

    # clear selection and transactions which may depend
    # on any object we will delete now
    @lv.cancel
    @lv.clear_transactions

    # perform the actions for the current time slot
    @time += @tick
    actions = @actions[(@time / @tick + 0.5).to_i]
    if actions
      actions.each do |a|
        a.call
      end
    end

    # clear all layers except the mask (text) layer
    if @clear
      Layers.each do |n,l|
        @top.shapes(n).clear
      end
    end

    # call "move" on each object - since "move" may unregister the 
    # object we cannot iterate over the hash directly.
    objs =  @objects.collect { |id,obj| obj }
    objs.each do |obj|
      obj.move
    end
 
    # call produce on the objects
    @objects.each do |id,obj|
      obj.produce(@ly, @top)
    end

  end

end

# The main action of this module: instantiate the script player
# and initiate the playing of the script
$y2013script = ScriptPlayer.new
$y2013script.play Script

# After the player has been started, run the real application
# (this will do nothing if the script has been started by dragging
# it into the already running application)
Application.instance.exec


