{-# LANGUAGE RecordWildCards #-}

module Potato.Flow.Methods.TextCommon (
  displayLinesToChar
) where

import           Relude

import           Potato.Flow.SElts

import qualified Data.Map as Map
import qualified Data.Text                      as T
import qualified Potato.Data.Text.Zipper        as TZ




concatSpans :: [TZ.Span a] -> Text
concatSpans :: forall a. [Span a] -> Text
concatSpans [Span a]
spans = forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(TZ.Span a
_ Text
t) -> Text
t) [Span a]
spans

subWidth :: Text -> [Maybe Char]
subWidth :: Text -> [Maybe Char]
subWidth Text
t = forall (m :: * -> *) a. Monad m => m (m a) -> m a
join forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> [Maybe Char]
fn forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack forall a b. (a -> b) -> a -> b
$ Text
t where
  fn :: Char -> [Maybe Char]
fn Char
c = case Char -> Int
TZ.charWidth Char
c of
    Int
1 -> [forall a. a -> Maybe a
Just Char
c]
    Int
2 -> [forall a. a -> Maybe a
Just Char
c, forall a. Maybe a
Nothing]
    Int
n -> [forall a. Maybe a
Nothing]
    --n -> trace ("unexpected char " <> [c] <> " of width " <> show n) [Nothing]



displayLinesToChar ::
  (Int, Int) -- ^ the upper left corner of the box containing the text we want to render
  -> TZ.DisplayLines Int -- ^ pre-generated displaylines
  -> (Int, Int) -- ^ the point we want to render
  -> (Int, Int) -- ^ how much text is offest by
  -> Maybe MPChar
displayLinesToChar :: (Int, Int)
-> DisplayLines Int
-> (Int, Int)
-> (Int, Int)
-> Maybe (Maybe Char)
displayLinesToChar (Int
x, Int
y) DisplayLines Int
dl (Int
x',Int
y') (Int
xoff, Int
yoff) = Maybe (Maybe Char)
outputChar where
  spans :: [[Span Int]]
spans = forall tag. DisplayLines tag -> [[Span tag]]
TZ._displayLines_spans DisplayLines Int
dl
  offsetMap :: OffsetMapWithAlignment
offsetMap = forall tag. DisplayLines tag -> OffsetMapWithAlignment
TZ._displayLines_offsetMap DisplayLines Int
dl
  yidx :: Int
yidx = Int
y' forall a. Num a => a -> a -> a
- Int
y forall a. Num a => a -> a -> a
- Int
yoff
  xalignoffset :: Int
xalignoffset = case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Int
yidx OffsetMapWithAlignment
offsetMap of
    -- this will happen because the last character in spans is a generated cursor character if the cursor is at the end and the text ends with a new line
    Maybe (Int, Int)
Nothing -> -Int
1
    --Nothing -> error $ "should not happen. got " <> show yidx <> " in\n" <> show dl <> "\n" <> show spans <> "\n" <> show offsetMap
    Just (Int
offset,Int
_) -> Int
offset
  outputChar :: Maybe (Maybe Char)
outputChar = case [[Span Int]]
spans forall a. [a] -> Int -> Maybe a
!!? Int
yidx of
    Maybe [Span Int]
Nothing -> forall a. Maybe a
Nothing
    Just [Span Int]
row -> Maybe (Maybe Char)
outputChar' where
      rowText :: [Maybe Char]
rowText = Text -> [Maybe Char]
subWidth forall a b. (a -> b) -> a -> b
$ forall a. [Span a] -> Text
concatSpans [Span Int]
row
      xidx :: Int
xidx = Int
x' forall a. Num a => a -> a -> a
- Int
x forall a. Num a => a -> a -> a
- Int
xoff forall a. Num a => a -> a -> a
- Int
xalignoffset
      outputChar' :: Maybe (Maybe Char)
outputChar' = case [Maybe Char]
rowText forall a. [a] -> Int -> Maybe a
!!? Int
xidx of
        Maybe (Maybe Char)
Nothing   -> forall a. Maybe a
Nothing
        Just Maybe Char
cell -> forall a. a -> Maybe a
Just Maybe Char
cell