# Path: annotation_tool/models.py
# class Project(models.Model):
#     name = models.CharField(max_length=50, unique=True)
#     creation_date = models.DateTimeField('creation date')
#     overlap = models.BooleanField(default=False)
# 
#     def __str__(self):
#         return str(self.name)
# 
# class Class(models.Model):
#     name = models.CharField(max_length=50, unique=True)
# 
#     class Meta:
#         ordering = ('name',)
# 
#     def __str__(self):
#         return str(self.name)
# 
# class Wav(models.Model):
#     project = models.ForeignKey('Project', on_delete=models.CASCADE)
#     file = models.FileField(
#         upload_to=get_wav_file_path,
#         max_length=500)
#     name = models.CharField(max_length=1000)
#     upload_date = models.DateTimeField('upload date')
# 
#     def __str__(self):
#         return str(self.name)
# 
# class Segment(models.Model):
#     wav = models.ForeignKey('Wav', on_delete=models.CASCADE)
#     start_time = models.FloatField()
#     end_time = models.FloatField()
#     name = models.CharField(max_length=1000)
#     priority = models.FloatField(default=2.0)
#     reliable = models.BooleanField(default=False)
# 
#     def get_project(self):
#         return self.wav.project
# 
#     def __str__(self):
#         return str(self.start_time) + '_' + str(self.end_time)
# 
# class Annotation(models.Model):
#     FINISHED = 'finished'
#     UNFINISHED = 'unfinished'
#     STATUS_CHOICES = (
#         (FINISHED, FINISHED),
#         (UNFINISHED, UNFINISHED)
#     )
#     segment = models.ForeignKey('Segment', on_delete=models.CASCADE)
#     user = models.ForeignKey(User, on_delete=models.CASCADE)
#     name = models.CharField(max_length=1000)
#     annotation_date = models.DateTimeField('annotation date')
#     status = models.CharField(max_length=10, default=UNFINISHED, choices=STATUS_CHOICES)
# 
#     def get_project(self):
#         return self.segment.wav.project
# 
#     class Meta:
#         unique_together = ("segment", "user")
# 
#     def __str__(self):
#         return str(self.name)
# 
# class Event(models.Model):
#     annotation = models.ForeignKey('Annotation', on_delete=models.CASCADE)
#     event_class = models.ForeignKey('Class', null=True,
#                                     on_delete=models.CASCADE)
#     start_time = models.FloatField()
#     end_time = models.FloatField()
#     color = models.CharField(max_length=50, blank=True)
#     tags = models.ManyToManyField('Tag', blank=True)
# 
#     def get_project(self):
#         return self.annotation.get_project()
# 
#     class Meta:
#         unique_together = ("annotation", "event_class", "start_time",
#                            "end_time")
# 
#     def __str__(self):
#         return str(self.id)
# 
# class Region(models.Model):
#     annotation = models.ForeignKey('Annotation', on_delete=models.CASCADE)
#     start_time = models.FloatField()
#     end_time = models.FloatField()
#     color = models.CharField(max_length=50, blank=True)
#     tags = models.ManyToManyField('Tag', blank=True)
# 
#     def get_project(self):
#         return self.annotation.get_project()
# 
#     class Meta:
#         unique_together = ("annotation", "start_time", "end_time")
# 
#     def __str__(self):
#         return str(self.id)
# 
# class ClassProminence(models.Model):
#     VERY_LOW = 1
#     LOW = 2
#     MID = 3
#     LOUD = 4
#     VERY_LOUD = 5
#     PROMINENCE_CHOICES = (
#         (VERY_LOW, ''),
#         (LOW, ''),
#         (MID, ''),
#         (LOUD, ''),
#         (VERY_LOUD, 'Most salient')
#     )
#     region = models.ForeignKey(Region, related_name='classes')
#     class_obj = models.ForeignKey('Class')
#     prominence = models.PositiveSmallIntegerField(choices=PROMINENCE_CHOICES, blank=True, null=True)
# 
#     def __str__(self):
#         return self.class_obj.name
# 
#     class Meta:
#         ordering = ('class_obj__name',)
# 
# class Tag(models.Model):
#     name = models.CharField(unique=True, max_length=50)
# 
#     @staticmethod
#     def get_tag_names():
#         return Tag.objects.values_list('name', flat=True)
# 
#     def __str__(self):
#         return str(self.name)
# 
# Path: config/settings/common.py
# BASE_DIR = str(ROOT_DIR)
# 
# MEDIA_ROOT = str(ROOT_DIR('media'))


import os
import shutil
import numpy as np
import contextlib
import wave
import csv
import subprocess
import django.core.exceptions as e
from math import ceil, floor
from scipy.io.wavfile import read
from scipy.io.wavfile import write
from django.utils import timezone
from intervaltree import IntervalTree
from django.core.files import File
from annotation_tool.models import Project, Class, Wav, Segment, Annotation, Event, Region, ClassProminence, Tag
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from config.settings.common import BASE_DIR, MEDIA_ROOT
from tqdm import tqdm


def create_project(name, creation_date):
    p = Project(name=name, creation_date=creation_date)
    p.save()


def delete_project(name):
    p = Project.objects.get(name=name)
    p.delete()


def get_project(name):
    try:
        p = Project.objects.get(name=name)
    except:
        raise e.ObjectDoesNotExist("Project '%s' does not exist. Create it first." % project_name)

    return p


def create_wav(project, file, name, upload_date):

# Path: annotation_tool/models.py
# class Project(models.Model):
#     name = models.CharField(max_length=50, unique=True)
#     creation_date = models.DateTimeField('creation date')
#     overlap = models.BooleanField(default=False)
# 
#     def __str__(self):
#         return str(self.name)
# 
# class Class(models.Model):
#     name = models.CharField(max_length=50, unique=True)
# 
#     class Meta:
#         ordering = ('name',)
# 
#     def __str__(self):
#         return str(self.name)
# 
# class Wav(models.Model):
#     project = models.ForeignKey('Project', on_delete=models.CASCADE)
#     file = models.FileField(
#         upload_to=get_wav_file_path,
#         max_length=500)
#     name = models.CharField(max_length=1000)
#     upload_date = models.DateTimeField('upload date')
# 
#     def __str__(self):
#         return str(self.name)
# 
# class Segment(models.Model):
#     wav = models.ForeignKey('Wav', on_delete=models.CASCADE)
#     start_time = models.FloatField()
#     end_time = models.FloatField()
#     name = models.CharField(max_length=1000)
#     priority = models.FloatField(default=2.0)
#     reliable = models.BooleanField(default=False)
# 
#     def get_project(self):
#         return self.wav.project
# 
#     def __str__(self):
#         return str(self.start_time) + '_' + str(self.end_time)
# 
# class Annotation(models.Model):
#     FINISHED = 'finished'
#     UNFINISHED = 'unfinished'
#     STATUS_CHOICES = (
#         (FINISHED, FINISHED),
#         (UNFINISHED, UNFINISHED)
#     )
#     segment = models.ForeignKey('Segment', on_delete=models.CASCADE)
#     user = models.ForeignKey(User, on_delete=models.CASCADE)
#     name = models.CharField(max_length=1000)
#     annotation_date = models.DateTimeField('annotation date')
#     status = models.CharField(max_length=10, default=UNFINISHED, choices=STATUS_CHOICES)
# 
#     def get_project(self):
#         return self.segment.wav.project
# 
#     class Meta:
#         unique_together = ("segment", "user")
# 
#     def __str__(self):
#         return str(self.name)
# 
# class Event(models.Model):
#     annotation = models.ForeignKey('Annotation', on_delete=models.CASCADE)
#     event_class = models.ForeignKey('Class', null=True,
#                                     on_delete=models.CASCADE)
#     start_time = models.FloatField()
#     end_time = models.FloatField()
#     color = models.CharField(max_length=50, blank=True)
#     tags = models.ManyToManyField('Tag', blank=True)
# 
#     def get_project(self):
#         return self.annotation.get_project()
# 
#     class Meta:
#         unique_together = ("annotation", "event_class", "start_time",
#                            "end_time")
# 
#     def __str__(self):
#         return str(self.id)
# 
# class Region(models.Model):
#     annotation = models.ForeignKey('Annotation', on_delete=models.CASCADE)
#     start_time = models.FloatField()
#     end_time = models.FloatField()
#     color = models.CharField(max_length=50, blank=True)
#     tags = models.ManyToManyField('Tag', blank=True)
# 
#     def get_project(self):
#         return self.annotation.get_project()
# 
#     class Meta:
#         unique_together = ("annotation", "start_time", "end_time")
# 
#     def __str__(self):
#         return str(self.id)
# 
# class ClassProminence(models.Model):
#     VERY_LOW = 1
#     LOW = 2
#     MID = 3
#     LOUD = 4
#     VERY_LOUD = 5
#     PROMINENCE_CHOICES = (
#         (VERY_LOW, ''),
#         (LOW, ''),
#         (MID, ''),
#         (LOUD, ''),
#         (VERY_LOUD, 'Most salient')
#     )
#     region = models.ForeignKey(Region, related_name='classes')
#     class_obj = models.ForeignKey('Class')
#     prominence = models.PositiveSmallIntegerField(choices=PROMINENCE_CHOICES, blank=True, null=True)
# 
#     def __str__(self):
#         return self.class_obj.name
# 
#     class Meta:
#         ordering = ('class_obj__name',)
# 
# class Tag(models.Model):
#     name = models.CharField(unique=True, max_length=50)
# 
#     @staticmethod
#     def get_tag_names():
#         return Tag.objects.values_list('name', flat=True)
# 
#     def __str__(self):
#         return str(self.name)
# 
# Path: config/settings/common.py
# BASE_DIR = str(ROOT_DIR)
# 
# MEDIA_ROOT = str(ROOT_DIR('media'))


# Path: annotation_tool/utils.py
import os
import shutil
import numpy as np
import contextlib
import wave
import csv
import subprocess
import django.core.exceptions as e
from math import ceil, floor
from scipy.io.wavfile import read
from scipy.io.wavfile import write
from django.utils import timezone
from intervaltree import IntervalTree
from django.core.files import File
from annotation_tool.models import Project, Class, Wav, Segment, Annotation, Event, Region, ClassProminence, Tag
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from config.settings.common import BASE_DIR, MEDIA_ROOT
from tqdm import tqdm



def create_project(name, creation_date):
    p = Project(name=name, creation_date=creation_date)
    p.save()


def delete_project(name):
    p = Project.objects.get(name=name)
    p.delete()


def get_project(name):
    try:
        p = Project.objects.get(name=name)
    except:
        raise e.ObjectDoesNotExist("Project '%s' does not exist. Create it first." % project_name)

    return p


def create_wav(project, file, name, upload_date):

    w = Wav(project=project, file=file, name=name, upload_date=upload_date)