{-
   Copyright 2016, Dominic Orchard, Andrew Rice, Mistral Contrastin, Matthew Danish

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}

module Analysis.Annotations where

import Data.Data
import Data.Generics.Uniplate.Operations

import Data.Map.Lazy hiding (map)
import Debug.Trace

import Language.Haskell.ParseMonad 

import Language.Fortran
import Analysis.IntermediateReps 

type Report = String

-- Additional "helper" syntax (NOT GENERATED BY PARSER)

-- Loop classifications 

data ReduceType = Reduce | NoReduce
data AccessPatternType = Regular | RegularAndConstants | Irregular | Undecidable 
data LoopType = Functor ReduceType 
               | Gather ReduceType ReduceType AccessPatternType 
               | Scatter ReduceType AccessPatternType

{- classify :: Fortran Annotation -> Fortran Annotation
 classify x = -}

type A = Annotation

data Annotation = A { indices        :: [Variable],
                      lives          :: ([Access],[Access]),
                      arrsRead       :: Map Variable [[Expr ()]], 
                      arrsWrite      :: Map Variable [[Expr ()]],
                      unitVar        :: Int,
                      number         :: Int,
                      refactored     :: Maybe SrcLoc, 
                      successorStmts :: [Int], 
                      newNode        :: Bool      -- used to indicate when a node is newly introduced
                    }
                   deriving (Eq, Show, Typeable, Data)

liveOut = snd . lives
liveIn = fst . lives

 -- Map Variable [[(Variable,Int)]],

pRefactored :: Annotation -> Bool
pRefactored x = case (refactored x) of
                  Nothing -> False
                  Just _  -> True

unitAnnotation = A [] ([], []) empty empty 0 0 Nothing [] False