func main() {

	giftFile := flag.String("g", "", "Gift file")
	subFile := flag.String("s", "", "Submission file")
	quiet := flag.Bool("q", false, "Only print result")
	flag.Parse()

	if *giftFile == "" || *subFile == "" {
		fmt.Println("Error: missing gift or submission file argument")
		os.Exit(1)

	}

	if !*quiet {
		fmt.Println("Using gift file ", *giftFile)
		fmt.Println("Using sub file ", *subFile)
	}

	// LOAD FILES -----------------------------------------------------------
	gifts, err := gift.LoadGifts(*giftFile)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	sub = submission.NewSubmission()
	err = sub.LoadFile(*subFile)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if !*quiet {
		fmt.Println("Read ", len(gifts), " gifts")
		fmt.Println("Read ", sub.NumTrips(), " trips")
	}

	// VALIDATE ------------------------------------------------------------
	if !sub.Validate(&gifts) {
		fmt.Println("Solution is NOT valid")
	}

	// SCORE ---------------------------------------------------------------
	totalWRW := sub.Score(&gifts)
	if !*quiet {
		fmt.Printf("Total WRW ")
	}
	fmt.Printf("%f\n", totalWRW)

}
func Cluster(gifts *map[int]gift.Gift) *submission.Submission {

	// Create SQT
	fmt.Println("Creating SQT....")

	s := sqt.NewSQT()
	for _, g := range *gifts {
		s.AddNode(g.Id, g.Weight, g.Location.Lat, g.Location.Lon)
	}

	// Split the SQT
	fmt.Println("Splitting SQT...")
	s.Split(func(tri *sqt.Triangle) bool {
		retval := false
		if (math.Ceil(tri.Weight/trip.WeightLimit) > 2) || (len(tri.Nodes) > 10) {
			retval = true
		}
		return retval
	})

	// Iterate over triangles and cluster nodes
	fmt.Println("Clustering......")
	sub := submission.NewSubmission()
	tid := 1
	for _, tri := range s.Triangles {

		if tri.NumNodes() == 0 {
			continue
		}

		if len(tri.Nodes) > 0 {

			k := int(math.Ceil(tri.Weight / trip.WeightLimit))
			clusts := kmeans.Cluster(tri.Nodes, k, trip.WeightLimit)

			// Create a trip for each cluster
			for _, clust := range clusts {
				t := trip.TripNew(tid)
				for _, n := range clust {
					t.AddGift(n.Id)
				}
				sub.AddTrip(t)
				tid++
			}
		}
	}

	return sub
}
func Naive(gifts *map[int]gift.Gift) *submission.Submission {

	fmt.Println("Called Naive function")

	s := submission.NewSubmission()
	tid := 1
	for _, g := range *gifts {
		t := trip.TripNew(tid)
		t.AddGift(g.Id)
		s.AddTrip(t)
		tid++
	}

	fmt.Println("Last tid: ", tid)
	return s
}