#-------------------------------------------------------------------------------
# Name:        MACpass 2.0
# Purpose:     Change the world
# Author:      Snailface
# Build:       09/28/2013
# Copyright:   (c) Snailface 2013
# License:     See 'License.txt' in the root of this distribution for details.
#------HEADER-------------------------------------------------------------------
import os,sys
import threading
from threading import Timer
import subprocess
import random
import select
import time
from Tkinter import *
import tkMessageBox

macs=[]
options=['']*10
macsize=0
macounter=0
mac=0
output=''
delay=0
delayInit=0
i=0
halt=1
begin=1
killit=0
countdown=0
nextflag=0
macold=0
cooldown=10
temp=0
adapter="Wi-Fi"
miniport=1

#------FUNCTION_DEFS------------------------------------------------------------
def config():
    global options,cooldown,adapter,clist,miniport
    root.title("MACpass 2.0  [adapter="+adapter+"]")

    try:
        f=open('config.ini','r')
        options=f.readlines()
        f.close()
    except:
        display.delete(0.0,2.0)
        display.insert(0.0,'No config.ini file found.\n')

    for i in options:
        if   'adapter=' in i:
            adapter=i.replace('adapter=','').rstrip()
        elif 'cooldwn=' in i:
            cooldown=int(i.replace('cooldwn=',''))
        elif 'command=' in i:
            clist.insert(END,i.replace('command=',''))
        elif 'miniprt=' in i:
            miniport=int(i.replace('miniprt=',''))
        else:
            pass

    if (miniport==1):
        button6.select()
    else:
        pass


def createmacs():
    if os.path.isfile('macs.txt') == False:
        macends=["46", "40", "41", "42", "43", "44", "45", "4F", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", "60", "61", "62", "63", "64", "66", "65", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F"]
        random.shuffle(macends)

        f=open('macs.txt','w')

        for i in macends:
            f.write("4E53504F4F"+i+'\n')
        f.close()
    if os.path.isfile('macsave.txt') == False:
        f=open('macsave.txt','w')
        f.close()

def readmacs():
    global macs,macsize
    f=open('macs.txt','r')
    macs=f.readlines()
    macs=[s.replace(':', '') for s in macs]
    macs=[s.replace(' ', '') for s in macs]
    f.close()
    macsize=len(macs)
    for i in macs:
        mlist.insert(END,'   ['+str(macs.index(i))+']          '+i)
    mlist.see(0)
    mlist.selection_set(0)

def start():
    global delay,delayInit,halt,macounter,begin,nextflag,mlist
    if halt==0:
        no()
        return

    begin=0
    halt=0
    nextflag=0
    delay=int(button5.get())

    if delay<30:
        delay=30
        button5.delete(0,END)
        button5.insert(0,'30')

    delayInit=int(button5.get())
    try:
        macounter=int(mlist.curselection()[0])
    except:
        pass


    swapmac()

def save():
    global macs,macounter,halt,button5
    f=open('macsave.txt','w')
    f.write(str(macounter)+'\n')
    f.write(button5.get()+'\n')
    for i in macs:
        if len(i) == 13:
            f.write('%s' % i)
        else:
            f.write('%s\n' % i)
    f.close()
    halt=1

def load():
    global macs,macsize,macounter,button5,mlist
    if halt == 0:
        no()
        return
    f=open('macsave.txt','r')
    macs=f.readlines()
    macs=[s.replace(':', '') for s in macs]
    macs=[s.replace(' ', '') for s in macs]

    macounter=int(macs[0])
    macs.pop(0)

    delayInit=int(macs[0])
    macs.pop(0)

    button5.delete(0,END)
    button5.insert(0,str(delayInit))

    f.close()
    macsize=len(macs)
    display.delete(1.0,END)
    display.insert(1.0,"Saved MACS loaded. Press Start. ")

    mlist.delete(0,END)

    for i in macs:
        mlist.insert(END,'   ['+str(macs.index(i))+']          '+i)
    mlist.selection_set(macounter)
    mlist.see(macounter)


def msave():
    global mlist,macs,mac
    if halt == 0:
        no()
        return
    try:
        temp=macedit.get()
    except:
        pass
    if len(temp.rstrip()) != 12:
        tkMessageBox.showwarning('MACpass', 'Incorrect Mac address.' )
        return

    macs[mac]=macedit.get().upper()
    macs[mac]=macs[mac].rstrip()
    mlist.delete(0,END)

    for i in macs:
        mlist.insert(END,'   ['+str(macs.index(i))+']          '+i)
    mlist.selection_set(mac)

def mload():
    global macs,mlist,mac
    if halt == 0:
        no()
        return
    try:
        mac=int(mlist.curselection()[0])
    except:
        return
    #print mac
    macedit.delete(0,END)
    macedit.insert(0,macs[mac])

def swapmac():
    global macounter,macs,macsize,delay,output,delayInit,killit,options,countdown,halt,begin,macold,cooldown,adapter
    if killit==1:
        return
    try:
        macold=int(mlist.curselection()[0])
        mlist.selection_clear(macold)


    except:
        pass

    mlist.selection_set(macounter)
    mlist.see(macounter)
    mlist.see(macounter+5)

    if delay==delayInit:
        display.delete(1.0,END)
        p =subprocess.Popen('macshift -i "'+ adapter +'" ' + macs[macounter], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        output = p.stdout.read()
        display.insert(1.0,output)
    if mini.get()==1 and delayInit-delay == cooldown:
        p = subprocess.Popen('netsh wlan start hostednetwork', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        output = p.stdout.read()
        display.delete(1.0,END)
        display.insert(1.0,output)
    else:
        display.delete(1.0,END)
        display.insert(1.0,"Seconds until next change: "+ str(delay))
        display.insert(1.0,macs[macounter]+'\n')
        display.insert(1.0,"Current MAC: "+ str(macounter) +'/'+ str(macsize-1)+'\n')

    delay-=1

    if delay==-1:
        delay=delayInit
        macounter+=1
        if stopat.get() != '':
            countdown=int(stopat.get())-1
            stopat.delete(0,END)
            stopat.insert(0,str(countdown))

    if countdown==-1:
        #display.delete(1.0,END)
        display.insert(1.0,"Countdown stop.\n")
        stopat.delete(0,END)
        halt=1
        countdown=0
        return
    elif halt==1:
        #display.delete(1.0,END)
        display.insert(1.0,"Saved and Paused.\n")
        stopat.delete(0,END)
        return
    elif halt==2:
        #display.delete(1.0,END)
        start()
        return
    elif macounter <= macsize-1:
        t = Timer(1, swapmac)
        t.start()
    else:
        macounter=0
        t = Timer(1, swapmac)
        t.start()

def next():
    global halt,macounter,macsize,nextflag,countdown
    if nextflag==1:
        return
    if macounter == macsize-1:
        macounter=-1
    macounter+=1
    halt=2
    try:
        countdown=int(stopat.get())-1
        stopat.delete(0,END)
        stopat.insert(0,str(countdown))
    except:
        pass
    nextflag=1

def randomize():
    global button3
    global macs,mlist,macounter
    if halt==0:
        no()
        return
    random.shuffle(macs)
    display.delete(1.0,END)
    display.insert(1.0,"Macs shuffled.\n")

    mlist.delete(0,END)

    for i in macs:
        mlist.insert(END,'['+str(macs.index(i))+']   '+str(i))
    mlist.selection_set(macounter)
    mlist.see(macounter)

def execute():
    if halt==0:
        no()
        return
    display.delete(1.0,END)
    temp1=clistenter.get().rstrip()
    p =subprocess.Popen(temp1, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = p.stdout.read()
    display.insert(1.0,output)

def poll():
    global temp,halt

    if clist.curselection() != temp:
        #print str(clist.focus_displayof())

        try:
            if(root.focus_get()==clist and halt!=0):
                clistenter.delete(0,END)
                clistenter.insert(0,clist.selection_get().rstrip())
        except:
            pass

    root.after(250,poll)
    #print clist.curselection(), temp
    temp=clist.curselection()



def no():
    display.delete(1.0,END)
    display.insert(1.0,"Not now!\nPress Save/Pause first.")

def end():
    global killit
    killit=1
    root.destroy()
    sys.exit(0)

#------GUI----------------------------------------------------------------------
root = Tk()
root.resizable(width=FALSE,height=FALSE)
root.protocol('WM_DELETE_WINDOW', end)
ds='sunken'
ss='raised'
bs='raised'

app=Frame(root).grid()

display=Text (app,width=55,height=4,relief=ds,background="#FFD")

display.grid(row=0,column=0,columnspan=3,sticky="nsew",padx=2,pady=2)
button2=Button(app,text='START',width=16,height=4,command=start,relief=ss,background="#EEE").grid(row=2,column=2,rowspan=2,padx=0,pady=0)

button3=Button(app,text='Shuffle Macs',width=16,height=2,command=randomize,relief=bs,background="#FFFFFF")
button3.grid(row=3,column=0,sticky="ew",padx=1,pady=1)

button4=Button(app,text='Next Mac',width=16,height=2,command=next,relief=bs,background="#FFFFFF").grid(row=3,column=1,sticky="ew",padx=1,pady=1)

button10=Button(app,text='Save/Pause',width=16,height=2,command=save,relief=bs,background="#FFFFFF").grid(row=2,column=1,sticky="ew",padx=1,pady=1)
button11=Button(app,text='Load Saved Macs',width=16,height=2,command=load,relief=bs,background="#FFFFFF").grid(row=2,column=0,sticky="ew",padx=1,pady=1)

label1= Label  (app,text='  Delay',width=6,height=1).grid(row=1,column=0,sticky="w")
button5= Entry(app,width=6,background="#FFD")
button5.grid(row=1,column=0,sticky="",padx=10)
button5.insert(0,'60')

mini=IntVar()
button6= Checkbutton(app,text="Virtual Miniport",variable=mini)
button6.grid(row=1,column=2)

label1= Label  (app,text='Countdown',width=10,height=2).grid(row=1,column=1,sticky="w")
stopat= Entry(app,width=6,background="#FFB")
stopat.grid(row=1,column=1,sticky="e",padx=25)

display.insert(1.0,'Welcome to MACpass by Snailface.\n\nPlease read License.txt and Readme.txt in MACpass\nfolder before further usage.')

frame=Frame(root)
frame.grid(row=0,column=3,rowspan=3,ipadx=0,sticky='n')
scrollbar=Scrollbar(frame,orient=VERTICAL)
mlist=Listbox(frame, width=27,yscrollcommand=scrollbar.set,activestyle='none')

scrollbar.config(command=mlist.yview)
scrollbar.grid(sticky="ns",row=0,column=1,rowspan=3)
mlist.grid(sticky='',row=0,column=0,rowspan=3)

button7=Button(app,text='Enter',width=5,height=1,relief=bs,background="#FFFFFF",command=msave).grid(row=3,column=3,sticky="e",pady=5,padx=0)
button8=Button(app,text='Load',width=5,height=1,relief=bs,background="#FFFFFF",command=mload).grid(row=3,column=3,sticky="w",pady=5,padx=0)
macedit=Entry(app,width=12,background="#FFD")
macedit.grid(row=3,column=3,sticky='',pady=5,padx=0)

mlist.selection_set(0)

scrollbar2=Scrollbar(app,orient='vertical')
clist=Listbox(app, height=3,yscrollcommand=scrollbar2.set,activestyle='none')

scrollbar2.config(command=clist.yview)
scrollbar2.grid(sticky="w",row=4,column=3,rowspan=1)
clist.grid(sticky='we',row=4,column=0,columnspan=3)

button15= Button(app,width=10,text='<<  Execute',padx=10,background="#EEE",command=execute)
button15.grid(row=5,column=3,sticky='sew',padx=30)

clistenter=Entry(app,background="#FFB")
clistenter.grid(row=5,column=0,columnspan=3,sticky='ew')

#------MAIN------------------------------------------------------------------
config()
createmacs()
readmacs()
poll()
root.mainloop()