@name FailCake HTTP Midi Parser V1
@outputs Thing:string CurDex
@persist [O E]:entity GTable:gtable HideChat Type:table Play 
@persist Load Chat:array FileName:string MidiInfo:string RawMidi:array Index [Info Things]:array Tempo Timing SpeakerNode
@persist StartTime Timesz Events:string HardLaggyWay Set BPM Asd In Okai:array Temp:array Midi:string K TempMidi:string Os
@trigger all 
@model models/beer/wiremod/watersensor.mdl

function number findTime(Lol:array){   
In = 0

while(perf() && In < Lol:count()){

Okai = Lol[In,string]:explode(" ") 

if(Okai[1,string] == Type["4",string]){ 
    
BPM = (60000000/Okai[3,string]:toNumber())

if (Asd == 0)
{
Asd = (GTable["timebase",number]*(BPM/60))
printColor(vec(255,0,0),"Default Time Found! Time = ",vec(255,255,255),Asd)
return Asd  
break
}
 
}
In++
}


}



if(first() | duped()){
runOnHTTP(1) 
runOnChat(1)
runOnTick(1)

O = owner()
E = entity()

K = 0

GTable = gTable("stream",1)

if(GTable["first",number] == 0){
GTable:clear()
GTable["first",number] = 1
GTable["HardLaggyWay",number] = 0
GTable["ID",number] = 1
printColor(vec(255,0,0),"[Warning]",vec(255,255,255)," Gtable Reseted!")
}

## SETTINGS ##
GTable["Music",string] = "\synth/square.wav"
GTable["Go",number] = 0
HideChat = 1
## SETTINGS ##    

GTable["Music",string] = ""

## Types ##

Type["1",string] = "I" ## Track Beginging
Type["2",string] = "E" ## Track End
Type["3",string] = "N" ## Note On
Type["5",string] = "F" ## Note On
Type["4",string] = "T" ## Track Tempo


## Sphere thing Counter (loading)
holoCreate(1)
holoModel(1,"dome")
holoPos(1,E:toWorld(vec(0,0,0.6)))
holoScaleUnits(1,vec(1.2,1.2,1))
holoColor(1,vec(1,1,1))
holoParent(1,E)

holoCreate(2)
holoModel(2,"pyramid")
holoPos(2,E:toWorld(vec(-1,0,0.6)))
holoScaleUnits(2,vec(0.5,1,2.3))
holoColor(2,vec(1,1,1))
holoAng(2,ang(-90,0,0))
holoParent(2,1)

holoCreate(3)
holoModel(3,"models/props_junk/sawblade001a.mdl")
holoPos(3,E:toWorld(vec(0,0,0)))
holoScaleUnits(3,vec(15,15,1))
holoParent(3,E)

Set = 1 # default

# Holo Check
if(holoEntity(3):model() != "models/props_junk/sawblade001a.mdl")
{
holoDelete(3)   
printColor(vec(255,0,0),"HoloModel Not Detected!")
GTable["Holo",number] = 0
}

setName("FailCake HTTP Midi Parser V1 [IDLE]")

Load = 0
}

if(chatClk(O)){
Chat = O:lastSaid():explode(" ")

if(Chat[1,string]:lower() == "-load" & Load == 0 & Play == 0){
    
if(HideChat){
hideChat(1)    
}

FileName = Chat[2,string]:lower()

if(FileName != ""){
Load = 1
hint("* Loading Midi *",7)  
setName("FailCake HTTP Midi Parser V1 [Loading Midi]")
E:soundPlay(1,0,"/buttons/button14.wav")
httpRequest("http://failcakemidi.uphero.com/testmidi")
}else{
FileName = ""
hint("* Insert the Midi Name! *",7)  
}
  
}

if(Chat[1,string]:lower() == "-play" & Load == 0 & Play == 0){
    
if(HideChat){
hideChat(1)    
}    

Play = 1
}

if(Chat[1,string]:lower() == "-clean" & Load == 0 & Play == 0){
    
if(HideChat){
hideChat(1)    
}    

GTable["first",number] = 0
printColor(vec(255,0,0),"[Warning]",vec(255,255,255)," GTable Cleaned!")
reset()
}

if(Chat[1,string]:lower() == "-lagway" & Load == 0 & Play == 0){
    
if(HideChat){
hideChat(1)    
}    

GTable["HardLaggyWay",number] = Chat[2,string]:toNumber()
hint("* Laggy Way : " + GTable["HardLaggyWay",number] + " *",7)
}

}


if(Load == 1){
if(httpClk()){
Midi = httpData() ## the midi info!

if(Midi == ""){
printColor(vec(255,0,0),"[Warning]",vec(255,255,255)," Midi Not Found!")
Load = 0
}else{
Load = 2
MidiInfo = Midi
printColor(vec(0,255,0),"[Hint] ",vec(255,255,255),"HTTP Midi Found!")
printColor(vec(0,255,0),"[Info] ",vec(255,0,0),MidiInfo:length() ,vec(255,255,255)," HTTP Size!")
printColor(vec(0,255,0),"[Hint] ",vec(255,255,255),"Now Parsing The Midi!")
}

}
}




## Parse the Actual Midi!

if(changed(Load) & Load == 2){
setName("FailCake HTTP Midi Parser V1 [Loading Midi] [Parsing]")    
Temp:clear()
}




if(Load == 2){
  
if(GTable["HardLaggyWay",number] == 1){
while( perf() & K < MidiInfo:length()){
  
TempMidi += MidiInfo
Thing = K + " <-> " + MidiInfo:length() + " -- " + RawMidi:count()

if(MidiInfo[Os] == "P"){
RawMidi:pushString(TempMidi)
TempMidi = ""
Os = 0
} 
 
Os++   
K++ 

if(K > MidiInfo:length()){
Load = 0
printColor(vec(0,255,0),"[Hint] ",vec(255,255,255),"Midi Parsed!")
setName("FailCake HTTP Midi Parser V1")   
break  
}
}
}else{
RawMidi = MidiInfo:explode("\n")
Load = 0
printColor(vec(0,255,0),"[Hint] ",vec(255,255,255),"Midi Parsed!")
setName("FailCake HTTP Midi Parser V1")  
}  
   
}


if(Play == 1){
setName("FailCake HTTP Midi Parser V1 [Playing Midi] [Preparing]")    

Info = RawMidi[1,string]:explode(" ")

if(Info[1,string] == Type["1",string]){
printColor(vec(155,0,155),"########### Midi Info ##########")
printColor(vec(255,255,255),"Midi Format : " + Info[2,string])
printColor(vec(255,255,255),"Midi TimeBase : " + Info[3,string])  
printColor(vec(155,0,155),"########### Midi Info ##########")

GTable["timebase",number] = Info[3,string]:toNumber()

Play = 2
}else{
Play = 0
printColor(vec(255,0,0),"[Warning]",vec(255,255,255)," Error In Midi File!")
setName("FailCake HTTP Midi Parser V1") 

}
}


if(changed(Play) & Play == 2){
StartTime = realtime()
Index = 0
Timesz = 0
GTable["Active",number] = 1
GTable["prepare",number] = 1
GTable["Go",number] = 1
Timing = findTime(RawMidi)

setName("FailCake HTTP Midi Parser V1 [Playing]") 
}

if(Play == 2){
    
CurDex = Timesz
Thing = SpeakerNode + " - " + Things[4,string]:toNumber() + " - " + Things[3,string]:toNumber()
Things = RawMidi[Index,string]:explode(" ") 

   
GTable["CurTime",number] = Things[2,string]:toNumber()
Timesz = (realtime()-StartTime)*Timing


while (perf() & Timesz >= Things[2,string]:toNumber() )
{  
        Events = Things[1,string]
        
        if (Events == Type["4",string]){  
             
            Tempo  = Things[3,string]:toNumber()
            Timing = (GTable["timebase",number]*(Tempo/60))
            
        }elseif(Events == Type["3",string]){
    
         SpeakerNode = floor(Things[3,string]:toNumber()/Set) + 1
         GTable["chan_"+SpeakerNode,number] = (Things[3,string]:toNumber()%Set) + 1
         GTable["pi_"+SpeakerNode,number] = Things[4,string]:toNumber()
         GTable["vol_"+SpeakerNode,number] = Things[5,string]:toNumber()
        }elseif(Events == Type["5",string]){
    
         SpeakerNode = floor(Things[3,string]:toNumber()/Set) + 1
         GTable["vol_"+SpeakerNode,number] = 0  
    }
        
        Index++
        if(Index > RawMidi:count()){
         break
       
        }
    }   
}
