func saveBandRecordToConcertHandler(rw http.ResponseWriter, req *http.Request) {
	err := req.ParseForm()
	common.CheckError(err)
	form := req.Form

	concertId, err := strconv.ParseInt(form["concert_id"][0], 10, 64)
	common.CheckError(err)

	bandId, err := strconv.ParseInt(form["band_id"][0], 10, 64)

	dbmap := db.InitDb(BandConcert{}, "band_concert")
	defer dbmap.Db.Close()

	bandConcert := BandConcert{BandId: bandId, ConcertId: concertId}
	err = dbmap.SelectOne(&bandConcert, "SELECT * FROM concertsap.concert_band WHERE band_id=? AND concert_id=?", bandConcert.BandId, bandConcert.ConcertId)

	if err != nil {
		insertBandConcert(bandConcert)
		err = dbmap.SelectOne(&bandConcert, "SELECT * FROM concertsap.concert_band WHERE band_id=? AND concert_id=?", bandConcert.BandId, bandConcert.ConcertId)
	}

	formDate := form["date"][0]
	formTime := form["time"][0]
	bandConcertRecord := BandConcertRecord{BandId: bandConcert.BandId, ConcertId: bandConcert.ConcertId, Date: formDate, Time: formTime}
	insertBandConcertRecord(bandConcertRecord)

	http.Redirect(rw, req, "addBandRecordToConcert", http.StatusFound)
}
func addHandler(rw http.ResponseWriter, req *http.Request) {
	if req.Method == "POST" {
		dbmap := db.InitDb(Retailer{}, "retailer")
		defer dbmap.Db.Close()

		err := req.ParseForm()
		common.CheckError(err)
		form := req.Form

		err = dbmap.Insert(&Retailer{Name: form["name"][0], Website: form["website"][0]})
		common.CheckError(err)
	}

	type Page struct {
		PageName string
		Title    string
	}

	p := Page{
		PageName: "retailer",
		Title:    "Add Controller",
	}

	common.Templates = template.Must(template.ParseFiles("templates/retailer/add.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func saveBandsToConcertHandler(rw http.ResponseWriter, req *http.Request) {
	dbmap := db.InitDb(Band{}, "band")
	defer dbmap.Db.Close()

	err := req.ParseForm()
	common.CheckError(err)
	form := req.Form

	concertId, err := strconv.ParseInt(form["concert_id"][0], 10, 64)
	common.CheckError(err)

	r, err := regexp.Compile(`([^<]+)<br>`)
	common.CheckError(err)
	rawBands := form["parsedInput"][0]
	bandMatches := r.FindAllStringSubmatch(rawBands, -1)

	for _, bandName := range bandMatches {
		newBand := Band{Name: bandName[1]}
		err = dbmap.SelectOne(&newBand, "SELECT * FROM concertsap.band WHERE name=?", strings.ToUpper(newBand.Name))

		if err != nil {
			insertBand(newBand)
			err = dbmap.SelectOne(&newBand, "SELECT * FROM concertsap.band WHERE name=?", newBand.Name)
		}

		newBandConcert := BandConcert{BandId: newBand.Id, ConcertId: concertId}
		insertBandConcert(newBandConcert)
	}

	http.Redirect(rw, req, "addBandsToConcert", http.StatusFound)
}
func addHandler(rw http.ResponseWriter, req *http.Request) {
	if req.Method == "POST" {
		dbmap := db.InitDb(State{}, "state")
		defer dbmap.Db.Close()

		err := req.ParseForm()
		common.CheckError(err)
		form := req.Form

		err = dbmap.Insert(&State{Name: form["name"][0], Acronym: form["acronym"][0]})
		common.CheckError(err)
	}

	type Page struct {
		PageName string
		Title    string
	}

	p := Page{
		PageName: "state",
		Title:    "Add New Concert",
	}

	common.Templates = template.Must(template.ParseFiles("templates/state/add.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func userViewOneHandler(rw http.ResponseWriter, req *http.Request) {
	params := mux.Vars(req)
	id := params["id"]

	type Page struct {
		PageName     string
		Title        string
		Concert      Concert
		ConcertState int
		UntilDays    int
	}

	concert := FindOne(id)

	var concertState int
	var untilDays int

	tStart, terr := time.Parse("2006-01-02 15:04:05", concert.Start+" 23:59:59")
	common.CheckError(terr)

	tEnd, terr := time.Parse("2006-01-02 15:04:05", concert.End+" 23:59:59")
	common.CheckError(terr)

	if time.Now().After(tEnd) {
		// Concert is in the past - concertState = 1
		concertState = 1
		untilDays = int(time.Since(tEnd).Hours()/24) + 1
	} else if time.Now().After(tStart) {
		// Concert is now! - concertState = 2
		concertState = 2
		untilDays = int(time.Since(tEnd).Hours()/24) + 1
	} else {
		// Concert is in the future - concertState = 3
		concertState = 3
		untilDays = -1*int(time.Since(tStart).Hours()/24) + 1
	}

	p := Page{
		PageName:     "user_concert",
		Title:        "View One Controller: " + id,
		Concert:      concert,
		ConcertState: concertState,
		UntilDays:    untilDays,
	}

	common.Templates = template.Must(template.ParseFiles("templates/concert/userViewOne.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func addHandler(rw http.ResponseWriter, req *http.Request) {
	type Page struct {
		PageName  string
		Title     string
		Concerts  []concert.Concert
		Retailers []retailer.Retailer
		Now       string
	}

	concerts := concert.FindAll()
	retailers := retailer.FindAll()
	t := time.Now()

	p := Page{
		PageName:  "ticket",
		Title:     "Add Controller",
		Concerts:  concerts,
		Retailers: retailers,
		Now:       t.Format("2006-01-02 15:04:05"),
	}

	common.Templates = template.Must(template.ParseFiles("templates/ticket/add.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func userViewOneHandler(rw http.ResponseWriter, req *http.Request) {
	params := mux.Vars(req)
	id := params["id"]

	type Page struct {
		PageName string
		Title    string
		Band     Band
		Concerts []concert.Concert
	}

	band := FindOne(id)
	concerts := concert.FindConcertsByBand(id)

	p := Page{
		PageName: "user_band",
		Title:    "View One Controller: " + id,
		Band:     band,
		Concerts: concerts,
	}

	common.Templates = template.Must(template.ParseFiles("templates/band/userViewOne.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func FindBandConcert(concertId string) []BandJoinedConcert {
	dbmap := db.InitDb(BandConcert{}, "band_concert")
	defer dbmap.Db.Close()

	var concertIdString string

	if concertId != "" {
		concertIdString = "AND c.id = " + concertId
	}

	var bandConcerts []BandJoinedConcert
	_, err := dbmap.Select(&bandConcerts, `
        SELECT b.id AS band_id,
            b.name AS band_name,
            b.website AS band_website,
            c.id AS concert_id,
            c.name AS concert_name,
            c.address AS concert_address,
            c.state_id AS concert_state_id,
            c.website AS concert_website,
            c.start AS concert_start,
            c.end AS concert_end
        FROM band_concert bc
        JOIN band b
        ON b.id = bc.band_id
        JOIN concert c
        ON c.id = bc.concert_id
        `+concertIdString+`
        ORDER BY b.name`)
	common.CheckError(err)

	return bandConcerts
}
func ConcertBandHandler(rw http.ResponseWriter, req *http.Request) {
	params := mux.Vars(req)
	id := params["id"]

	json, err := json.Marshal(band.FindBandConcert(id))
	common.CheckError(err)

	fmt.Fprintf(rw, "%v", string(json))
}
func FindOne(id string) Concert {
	dbmap := db.InitDb(Concert{}, "concert")
	defer dbmap.Db.Close()

	var concert Concert
	err := dbmap.SelectOne(&concert, "SELECT * FROM concert WHERE id = ? ORDER BY name", id)
	common.CheckError(err)

	return concert
}
func FindAll() []Concert {
	dbmap := db.InitDb(Concert{}, "concert")
	defer dbmap.Db.Close()

	var concerts []Concert
	_, err := dbmap.Select(&concerts, "SELECT * FROM concert ORDER BY name")
	common.CheckError(err)

	return concerts
}
func FindOne(id string) Band {
	dbmap := db.InitDb(Band{}, "band")
	defer dbmap.Db.Close()

	var band Band
	err := dbmap.SelectOne(&band, "SELECT * FROM band WHERE id = ? ORDER BY name", id)
	common.CheckError(err)

	return band
}
func FindBandsAndConcerts() []BandAndConcertsCount {
	dbmap := db.InitDb(Band{}, "band")
	defer dbmap.Db.Close()

	var bandsAndConcertsCount []BandAndConcertsCount
	_, err := dbmap.Select(&bandsAndConcertsCount, "SELECT b.id, b.name, COUNT(*) AS count_count FROM band_concert bc JOIN band b ON bc.band_id = b.id GROUP BY b.id ORDER BY b.name")
	common.CheckError(err)

	return bandsAndConcertsCount
}
func FindAll() []State {
	dbmap := db.InitDb(State{}, "state")
	defer dbmap.Db.Close()

	var states []State
	_, err := dbmap.Select(&states, "SELECT * FROM state ORDER BY acronym")
	common.CheckError(err)

	return states
}
func FindAll() []Ticket {
	dbmap := db.InitDb(Ticket{}, "ticket_record")
	defer dbmap.Db.Close()

	var tickets []Ticket
	_, err := dbmap.Select(&tickets, "SELECT * FROM ticket_records ORDER BY timestamp")
	common.CheckError(err)

	return tickets
}
func FindAll() []Band {
	dbmap := db.InitDb(Band{}, "band")
	defer dbmap.Db.Close()

	var bands []Band
	_, err := dbmap.Select(&bands, "SELECT * FROM band ORDER BY name")
	common.CheckError(err)

	return bands
}
func saveHandler(rw http.ResponseWriter, req *http.Request) {
	err := req.ParseForm()
	common.CheckError(err)
	form := req.Form

	stateId, err := strconv.ParseInt(common.IssetInForm(form["state_id"], 0), 10, 64)
	common.CheckError(err)

	concert := Concert{
		Name:    common.IssetInForm(form["name"], 0),
		Address: common.IssetInForm(form["address"], 0),
		StateId: stateId,
		Website: common.IssetInForm(form["website"], 0),
		Start:   common.IssetInForm(form["start"], 0),
		End:     common.IssetInForm(form["end"], 0),
	}

	insertConcert(concert)

	http.Redirect(rw, req, "add", http.StatusFound)
}
func InitDb(i interface{}, dbName string) *gorp.DbMap {
	// connect to db using standard Go database/sql API
	// use whatever database/sql driver you wish
	db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/concertsap")
	common.CheckError(err)

	// construct a gorp DbMap
	dbmap := &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{}}

	dbmap.AddTableWithName(i, dbName).SetKeys(true, "id")

	return dbmap
}
func saveHandler(rw http.ResponseWriter, req *http.Request) {
	dbmap := db.InitDb(Band{}, "band")
	defer dbmap.Db.Close()

	err := req.ParseForm()
	common.CheckError(err)
	form := req.Form

	newBand := Band{Name: strings.ToUpper(form["name"][0]), Website: form["website"][0]}
	insertBand(newBand)

	http.Redirect(rw, req, "add", http.StatusFound)
}
func saveHandler(rw http.ResponseWriter, req *http.Request) {
	err := req.ParseForm()
	common.CheckError(err)
	form := req.Form

	retailer := Retailer{
		Name:    common.IssetInForm(form["name"], 0),
		Website: common.IssetInForm(form["website"], 0),
	}

	insertRetailer(retailer)

	http.Redirect(rw, req, "add", http.StatusFound)
}
func saveHandler(rw http.ResponseWriter, req *http.Request) {
	err := req.ParseForm()
	common.CheckError(err)
	form := req.Form

	state := State{
		Name:    common.IssetInForm(form["name"], 0),
		Acronym: common.IssetInForm(form["acronym"], 0),
	}

	insertState(state)

	http.Redirect(rw, req, "add", http.StatusFound)
}
func addHandler(rw http.ResponseWriter, req *http.Request) {
	type Page struct {
		PageName string
		Title    string
	}

	p := Page{
		PageName: "admin_band",
		Title:    "Add Controller",
	}

	common.Templates = template.Must(template.ParseFiles("templates/band/add.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func loginHandler(rw http.ResponseWriter, req *http.Request) {
	type Page struct {
		PageName string
		Title    string
	}

	p := Page{
		PageName: "login",
		Title:    "Login",
	}

	common.Templates = template.Must(template.ParseFiles("templates/home/login.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func FindConcertsByBand(bandId string) []Concert {
	dbmap := db.InitDb(Concert{}, "concert")
	defer dbmap.Db.Close()

	var concerts []Concert
	_, err := dbmap.Select(&concerts, `
        SELECT c.*
        FROM band_concert bc
        JOIN concert c
        ON c.id = bc.concert_id
        WHERE bc.band_id = ?
        ORDER BY name`, bandId)
	common.CheckError(err)

	return concerts
}
func saveHandler(rw http.ResponseWriter, req *http.Request) {
	err := req.ParseForm()
	common.CheckError(err)
	form := req.Form

	ticket := Ticket{
		Price:      common.IssetInForm(form["price"], 0),
		ConcertId:  common.IssetInForm(form["concert_id"], 0),
		RetailerId: common.IssetInForm(form["retailer_id"], 0),
		Timestamp:  common.IssetInForm(form["datetime"], 0),
	}

	insertTicket(ticket)

	http.Redirect(rw, req, "add", http.StatusFound)
}
func adminViewOneHandler(rw http.ResponseWriter, req *http.Request) {
	params := mux.Vars(req)
	id := params["id"]

	type Page struct {
		PageName string
		Title    string
	}

	p := Page{
		PageName: "admin_concert",
		Title:    "View One Controller: " + id,
	}

	common.Templates = template.Must(template.ParseFiles("templates/concert/adminViewOne.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func editHandler(rw http.ResponseWriter, req *http.Request) {
	params := mux.Vars(req)
	id := params["id"]

	type Page struct {
		PageName string
		Title    string
	}

	p := Page{
		PageName: "retailer",
		Title:    "Edit Controller: " + id,
	}

	common.Templates = template.Must(template.ParseFiles("templates/retailer/edit.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func adminViewAllHandler(rw http.ResponseWriter, req *http.Request) {
	type Page struct {
		PageName string
		Title    string
		Concerts []Concert
	}

	concerts := FindAll()

	p := Page{
		PageName: "admin_concert",
		Title:    "View All Concerts",
		Concerts: concerts,
	}

	common.Templates = template.Must(template.ParseFiles("templates/concert/adminViewAll.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func viewAllHandler(rw http.ResponseWriter, req *http.Request) {
	type Page struct {
		PageName  string
		Title     string
		Retailers []Retailer
	}

	retailers := FindAll()

	p := Page{
		PageName:  "retailer",
		Title:     "View All Retailers",
		Retailers: retailers,
	}

	common.Templates = template.Must(template.ParseFiles("templates/retailer/viewAll.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}
func userViewAllHandler(rw http.ResponseWriter, req *http.Request) {
	type Page struct {
		PageName string
		Title    string
		Bands    []BandAndConcertsCount
	}

	bandsWithConcertsCount := FindBandsAndConcerts()

	p := Page{
		PageName: "user_band",
		Title:    "View All Bands",
		Bands:    bandsWithConcertsCount,
	}

	common.Templates = template.Must(template.ParseFiles("templates/band/userViewAll.html", common.LayoutPath))
	err := common.Templates.ExecuteTemplate(rw, "base", p)
	common.CheckError(err)
}