   (:use [clojure.contrib.string :only (substring?)])
 )
 
-(defn gen-edfi
-  [interchange output-file contents]
-  ; (prn output-file)
-  (with-open [out (java.io.OutputStreamWriter. (java.io.FileOutputStream. output-file) "UTF-8")]
-    (emit (element interchange {:xmlns "http://ed-fi.org/0100"} contents) out)
-  )
-)
-
-(defn gen-student [schoolName studentId]
-  (element :Student {:id (format "%s-%s" schoolName (str studentId))}
-    (element :StudentUniqueStateId {} (format "%s-%s" schoolName (str studentId)))
-    (element :Name {}
-      (element :FirstName {} (rand-nth ["Nathan" "Gina" "Alan" "Morena" "Adam" "Jewel" "Sean" "Summer" "Ron"]))
-      (element :LastSurname {} (rand-nth ["Fillion" "Torres" "Tudyk" "Baccarin" "Baldwin" "Staite" "Maher" "Glau" "Glass"]))
-    )
-    (element :Sex {} (rand-nth ["Male" "Female"]))
-    (element :BirthData {}
-      (element :BirthDate {} (str "2001-" (format "%02d" (inc (rand-int 12))) "-" (format "%02d" (inc (rand-int 28)))))
-    )
-    (element :HispanicLatinoEthnicity {} (rand-nth ["true" "false"]))
-    (element :Race {})
-  )
-)
-
-(defn gen-students [schools rng output-file]
-  (gen-edfi :InterchangeStudentParent output-file
-    (into ()
-      [
-        (for [schoolName schools]
-          (for [id rng
-            :let [tmp (gen-student schoolName id)]
-            ]
-            tmp
-          )
-        )
-      ]
-    )
-  )
-)
-
-(defn create-state []
-  (let [tmp (element :StateEducationAgency {:id "NY"}
-    (element :StateOrganizationId {} "NY")
-    (element :NameOfInstitution {} "New York State Board of Education")
-    (element :OrganizationCategories {}
-      (element :OrganizationCategory {} "State Education Agency")
-    )
-    (element :Address {}
-      (element :StreetNumberName {} "123 Street")
-      (element :City {} "Albany")
-      (element :StateAbbreviation {} "NY")
-      (element :PostalCode {} "11011")
-    )
-  )]
-  tmp
-  )
-)
-
-(defn create-district [districtName]
-  (let [tmp (element :LocalEducationAgency {:id districtName}
-    (element :StateOrganizationId {} districtName)
-    (element :NameOfInstitution {} districtName)
-    (element :OrganizationCategories {}
-      (element :OrganizationCategory {} "Local Education Agency")
-    )
-    (element :Address {}
-      (element :StreetNumberName {} "123 Street")
-      (element :City {}  districtName)
-      (element :StateAbbreviation {} "NY")
-      (element :PostalCode {} "11011")
-    )
-    (element :LEACategory {} "Independent")
-    (element :StateEducationAgencyReference {:ref "NY"})
-    )]
-    tmp
-  )
-)
-
-(defn create-school [districtName, schoolName]
-  (let [tmp (element :School {:id schoolName}
-    (element :StateOrganizationId {} schoolName)
-    (element :EducationOrgIdentificationCode {:IdentificationSystem "School"}
-      (element :ID {} schoolName)
-    )
-    (element :NameOfInstitution {} schoolName)
-    (element :OrganizationCategories {}
-      (element :OrganizationCategory {} "School")
-    )
-    (element :Address {:AddressType "Physical"}
-      (element :StreetNumberName {} "123 Street")
-      (element :City {} "Albany")
-      (element :StateAbbreviation {} "NY")
-      (element :PostalCode {} "11011")
-      (element :NameOfCounty {} districtName)
-    )
-    (element :Telephone {:InstitutionTelephoneNumberType "Main"}
-      (element :TelephoneNumber {} "(425)-555-1212" )
-    )
-    (element :GradesOffered {}
-      (element :GradeLevel {} "First grade")
-      (element :GradeLevel {} "Second grade")
-      (element :GradeLevel {} "Third grade")
-      (element :GradeLevel {} "Fourth grade")
-      (element :GradeLevel {} "Fifth grade")
-      (element :GradeLevel {} "Sixth grade")
-    )
-    (element :SchoolCategories {}
-      (element :SchoolCategory {} "Elementary School")
-    )
-    (element :LocalEducationAgencyReference {:ref districtName})
-  )]
-  tmp
-  )
-)
-
-(defn create-courses [districtName]
-  (let [tmp (element :Course {:id (format "Math007-%s" districtName)}
-    (element :CourseTitle {} "Math007")
-    (element :NumberOfParts {} "1")
-    (element :CourseCode {:IdentificationSystem "CSSC course code"}
-        (element :ID {} (format "Math007-%s" districtName))
-    )
-    (element :CourseDescription {} "7th grade math")
-    (element :EducationOrganizationReference {}
-      (element :EducationalOrgIdentity {}
-        (element :StateOrganizationId {} districtName)
-      )
-    )
-    )]
-    tmp
-  )
-)
-
-(defn gen-schools [districtName schools output-file]
-  (gen-edfi :InterchangeEducationOrganization output-file
-    (reverse
-      (into ()
-        [
-          (create-state)
-          (create-district districtName)
-          (for [schoolName schools
-            :let [tmp (create-school districtName schoolName)]]
-            tmp
-          )
-          (create-courses districtName)
-        ]
-      )
-    )
-  )
-)
-
-(defn create-assessment [assessmentName]
-  (let [tmp (element :Assessment {:id "Grade_7_2011_State_Math"}
-      (element :AssessmentTitle {} assessmentName)
-      (element :AssessmentIdentificationCode {:IdentificationSystem "Test Contractor"}
-        (element :ID {} assessmentName)
-      )
-      (element :AssessmentCategory {} "State summative assessment 3-8 general")
-      (element :AcademicSubject {} "Mathematics")
-      (element :GradeLevelAssessed {} "Seventh grade")
-      (element :AssessmentPerformanceLevel {}
-        (element :PerformanceLevel {}
-          (element :CodeValue {} "W")
-        )
-        (element :AssessmentReportingMethod {} "Scale score")
-        (element :MinimumScore {} "6")
-        (element :MaximumScore {} "14")
-      )
-      (element :AssessmentPerformanceLevel {}
-        (element :PerformanceLevel {}
-          (element :CodeValue {} "B")
-        )
-        (element :AssessmentReportingMethod {} "Scale score")
-        (element :MinimumScore {} "15")
-        (element :MaximumScore {} "20")
-      )
-      (element :AssessmentPerformanceLevel {}
-        (element :PerformanceLevel {}
-          (element :CodeValue {} "S")
-        )
-        (element :AssessmentReportingMethod {} "Scale score")
-        (element :MinimumScore {} "21")
-        (element :MaximumScore {} "27")
-      )
-      (element :AssessmentPerformanceLevel {}
-        (element :PerformanceLevel {}
-          (element :CodeValue {} "E")
-        )
-        (element :AssessmentReportingMethod {} "Scale score")
-        (element :MinimumScore {} "28")
-        (element :MaximumScore {} "33")
-      )
-      (element :ContentStandard {} "State Standard")
-      (element :Version {} "1")
-      (element :RevisionDate {} "2011-03-12")
-      (element :MaxRawScore {} "33")
-    )]
-    tmp
-  )
-)
-
-(defn gen-assessment [assessmentName output-file]
-  (gen-edfi :InterchangeAssessmentMetadata output-file (create-assessment assessmentName))
-)
-
-(defn get-perf-level [score]
-  (cond
-    (> 14 score) "W"
-    (> 20 score) "B"
-    (> 27 score) "S"
-    (> 33 score) "E")
-)
-
-(defn student-ref [schoolName studentId]
-  (element :StudentReference {}
-    (element :StudentIdentity {}
-      (element :StudentUniqueStateId {} (format "%s-%s" schoolName (str studentId)))
-    )
-  )
-)
-
-(defn gen-saa [schoolName studentId assessmentName date]
-  (let [score (rand-nth (range 6 33))]
-    (element :StudentAssessment {:id (format "SAA-%s-%s-%s" schoolName (str studentId) date)}
-      (element :AdministrationDate {} date)
-      (element :AdministrationEndDate {} date)
-      (element :SerialNumber {} "2")
-      (element :ScoreResults {:AssessmentReportingMethod "Scale score"}
-        (element :Result {} (str score))
-      )
-      (element :PerformanceLevels {}
-        (element :CodeValue {} (get-perf-level score))
-      )
-      (student-ref schoolName studentId)
-      (element :AssessmentReference {}
-        (element :AssessmentIdentity {}
-          (element :AssessmentIdentificationCode {:IdentificationSystem "Test Contractor"}
-            (element :ID {} assessmentName)
-          )
-        )
-      )
-    )
-  )
-)
-
-(defn gen-saas
-  [districtName schools students assessment n output-file]
-  (gen-edfi :InterchangeStudentAssessment output-file
-    (for [schoolName schools]
-      (for [studentId students, i (range 1 n)]
-        (gen-saa schoolName studentId assessment (str "2011-10-" (format "%02d" i)))
-      )
-    )
-  )
-)
-
-(defn gen-enroll
-  [schoolName studentId]
-  (element :StudentSchoolAssociation {}
-    (student-ref schoolName studentId)
-    (element :SchoolReference {}
-      (element :EducationalOrgIdentity {}
-        (element :StateOrganizationId {} schoolName)
-      )
-    )
-    (element :EntryDate {} "2011-09-01")
-    (element :EntryGradeLevel {} "Seventh grade")
-  )
-)
-
-(defn gen-section-assoc
-  [schoolName studentId]
-  (element :StudentSectionAssociation {}
-    (student-ref schoolName studentId)
-    (element :SectionReference {}
-      (element :SectionIdentity {}
-        (element :StateOrganizationId {} schoolName)
-        (element :UniqueSectionCode {}  (format "%s-Math-7-2011-Sec2" schoolName))
-      )
-    )
-    (element :BeginDate {} "2011-09-06")
-    (element :EndDate {} "2011-12-16")
-  )
-)
-
-(defn enroll [schoolName studentId]
-  (into () [
-    (gen-enroll schoolName studentId)
-    (gen-section-assoc schoolName studentId) ]
-  )
-)
-
-(defn gen-enrollments [schools rng output-file]
-  (gen-edfi :InterchangeStudentEnrollment output-file
-    (for [schoolName schools]
-      (for [id rng]
-        (enroll schoolName id)
-      )
-    )
-  )
-)
-
-(defn create-session [districtName schoolName]
-  (into () [
-    (element :CalendarDate {:id (format "%s-%s-day" districtName schoolName) }
-      (element :Date {} "2011-09-22")
-      (element :CalendarEvent {} "Instructional day")
-    )
-
-    (element :GradingPeriod {:id (format "%s-%s-GP1" districtName schoolName)}
-      (element :GradingPeriodIdentity {}
-        (element :GradingPeriod {} "End of Year")
-        (element :SchoolYear {} "2011-2012")
-        (element :StateOrganizationId {} districtName)
-      )
-
-      (element :BeginDate {} "2011-09-01")
-      (element :EndDate {} "2011-12-01")
-      (element :TotalInstructionalDays {} "90")
-      (element :CalendarDateReference {:ref (format "%s-%s-day" districtName schoolName)})
-    )
-
-    (element :Session {}
-      (element :SessionName {} (format "%s-%s-Fall-2011" districtName schoolName))
-      (element :SchoolYear {} "2011-2012")
-      (element :Term {} "Fall Semester")
-      (element :BeginDate {} "2011-09-06")
-      (element :EndDate {} "2011-12-16")
-      (element :TotalInstructionalDays {} "75")
-      (element :EducationOrganizationReference {}
-        (element :EducationalOrgIdentity {}
-          (element :StateOrganizationId {} schoolName)
-        )
-      )
-      (element :GradingPeriodReference {:ref (format "%s-%s-GP1" districtName schoolName)})
-      (element :CalendarDateReference {:ref (format "%s-%s-day" districtName schoolName)})
-    ) ]
-  )
-)
-
-(defn gen-sessions [districtName schools output-file]
-  (gen-edfi :InterchangeEducationOrgCalendar output-file
-    (for [schoolName schools]
-      (reverse (create-session districtName schoolName))
-    )
-  )
-)
-
-(defn create-section [districtName schoolName]
-  (into () [
-    (element :CourseOffering {}
-      (element :LocalCourseCode {} (format "%s-%s-Math-7" districtName schoolName))
-      (element :LocalCourseTitle {} "7th Grade Math")
-      (element :SchoolReference {}
-        (element :EducationalOrgIdentity {}
-          (element :StateOrganizationId {} schoolName)
-        )
-      )
-      (element :SessionReference {}
-        (element :SessionIdentity {}
-          (element :SessionName {} (format "%s-%s-Fall-2011" districtName schoolName))
-        )
-      )
-      (element :CourseReference {}
-        (element :CourseIdentity {}
-          (element :CourseCode {:IdentificationSystem "CSSC course code"}
-            (element :ID {} (format "Math007-%s" districtName))
-          )
-        )
-      )
-    )
-
-    (element :Section {}
-      (element :UniqueSectionCode {} (format "%s-%s-Math-7-2011-Sec2" districtName schoolName))
-      (element :SequenceOfCourse {} "1")
-      (element :CourseOfferingReference {}
-        (element :CourseOfferingIdentity {}
-          (element :LocalCourseCode {} (format "%s-%s-Math-7" districtName schoolName))
-          (element :CourseCode {:IdentificationSystem "CSSC course code"}
-            (element :ID {} (format "Math-7-%s" districtName))
-          )
-          (element :Term {} "Fall Semester")
-          (element :SchoolYear {} "2011-2012")
-          (element :StateOrganizationId {} schoolName)
-        )
-      )
-      (element :SchoolReference {}
-        (element :EducationalOrgIdentity {}
-          (element :StateOrganizationId {} schoolName)
-        )
-      )
-      (element :SessionReference {}
-        (element :SessionIdentity {}
-          (element :SessionName {} (format "%s-%s-Fall-2011" districtName schoolName))
-        )
-      )
-    ) ]
-  )
-)
-
-(defn gen-sections [districtName schools output-file]
-  (gen-edfi :InterchangeMasterSchedule output-file
-    (for [schoolName schools]
-      (reverse (create-section districtName schoolName))
-    )
-  )
-)
-
+(def first-names
+  ["James","John","Robert","Michael","William","David","Richard","Charles","Joseph","Thomas","Christopher","Daniel","Paul","Mark",
+   "Donald","George","Kenneth","Steven","Edward","Brian","Ronald","Anthony","Kevin","Jason","Matthew","Gary","Timothy","Jose","Larry",
+   "Jeffrey","Frank","Scott","Eric","Stephen","Andrew","Raymond","Gregory","Joshua","Jerry","Dennis","Walter","Patrick","Peter",
+   "Harold","Douglas","Henry","Carl","Arthur","Ryan","Roger","Joe","Juan","Jack","Albert","Jonathan","Justin","Terry","Gerald","Keith",
+   "Samuel","Willie","Ralph","Lawrence","Nicholas","Roy","Benjamin","Bruce","Brandon","Adam","Harry","Fred","Wayne","Billy","Steve",
+   "Louis","Jeremy","Aaron","Randy","Howard","Eugene","Carlos","Russell","Bobby","Victor","Martin","Ernest","Phillip","Todd","Jesse",
+   "Craig","Alan","Shawn","Clarence","Sean","Philip","Chris","Johnny","Earl","Jimmy","Antonio","Danny","Bryan","Tony","Luis","Mike",
+   "Stanley","Leonard","Nathan","Dale","Manuel","Rodney","Curtis","Norman","Allen","Marvin","Vincent","Glenn","Jeffery","Travis",
+   "Jeff","Chad","Jacob","Lee","Melvin","Alfred","Kyle","Francis","Bradley","Jesus","Herbert","Frederick","Ray","Joel","Edwin","Don",
+   "Eddie","Ricky","Troy","Randall","Barry","Alexander","Bernard","Mario","Leroy","Francisco","Marcus","Micheal","Theodore",
+   "Clifford","Miguel","Oscar","Jay","Jim","Tom","Calvin","Alex","Jon","Ronnie","Bill","Lloyd","Tommy","Leon","Derek","Warren","Darrell",
+   "Jerome","Floyd","Leo","Alvin","Tim","Wesley","Gordon","Dean","Greg","Jorge","Dustin","Pedro","Derrick","Dan","Lewis","Zachary",
+   "Corey","Herman","Maurice","Vernon","Roberto","Clyde","Glen","Hector","Shane","Ricardo","Sam","Rick","Lester","Brent","Ramon",
+   "Charlie","Tyler","Gilbert","Gene","Marc","Reginald","Ruben","Brett","Angel","Nathaniel","Rafael","Leslie","Edgar","Milton","Raul",
+   "Ben","Chester","Cecil","Duane","Franklin","Andre","Elmer","Brad","Gabriel","Ron","Mitchell","Roland","Arnold","Harvey","Jared",
+   "Adrian","Karl","Cory","Claude","Erik","Darryl","Jamie","Neil","Jessie","Christian","Javier","Fernando","Clinton","Ted","Mathew",
+   "Tyrone","Darren","Lonnie","Lance","Cody","Julio","Kelly","Kurt","Allan","Nelson","Guy","Clayton","Hugh","Max","Dwayne","Dwight",
+   "Armando","Felix","Jimmie","Everett","Jordan","Ian","Wallace","Ken","Bob","Jaime","Casey","Alfredo","Alberto","Dave","Ivan",
+   "Johnnie","Sidney","Byron","Julian","Isaac","Morris","Clifton","Willard","Daryl","Ross","Virgil","Andy","Marshall","Salvador",
+   "Perry","Kirk","Sergio","Marion","Tracy","Seth","Kent","Terrance","Rene","Eduardo","Terrence","Enrique","Freddie","Wade"]
+)
+
+(def last-names
+  ["Sears","Mayo","Dunlap","Hayden","Wilder","Mckay","Coffey","Mccarty","Ewing","Cooley","Vaughan","Bonner","Cotton","Holder","Stark",
+   "Ferrell","Cantrell","Fulton","Lynn","Lott","Calderon","Rosa","Pollard","Hooper","Burch","Mullen","Fry","Riddle","Levy","David",
+   "Duke","Odonnell","Guy","Michael","Britt","Frederick","Daugherty","Berger","Dillard","Alston","Jarvis","Frye","Riggs","Chaney",
+   "Odom","Duffy","Fitzpatrick","Valenzuela","Merrill","Mayer","Alford","Mcpherson","Acevedo","Donovan","Barrera","Albert","Cote",
+   "Reilly","Compton","Raymond","Mooney","Mcgowan","Craft","Cleveland","Clemons","Wynn","Nielsen","Baird","Stanton","Snider",
+   "Rosales","Bright","Witt","Stuart","Hays","Holden","Rutledge","Kinney","Clements","Castaneda","Slater","Hahn","Emerson","Conrad",
+   "Burks","Delaney","Pate","Lancaster","Sweet","Justice","Tyson","Sharpe","Whitfield","Talley","Macias","Irwin","Burris","Ratliff",
+   "Mccray","Madden","Kaufman","Beach","Goff","Cash","Bolton","Mcfadden","Levine","Good","Byers","Kirkland","Kidd","Workman","Carney",
+   "Dale","Mcleod","Holcomb","England","Finch","Head","Burt","Hendrix","Sosa","Haney","Franks","Sargent","Nieves","Downs","Rasmussen",
+   "Bird","Hewitt","Lindsay","Le","Foreman","Valencia","Oneil","Delacruz","Vinson","Dejesus","Hyde","Forbes","Gilliam","Guthrie",
+   "Wooten","Huber","Barlow","Boyle","Mcmahon","Buckner","Rocha"]
+)
 
 (def districts
     ["Abbott","Addison","Adirondack","Afton","Akron","Albany-City","Albion","Alden","Alexander","Alexandria","Alfred",


(defn gen-big-data
  [districtCount schoolCount studentCount]
  (def sectionName "7th Grade Math - Sec 2")
  (def assessmentName "Grade 7 State Math")
  (def i (make-counter 0))
  ;(def i (atom 0))

     "Ossining","Oswego","Oswego-City","Otego-Unadilla","Otsego-Delaw","Owego-Apalachin",
     "Panama","Parishville","Patchogue","Pavilion","Pawling","Pearl-River","Peekskill","Poland",
     "Randolph","Raquette","Ravena","Red-Creek","Red-Hook","Remsen","Remsenburg",
     "Salem","Salmon","Sandy-Creek","Saranac","Saranac-Lake","Saratoga-Springs","Saugerties","Sauquoit-Valley" ]
 )

(defn school-id [i j]
  (format "PS-%s" (str (+ i j)))
)

(defn student-id [schoolName studentId]
  (format "%s-%s" schoolName (str studentId))
)

(defn course-id [districtName]
  (format "Math007-%s" districtName)
)

(defn assessment-id [assessmentName]
  (str "Grade_7_2011_State_Math")
)

(defn saa-id [schoolName studentId date]
  (format "SAA-%s-%s-%s" schoolName (str studentId) date)
)

(defn section-id [schoolName]
  (format "%s-Math007-S2" schoolName)
)

(defn calendar-date-id [schoolName]
  (format "%s-day" schoolName)
)

(defn grading-period-id [schoolName]
  (format "%s-GP1" schoolName)
)

(defn session-id [schoolName]
  (format "%s-Fall-2011" schoolName)
)

(defn local-course-id [schoolName]
  (format "%s-Math007" schoolName)
)

(defn student-ref [schoolName studentId]
  (element :StudentReference {}
    (element :StudentIdentity {}
      (element :StudentUniqueStateId {} (student-id schoolName studentId))
    )
  )
)

(defn school-ref [schoolName]
  (element :SchoolReference {}
    (element :EducationalOrgIdentity {}
      (element :StateOrganizationId {} schoolName)
    )
  )
)

(defn ed-org-ref [edOrgName]
  (element :EducationalOrgIdentity {}
    (element :StateOrganizationId {} edOrgName)
  )
)

(defn section-ref [schoolName]
  (element :SectionReference {}
    (element :SectionIdentity {}
      (element :StateOrganizationId {} schoolName)
      (element :UniqueSectionCode {}  (section-id schoolName))
    )
  )
)

(defn gen-edfi
  [interchange output-file contents]
  ; (prn output-file)
  (with-open [out (java.io.OutputStreamWriter. (java.io.FileOutputStream. output-file) "UTF-8")]
    (emit (element interchange {:xmlns "http://ed-fi.org/0100"} contents) out)
  )
)

(defn gen-student [schoolName studentId]
  (element :Student {:id (student-id schoolName studentId)}
    (element :StudentUniqueStateId {} (student-id schoolName studentId))
    (element :Name {}
      (element :FirstName {} (rand-nth first-names))
      (element :LastSurname {} (rand-nth last-names))
    )
    (element :Sex {} (rand-nth ["Male" "Female"]))
    (element :BirthData {}
      (element :BirthDate {} (str "2001-" (format "%02d" (inc (rand-int 12))) "-" (format "%02d" (inc (rand-int 28)))))
    )
    (element :HispanicLatinoEthnicity {} (rand-nth ["true" "false"]))
    (element :Race {})
  )
)

(defn gen-students [schools rng output-file]
  (gen-edfi :InterchangeStudentParent output-file
    (into ()
      [
        (for [schoolName schools]
          (for [id rng
            :let [tmp (gen-student schoolName id)]
            ]
            tmp
          )
        )
      ]
    )
  )
)

(defn create-state []
  (let [tmp (element :StateEducationAgency {:id "NY"}
    (element :StateOrganizationId {} "NY")
    (element :NameOfInstitution {} "New York State Board of Education")
    (element :OrganizationCategories {}
      (element :OrganizationCategory {} "State Education Agency")
    )
    (element :Address {}
      (element :StreetNumberName {} "123 Street")
      (element :City {} "Albany")
      (element :StateAbbreviation {} "NY")
      (element :PostalCode {} "11011")
    )
  )]
  tmp
  )
)

(defn create-district [districtName]
  (let [tmp (element :LocalEducationAgency {:id districtName}
    (element :StateOrganizationId {} districtName)
    (element :NameOfInstitution {} districtName)
    (element :OrganizationCategories {}
      (element :OrganizationCategory {} "Local Education Agency")
    )
    (element :Address {}
      (element :StreetNumberName {} "123 Street")
      (element :City {}  districtName)
      (element :StateAbbreviation {} "NY")
      (element :PostalCode {} "11011")
    )
    (element :LEACategory {} "Independent")
    (element :StateEducationAgencyReference {:ref "NY"})
    )]
    tmp
  )
)

(defn create-school [districtName, schoolName]
  (let [tmp (element :School {:id schoolName}
    (element :StateOrganizationId {} schoolName)
    (element :EducationOrgIdentificationCode {:IdentificationSystem "School"}
      (element :ID {} schoolName)
    )
    (element :NameOfInstitution {} schoolName)
    (element :OrganizationCategories {}
      (element :OrganizationCategory {} "School")
    )
    (element :Address {:AddressType "Physical"}
      (element :StreetNumberName {} "123 Street")
      (element :City {} "Albany")
      (element :StateAbbreviation {} "NY")
      (element :PostalCode {} "11011")
      (element :NameOfCounty {} districtName)
    )
    (element :Telephone {:InstitutionTelephoneNumberType "Main"}
      (element :TelephoneNumber {} "(425)-555-1212" )
    )
    (element :GradesOffered {}
      (element :GradeLevel {} "First grade")
      (element :GradeLevel {} "Second grade")
      (element :GradeLevel {} "Third grade")
      (element :GradeLevel {} "Fourth grade")
      (element :GradeLevel {} "Fifth grade")
      (element :GradeLevel {} "Sixth grade")
    )
    (element :SchoolCategories {}
      (element :SchoolCategory {} "Elementary School")
    )
    (element :LocalEducationAgencyReference {:ref districtName})
  )]
  tmp
  )
)

(defn create-courses [districtName]
  (let [tmp (element :Course {:id (course-id districtName)}
    (element :CourseTitle {} "Math 7")
    (element :NumberOfParts {} "1")
    (element :CourseCode {:IdentificationSystem "CSSC course code"}
        (element :ID {} (course-id districtName))
    )
    (element :CourseDescription {} "7th grade math")
    (element :EducationOrganizationReference {} (ed-org-ref districtName))
    )]
    tmp
  )
)

(defn gen-schools [districtName schools output-file]
  (gen-edfi :InterchangeEducationOrganization output-file
    (reverse
      (into ()
        [
          (create-state)
          (create-district districtName)
          (for [schoolName schools
            :let [tmp (create-school districtName schoolName)]]
            tmp
          )
          (create-courses districtName)
        ]
      )
    )
  )
)

(defn create-assessment [assessmentName]
  (let [tmp (element :Assessment {:id (assessment-id assessmentName)}
      (element :AssessmentTitle {} assessmentName)
      (element :AssessmentIdentificationCode {:IdentificationSystem "Test Contractor"}
        (element :ID {} assessmentName)
      )
      (element :AssessmentCategory {} "State summative assessment 3-8 general")
      (element :AcademicSubject {} "Mathematics")
      (element :GradeLevelAssessed {} "Seventh grade")
      (element :AssessmentPerformanceLevel {}
        (element :PerformanceLevel {}
          (element :CodeValue {} "W")
        )
        (element :AssessmentReportingMethod {} "Scale score")
        (element :MinimumScore {} "6")
        (element :MaximumScore {} "14")
      )
      (element :AssessmentPerformanceLevel {}
        (element :PerformanceLevel {}
          (element :CodeValue {} "B")
        )
        (element :AssessmentReportingMethod {} "Scale score")
        (element :MinimumScore {} "15")
        (element :MaximumScore {} "20")
      )
      (element :AssessmentPerformanceLevel {}
        (element :PerformanceLevel {}
          (element :CodeValue {} "S")
        )
        (element :AssessmentReportingMethod {} "Scale score")
        (element :MinimumScore {} "21")
        (element :MaximumScore {} "27")
      )
      (element :AssessmentPerformanceLevel {}
        (element :PerformanceLevel {}
          (element :CodeValue {} "E")
        )
        (element :AssessmentReportingMethod {} "Scale score")
        (element :MinimumScore {} "28")
        (element :MaximumScore {} "33")
      )
      (element :ContentStandard {} "State Standard")
      (element :Version {} "1")
      (element :RevisionDate {} "2011-03-12")
      (element :MaxRawScore {} "33")
    )]
    tmp
  )
)

(defn gen-assessment [assessmentName output-file]
  (gen-edfi :InterchangeAssessmentMetadata output-file (create-assessment assessmentName))
)

(defn get-perf-level [score]
  (cond
    (> 14 score) "W"
    (> 20 score) "B"
    (> 27 score) "S"
    (> 33 score) "E")
)

(defn gen-saa [schoolName studentId assessmentName date]
  (let [score (rand-nth (range 6 33))]
    (element :StudentAssessment {:id (saa-id schoolName studentId date)}
      (element :AdministrationDate {} date)
      (element :AdministrationEndDate {} date)
      (element :SerialNumber {} "2")
      (element :ScoreResults {:AssessmentReportingMethod "Scale score"}
        (element :Result {} (str score))
      )
      (element :PerformanceLevels {}
        (element :CodeValue {} (get-perf-level score))
      )
      (student-ref schoolName studentId)
      (element :AssessmentReference {}
        (element :AssessmentIdentity {}
          (element :AssessmentIdentificationCode {:IdentificationSystem "Test Contractor"}
            (element :ID {} assessmentName)
          )
        )
      )
    )
  )
)

(defn gen-saas
  [districtName schools students assessment n output-file]
  (gen-edfi :InterchangeStudentAssessment output-file
    (for [schoolName schools]
      (for [studentId students, i (range 1 n)]
        (gen-saa schoolName studentId assessment (str "2011-10-" (format "%02d" i)))
      )
    )
  )
)

(defn gen-enroll
  [schoolName studentId]
  (element :StudentSchoolAssociation {}
    (student-ref schoolName studentId)
    (school-ref schoolName)
    (element :EntryDate {} "2011-09-01")
    (element :EntryGradeLevel {} "Seventh grade")
  )
)

(defn gen-section-assoc
  [schoolName studentId]
  (element :StudentSectionAssociation {}
    (student-ref schoolName studentId)
    (section-ref schoolName)
    (element :BeginDate {} "2011-09-06")
    (element :EndDate {} "2011-12-16")
  )
)

(defn enroll [schoolName studentId]
  (into () [
    (gen-enroll schoolName studentId)
    (gen-section-assoc schoolName studentId) ]
  )
)

(defn gen-enrollments [schools rng output-file]
  (gen-edfi :InterchangeStudentEnrollment output-file
    (for [schoolName schools]
      (for [id rng]
        (enroll schoolName id)
      )
    )
  )
)


(defn create-session [districtName schoolName]
  (into () [
    (element :CalendarDate {:id (calendar-date-id schoolName) }
      (element :Date {} "2011-09-22")
      (element :CalendarEvent {} "Instructional day")
    )

    (element :GradingPeriod {:id (grading-period-id schoolName)}
      (element :GradingPeriodIdentity {}
        (element :GradingPeriod {} "End of Year")
        (element :SchoolYear {} "2011-2012")
        (element :StateOrganizationId {} districtName)
      )

      (element :BeginDate {} "2011-09-01")
      (element :EndDate {} "2011-12-01")
      (element :TotalInstructionalDays {} "90")
      (element :CalendarDateReference {:ref (calendar-date-id schoolName)})
    )

    (element :Session {}
      (element :SessionName {} (session-id schoolName))
      (element :SchoolYear {} "2011-2012")
      (element :Term {} "Fall Semester")
      (element :BeginDate {} "2011-09-06")
      (element :EndDate {} "2011-12-16")
      (element :TotalInstructionalDays {} "75")
      (element :EducationOrganizationReference {} (ed-org-ref schoolName))
      (element :GradingPeriodReference {:ref (grading-period-id schoolName)})
      (element :CalendarDateReference {:ref (calendar-date-id schoolName)})
    ) ]
  )
)

(defn gen-sessions [districtName schools output-file]
  (gen-edfi :InterchangeEducationOrgCalendar output-file
    (for [schoolName schools]
      (reverse (create-session districtName schoolName))
    )
  )
)

(defn create-section [districtName schoolName]
  (into () [
    (element :CourseOffering {}
      (element :LocalCourseCode {} (local-course-id schoolName))
      (element :LocalCourseTitle {} "7th Grade Math")
      (element :SchoolReference {}
        (element :EducationalOrgIdentity {}
          (element :StateOrganizationId {} schoolName)
        )
      )
      (element :SessionReference {}
        (element :SessionIdentity {}
          (element :SessionName {} (session-id schoolName))
        )
      )
      (element :CourseReference {}
        (element :CourseIdentity {}
          (element :CourseCode {:IdentificationSystem "CSSC course code"}
            (element :ID {} (course-id districtName))
          )
        )
      )
    )

    (element :Section {}
      (element :UniqueSectionCode {} (section-id schoolName))
      (element :SequenceOfCourse {} "1")
      (element :CourseOfferingReference {}
        (element :CourseOfferingIdentity {}
          (element :LocalCourseCode {} (local-course-id schoolName))
          (element :CourseCode {:IdentificationSystem "CSSC course code"}
            (element :ID {} (course-id districtName))
          )
          (element :Term {} "Fall Semester")
          (element :SchoolYear {} "2011-2012")
          (element :StateOrganizationId {} schoolName)
        )
      )
      (element :SchoolReference {}
        (element :EducationalOrgIdentity {}
          (element :StateOrganizationId {} schoolName)
        )
      )
      (element :SessionReference {}
        (element :SessionIdentity {}
          (element :SessionName {} (session-id schoolName))
        )
      )
    ) ]
  )
)

(defn gen-sections [districtName schools output-file]
  (gen-edfi :InterchangeMasterSchedule output-file
    (for [schoolName schools]
      (reverse (create-section districtName schoolName))
    )
  )
)

(defn gen-district-schools [districtCount schoolsPerDistrict studentsPerSchool]
  ; should distribute this in a more normal distribution
  (for [i (range 1 (+ districtCount 1))
    :let [r (assoc (hash-map) (districts i)
      (for [j (range 1 (+ 1 schoolsPerDistrict))]
        (school-id i j)))]]
   r)
)

