`ap.ttest` <-
function(me, mm, np.max = 500000, np=c(100, 1000, 5000, 10000, 50000, 100000), 
  aim.p=c(0.1, 0.05, 0.02, 0.01, 0.002, 0.001), confidence.p=0.0001, 
  var.equal=FALSE, min.obs = 10)
{
  if(!is.matrix(mm)){
    stop("mm must be a matrix\n")
  }
  
  dims = numeric(5)
	
  if(is.vector(me)){
    dims[1] = 1
    me = matrix(me, nrow=1)
  }else{
    dims[1] = nrow(me)
  }
  dims[2] = nrow(mm)
  dims[3] = ncol(mm)
  dims[4] = min.obs # number of non-missing values
  
  if(ncol(me) != ncol(mm)){
    stop("me and mm must have the same number of columns\n")
  }

  if(length(np) != length(aim.p)){
    stop("the length of np must equal to the length of aim.p\n")
  }
  
  if(any(diff(np)<=0)){ stop("np must be strictly ascending\n") }
  
  if(any(diff(aim.p)>=0)){ stop("aim.p must be strictly descending\n") }

  if(np.max <= max(np)){
    stop("np.max must be bigger than max(np)\n")
  }

  me.na = is.na(me)
  mm.na = is.na(mm)

  me[me.na] = 0
  mm[mm.na] = 0

  cuts  = qbinom(1-confidence.p, np, aim.p)
  pcuts = cuts/np
  np  = c(np, np.max)
  nnp = c(np[1], diff(np))
  idums = -sample(1000, length(np))

  dims[5] = nnp[1] # number of permutations
  
  pvals = p.pvals = numeric(dims[1])
  Z = .C("ap_ttest", as.double(t(me)), as.integer(t(mm)), as.integer(t(!me.na)), 
       as.integer(t(!mm.na)), as.integer(dims), as.integer(idums[1]), 
       as.integer(var.equal), pv = as.double(pvals), 
       ppv = as.double(p.pvals), PACKAGE="permuteP")
  
  ap.all = Z[["pv"]]
  pp.all = Z[["ppv"]]
  np.all = rep(np[1], dims[1])
  
  for(i in 2:length(np)){
    which.kp = which(pp.all < pcuts[i-1])
    if(length(which.kp)==0){break}
    
    me1 = me[which.kp,]
    me1.na = me.na[which.kp,]
    
    if(is.vector(me1)){
      dims[1] = 1
    }else{
      dims[1] = nrow(me1)
    }
    dims[5] = nnp[i] # number of permutations
    pvals = p.pvals = numeric(dims[1])
    Z = .C("ap_ttest", as.double(t(me1)), as.integer(t(mm)), as.integer(t(!me1.na)), 
         as.integer(t(!mm.na)), as.integer(dims), as.integer(idums[i]), 
         as.integer(var.equal), pv = as.double(pvals), 
         ppv = as.double(p.pvals), PACKAGE="permuteP")
    
    w2 = nnp[i]/np[i]
    w1 = 1 - w2
    pp.all[which.kp] = w1*pp.all[which.kp] + w2*Z[["ppv"]]
    np.all[which.kp] = np[i]
  }
  
  data.frame(nominal.p = ap.all, permute.p = pp.all, n.permute = np.all)
}
