From 4d134422afc0d2098eecc932e8843bf81f0a44f7 Mon Sep 17 00:00:00 2001 From: Patryk Hegenberg Date: Wed, 3 Jul 2024 20:06:54 +0200 Subject: [PATCH] initial commit --- go.mod | 38 +++++++ go.sum | 97 ++++++++++++++++ img/1.png | Bin 0 -> 2635 bytes img/10.png | Bin 0 -> 2496 bytes img/11.png | Bin 0 -> 3031 bytes img/12.png | Bin 0 -> 2800 bytes img/13.png | Bin 0 -> 6193 bytes img/14.png | Bin 0 -> 5260 bytes img/2.png | Bin 0 -> 3214 bytes img/3.png | Bin 0 -> 3358 bytes img/4.png | Bin 0 -> 3946 bytes img/5.png | Bin 0 -> 3748 bytes img/6.png | Bin 0 -> 4299 bytes img/7.png | Bin 0 -> 3483 bytes img/8.png | Bin 0 -> 3891 bytes img/9.png | Bin 0 -> 3417 bytes main.go | 325 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 17 files changed, 460 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 img/1.png create mode 100644 img/10.png create mode 100644 img/11.png create mode 100644 img/12.png create mode 100644 img/13.png create mode 100644 img/14.png create mode 100644 img/2.png create mode 100644 img/3.png create mode 100644 img/4.png create mode 100644 img/5.png create mode 100644 img/6.png create mode 100644 img/7.png create mode 100644 img/8.png create mode 100644 img/9.png create mode 100644 main.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..13f6d75 --- /dev/null +++ b/go.mod @@ -0,0 +1,38 @@ +module dobble-round + +go 1.22.3 + +require ( + github.com/charmbracelet/huh v0.4.2 + github.com/disintegration/imaging v1.6.2 + github.com/go-pdf/fpdf v0.9.0 +) + +require ( + github.com/atotto/clipboard v0.1.4 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/catppuccin/go v0.2.0 // indirect + github.com/charmbracelet/bubbles v0.18.0 // indirect + github.com/charmbracelet/bubbletea v0.26.3 // indirect + github.com/charmbracelet/lipgloss v0.11.0 // indirect + github.com/charmbracelet/x/ansi v0.1.1 // indirect + github.com/charmbracelet/x/exp/strings v0.0.0-20240524151031-ff83003bf67a // indirect + github.com/charmbracelet/x/input v0.1.1 // indirect + github.com/charmbracelet/x/term v0.1.1 // indirect + github.com/charmbracelet/x/windows v0.1.2 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-localereader v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/muesli/termenv v0.15.2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + golang.org/x/image v0.12.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..53c8793 --- /dev/null +++ b/go.sum @@ -0,0 +1,97 @@ +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA= +github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc= +github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= +github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= +github.com/charmbracelet/bubbletea v0.26.3 h1:iXyGvI+FfOWqkB2V07m1DF3xxQijxjY2j8PqiXYqasg= +github.com/charmbracelet/bubbletea v0.26.3/go.mod h1:bpZHfDHTYJC5g+FBK+ptJRCQotRC+Dhh3AoMxa/2+3Q= +github.com/charmbracelet/huh v0.4.2 h1:5wLkwrA58XDAfEZsJzNQlfJ+K8N9+wYwvR5FOM7jXFM= +github.com/charmbracelet/huh v0.4.2/go.mod h1:g9OXBgtY3zRV4ahnVih9bZE+1yGYN+y2C9Q6L2P+WM0= +github.com/charmbracelet/lipgloss v0.11.0 h1:UoAcbQ6Qml8hDwSWs0Y1cB5TEQuZkDPH/ZqwWWYTG4g= +github.com/charmbracelet/lipgloss v0.11.0/go.mod h1:1UdRTH9gYgpcdNN5oBtjbu/IzNKtzVtb7sqN1t9LNn8= +github.com/charmbracelet/x/ansi v0.1.1 h1:CGAduulr6egay/YVbGc8Hsu8deMg1xZ/bkaXTPi1JDk= +github.com/charmbracelet/x/ansi v0.1.1/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/x/exp/strings v0.0.0-20240524151031-ff83003bf67a h1:lOpqe2UvPmlln41DGoii7wlSZ/q8qGIon5JJ8Biu46I= +github.com/charmbracelet/x/exp/strings v0.0.0-20240524151031-ff83003bf67a/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= +github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a h1:k/s6UoOSVynWiw7PlclyGO2VdVs5ZLbMIHiGp4shFZE= +github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a/go.mod h1:YBotIGhfoWhHDlnUpJMkjebGV2pdGRCn1Y4/Nk/vVcU= +github.com/charmbracelet/x/input v0.1.1 h1:YDOJaTUKCqtGnq9PHzx3pkkl4pXDOANUHmhH3DqMtM4= +github.com/charmbracelet/x/input v0.1.1/go.mod h1:jvdTVUnNWj/RD6hjC4FsoB0SeZCJ2ZBkiuFP9zXvZI0= +github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI= +github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw= +github.com/charmbracelet/x/windows v0.1.2 h1:Iumiwq2G+BRmgoayww/qfcvof7W/3uLoelhxojXlRWg= +github.com/charmbracelet/x/windows v0.1.2/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ= +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= +github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw= +github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= +github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= +golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/img/1.png b/img/1.png new file mode 100644 index 0000000000000000000000000000000000000000..59012c50e2951deb69e6e8e6d75e4d02cb5869af GIT binary patch literal 2635 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 Au>b%7 literal 0 HcmV?d00001 diff --git a/img/3.png b/img/3.png new file mode 100644 index 0000000000000000000000000000000000000000..d2c817cec339d4ae701c3cb5b3df0e76969ba7db GIT binary patch literal 3358 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 literal 0 HcmV?d00001 diff --git a/img/4.png b/img/4.png new file mode 100644 index 0000000000000000000000000000000000000000..830b67094a2ff4e28818310cab717ab4e99b6bb1 GIT binary patch literal 3946 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

rSE5UUZpfqo0pEu9d=cWWS2b8D zNAQ%j9lR|-8$STuNwd5fBXmsA5nkQdG^1?+s$w&nEoeiU9tA4m z-w@;k(gZI@h&|S-4}`J<%r<+|4paobIWz=^NKWJBXtB9%y09v@ATWPD1oSnK38b(` z-5C51Bsq*1FJ8QO@#4jc7cXACc=6)Jix)3m4wFFeKW=u5U@~CROaK4?07*qoM6N<$ Eg6hv{(*OVf literal 0 HcmV?d00001 diff --git a/img/5.png b/img/5.png new file mode 100644 index 0000000000000000000000000000000000000000..c5e879d6cc02a131fb9deda59c470b5bde1c1612 GIT binary patch literal 3748 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 literal 0 HcmV?d00001 diff --git a/img/6.png b/img/6.png new file mode 100644 index 0000000000000000000000000000000000000000..1d43bafd81079f38852daa7bde22b56f757f5ab0 GIT binary patch literal 4299 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 literal 0 HcmV?d00001 diff --git a/img/7.png b/img/7.png new file mode 100644 index 0000000000000000000000000000000000000000..328075236530c77583637924a8862dcf21bfff14 GIT binary patch literal 3483 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 qYPqM6U!0`f1OCDYb`s8>I*jr=!5?~2L* literal 0 HcmV?d00001 diff --git a/img/9.png b/img/9.png new file mode 100644 index 0000000000000000000000000000000000000000..0783a414272b07b776f3b59859d4c95b772042c6 GIT binary patch literal 3417 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 literal 0 HcmV?d00001 diff --git a/main.go b/main.go new file mode 100644 index 0000000..c761c85 --- /dev/null +++ b/main.go @@ -0,0 +1,325 @@ +package main + +import ( + "errors" + "fmt" + "image" + "image/color" + "image/png" + "log/slog" + "math" + "math/rand" + "os" + "path/filepath" + "strconv" + + "github.com/charmbracelet/huh" + "github.com/disintegration/imaging" + "github.com/go-pdf/fpdf" +) + +const ( + imgDir = "./img" + cardWidth = 55.0 + cardHeight = 85.0 + margin = 5.0 + dpiScale = 3.779528 // 96 DPI + outputFileName = "dobble_cards.pdf" + minScaleFactor = 0.7 + maxScaleFactor = 1.0 +) + +type CardGenerator struct { + TotalCards int + ImagesPerCard int + ImageFiles []string + RoundCards bool +} + +func main() { + logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) + slog.SetDefault(logger) + + cg, err := getInputAndInitialize() + if err != nil { + logger.Error("Initialization failed", "error", err) + os.Exit(1) + } + + cards := cg.generateCards() + logger.Info("Cards generated", "count", len(cards)) + + if err := generatePDF(cards, cg.RoundCards); err != nil { + logger.Error("PDF generation failed", "error", err) + os.Exit(1) + } + + logger.Info("PDF successfully generated") +} + +func getInputAndInitialize() (*CardGenerator, error) { + var totalCardsStr, imagesPerCardStr string + var roundCards bool + + form := huh.NewForm( + huh.NewGroup( + huh.NewInput().Title("Enter the total number of cards:").Value(&totalCardsStr), + huh.NewInput().Title("Enter the number of images per card:").Value(&imagesPerCardStr), + huh.NewConfirm(). + Title("Do you want round cards?"). + Value(&roundCards), + ), + ) + + if err := form.Run(); err != nil { + return nil, fmt.Errorf("form input failed: %w", err) + } + + totalCards, err1 := strconv.Atoi(totalCardsStr) + imagesPerCard, err2 := strconv.Atoi(imagesPerCardStr) + if err := errors.Join(err1, err2); err != nil { + return nil, fmt.Errorf("invalid input: %w", err) + } + + cg := &CardGenerator{ + TotalCards: totalCards, + ImagesPerCard: imagesPerCard, + RoundCards: roundCards, + } + + if err := cg.loadImageFiles(); err != nil { + return nil, err + } + + return cg, nil +} + +func (cg *CardGenerator) generateCards() [][]string { + n := cg.ImagesPerCard - 1 + totalCards := n*n + n + 1 + + if len(cg.ImageFiles) < totalCards { + slog.Error("Not enough images for the given parameters", + "required", totalCards, + "available", len(cg.ImageFiles)) + return nil + } + + cards := cg.generateCardIndices(n) + imageCards := cg.convertToImageCards(cards) + cg.shuffleCards(imageCards) + + return cg.limitCards(imageCards) +} + +func (cg *CardGenerator) generateCardIndices(n int) [][]int { + cards := make([][]int, 0, n*n+n+1) + + for i := 0; i < n+1; i++ { + card := make([]int, cg.ImagesPerCard) + card[0] = 1 + for j := 0; j < n; j++ { + card[j+1] = (j + 1) + (i * n) + 1 + } + cards = append(cards, card) + } + + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + card := make([]int, cg.ImagesPerCard) + card[0] = i + 2 + for k := 0; k < n; k++ { + card[k+1] = (n + 1 + n*k + (i*k+j)%n) + 1 + } + cards = append(cards, card) + } + } + + return cards +} + +func (cg *CardGenerator) convertToImageCards(cards [][]int) [][]string { + imageCards := make([][]string, len(cards)) + for i, card := range cards { + imageCards[i] = make([]string, len(card)) + for j, symbolIndex := range card { + imageCards[i][j] = cg.ImageFiles[symbolIndex-1] + } + } + return imageCards +} + +func (cg *CardGenerator) shuffleCards(cards [][]string) { + rand.Shuffle(len(cards), func(i, j int) { + cards[i], cards[j] = cards[j], cards[i] + }) + + for i := range cards { + rand.Shuffle(len(cards[i]), func(j, k int) { + cards[i][j], cards[i][k] = cards[i][k], cards[i][j] + }) + } +} + +func (cg *CardGenerator) limitCards(cards [][]string) [][]string { + if cg.TotalCards < len(cards) { + return cards[:cg.TotalCards] + } + return cards +} + +func (cg *CardGenerator) loadImageFiles() error { + files, err := os.ReadDir(imgDir) + if err != nil { + return fmt.Errorf("failed to read image directory: %w", err) + } + + for _, file := range files { + if !file.IsDir() && filepath.Ext(file.Name()) == ".png" { + cg.ImageFiles = append(cg.ImageFiles, filepath.Join(imgDir, file.Name())) + } + } + + requiredImages := cg.calculateRequiredImages() + + if len(cg.ImageFiles) < requiredImages { + return fmt.Errorf("not enough images in the img folder: required %d, found %d", requiredImages, len(cg.ImageFiles)) + } + + rand.Shuffle(len(cg.ImageFiles), func(i, j int) { + cg.ImageFiles[i], cg.ImageFiles[j] = cg.ImageFiles[j], cg.ImageFiles[i] + }) + + return nil +} + +func (cg *CardGenerator) calculateRequiredImages() int { + n := cg.ImagesPerCard - 1 + return n*n + n + 1 +} + +func generatePDF(cards [][]string, roundCards bool) error { + pdf := fpdf.New("P", "mm", "A4", "") + pdf.SetAutoPageBreak(true, 10) + + pageWidth, pageHeight, _ := pdf.PageSize(1) + cardSize := math.Min(cardWidth, cardHeight) + cardsPerRow := int((pageWidth - 2*margin) / (cardSize + margin)) + cardsPerCol := int((pageHeight - 2*margin) / (cardSize + margin)) + cardsPerPage := cardsPerRow * cardsPerCol + + for i, card := range cards { + if i%cardsPerPage == 0 { + pdf.AddPage() + } + + col := i % cardsPerRow + row := (i / cardsPerRow) % cardsPerCol + + x := margin + float64(col)*(cardSize+margin) + y := margin + float64(row)*(cardSize+margin) + + slog.Info("Processing card", "index", i, "x", x, "y", y) + + if roundCards { + if err := processRoundCard(pdf, x, y, card); err != nil { + return fmt.Errorf("failed to process round card %d: %w", i, err) + } + } else { + if err := processSquareCard(pdf, x, y, card); err != nil { + return fmt.Errorf("failed to process square card %d: %w", i, err) + } + } + } + + return pdf.OutputFileAndClose(outputFileName) +} + +func processRoundCard(pdf *fpdf.Fpdf, x, y float64, card []string) error { + diameter := math.Min(cardWidth, cardHeight) + radius := diameter / 2 + + pdf.SetDrawColor(0, 0, 0) + pdf.Circle(x+radius, y+radius, radius, "D") + + availableRadius := radius - 5 + optimalImageSize := availableRadius * 2 / math.Sqrt(float64(len(card))) + + for i, imgFile := range card { + angle := 2 * math.Pi * float64(i) / float64(len(card)) + distanceFromCenter := availableRadius * 0.6 + + imgX := x + radius + distanceFromCenter*math.Cos(angle) - optimalImageSize/2 + imgY := y + radius + distanceFromCenter*math.Sin(angle) - optimalImageSize/2 + + if err := processImage(pdf, imgFile, imgX, imgY, optimalImageSize); err != nil { + return err + } + } + + return nil +} + +func processSquareCard(pdf *fpdf.Fpdf, x, y float64, card []string) error { + pdf.Rect(x, y, cardWidth, cardHeight, "D") + + availableWidth := cardWidth - 10 + availableHeight := cardHeight - 10 + optimalImageSize := math.Min(availableWidth/2, availableHeight/float64(len(card))) + + for i, imgFile := range card { + imgX := x + 5 + rand.Float64()*(availableWidth-optimalImageSize) + imgY := y + 5 + float64(i)*(availableHeight/float64(len(card))) + rand.Float64()*(availableHeight/float64(len(card))-optimalImageSize) + + if err := processImage(pdf, imgFile, imgX, imgY, optimalImageSize); err != nil { + return err + } + } + + return nil +} + +func processImage(pdf *fpdf.Fpdf, imgFile string, x, y, size float64) error { + file, err := os.Open(imgFile) + if err != nil { + return fmt.Errorf("failed to open image file: %w", err) + } + defer file.Close() + + img, _, err := image.Decode(file) + if err != nil { + return fmt.Errorf("failed to decode image: %w", err) + } + + scaleFactor := minScaleFactor + rand.Float64()*(maxScaleFactor-minScaleFactor) + imgSize := size * scaleFactor + targetSize := uint(imgSize * dpiScale) + + img = imaging.Fit(img, int(targetSize), int(targetSize), imaging.Lanczos) + + rotation := rand.Intn(4) * 90 + rotatedImg := imaging.Rotate(img, float64(rotation), color.Transparent) + + tmpFile, err := os.CreateTemp("", "processed_*.png") + if err != nil { + return fmt.Errorf("failed to create temp file: %w", err) + } + defer os.Remove(tmpFile.Name()) + + if err := png.Encode(tmpFile, rotatedImg); err != nil { + return fmt.Errorf("failed to encode processed image: %w", err) + } + tmpFile.Close() + + pdf.ImageOptions( + tmpFile.Name(), + x, y, + imgSize, imgSize, + false, + fpdf.ImageOptions{ImageType: "PNG"}, + 0, + "", + ) + + return nil +}