//  Copyright 2023 Brendan Halpin brendan.halpin@ul.ie
//  Distribution is permitted under the terms of the GNU General Public Licence
//
//  Variant of oma.ado to treat dyadic data in long format
//
//    $Id$
//    $Log$
//
// */

capture program drop sdlongdyad
capture program drop omamatv3
program omamatv3, plugin

program define sdlongdyad
syntax varlist(max=2 min=2) [if] [in] [using/], DYADid(varname) SUBSmat(string) DIST(string) ///
  [ MTYPE(string) INDELcost(real -1) LAMbda(real -1) NU(real -1) KLip(integer 0) WORkspace STAndard(string) VERsion ]

if ("`version'" != "") {
  di "SDLONGDYAD version: \$Id$"
}

if ("`mtype'"=="") {
  di as error "One of options MTYPE(OMA) and MTYPE(TWED) required"
  exit
}

local mtype = lower("`mtype'")

if ("`mtype'"=="oma" & `indelcost'==-1) {
  di as error "OMA requires INDELCOST"
  exit
}
if ("`mtype'"=="twed" & (`lambda'==-1 | `nu' == -1)) {
  di as error "TWED requires LAMBDA and NU"
  exit
}


tempvar ego alt
tokenize `varlist'
gen `ego' = `1'
gen `alt' = `2'

local norm 0
if ("`standard'"=="longer") {
  local norm 1
}
if (`norm'==1) {
  di "Normalising distances with respect to length"
}
else {
  di "Not normalising distances with respect to length"
}

local dups 1 // Not relevant to dyadic

marksample touse, novarlist // novarlist mean keep cases with missing vars
tempname misscheck
egen `misscheck' = rowmiss(`varlist')
qui su `misscheck' if `touse'
if (r(max)>0) {
  di as error "Missing values in state variables are not permitted"
  error 416
}
qui su `ego' if `touse'
local egomin = r(min)
qui su `alt' if `touse'
if (r(min)<1 | `egomin'<1) {
  di as error "Values in state variables must begin at 1"
  error 416
}

preserve
qui keep if `touse'

if ("`mtype'"=="twed") {
  local measuretype 5  // Long dyadic TWED
}
if ("`mtype'"=="oma") {
  local measuretype 6  // Long dyadic OMA
}


local printworkspace 0
if "`workspace'" ~= "" {
  local printworkspace 1
}

local adjdur 1
local facexp 1

// Create an idvar which goes from 1-N, based on dyadid
tempvar idvar lengthvar fmark
qui gen `idvar' = 1
qui replace `idvar' = `idvar'[_n-1] + (`dyadid'!=`dyadid'[_n-1]) if _n>1
bysort `idvar': gen `lengthvar' = _N
by     `idvar': gen `fmark' = _n==1

qui su `idvar'
mata: st_matrix("`dist'", J(`r(max)',3,.))
forvalues x = 1/`=_N' {
  local index = `idvar'[`x']
  if `fmark'[`x']==1 {
    mat `dist'[`index',1] = `dyadid'[`x']
    mat `dist'[`index',2] = `lengthvar'[`x']
    mat `dist'[`index',3] = `dyadid'[`x']
  }
}

scalar subsrows = rowsof(`subsmat')
scalar subscols = colsof(`subsmat')
if subsrows!=subscols {
  di "Error: non square substitution matrix"
  exit
}

if ("`measuretype'" == "5") {
  di "Running `mtype'"
  scalar indelcost = 0
  plugin call omamatv3 `idvar' `ego' `alt', ///
    `subsmat' indelcost subsrows `dist' 0 `printworkspace' 0 ///
    `measuretype' `lambda' `nu' 0 1 1 `norm' 1 `klip'
}

if ("`measuretype'" == "6") {
  di "Running `mtype'"
  scalar indelcost = `indelcost'
  plugin call omamatv3 `idvar' `ego' `alt', ///
    `subsmat' indelcost subsrows `dist' 0 `printworkspace' 0 ///
    `measuretype' 0 0 0 1 1 `norm' 1 `klip'
}

restore

end