void VideoListImp::update_meta_view(bool flat_list)
{
    m_metadata_view_flat.clear();
    m_metadata_view_flat.reserve(m_metadata.getList().size());

    m_metadata_view_tree.clear();

    // a big punt on setting the sort key
    // TODO: put this in the DB, half the time in this function is spent
    // doing this.
    for (metadata_list::const_iterator si = m_metadata.getList().begin();
         si != m_metadata.getList().end(); ++si)
    {
        if (!(*si)->HasSortKey())
        {
            VideoMetadata::SortKey skey =
                VideoMetadata::GenerateDefaultSortKey(*(*si), true);
            (*si)->SetSortKey(skey);
        }
    }

    if (flat_list)
    {
        for (metadata_list::const_iterator p = m_metadata.getList().begin();
             p != m_metadata.getList().end(); ++p)
        {
            if (m_video_filter.matches_filter(*(*p)))
            {
                m_metadata_view_flat.push_back(p->get());
            }
        }

        sort_view_data(flat_list);

        for (metadata_view_list::iterator p = m_metadata_view_flat.begin();
             p != m_metadata_view_flat.end(); ++p)
        {
            m_metadata_view_tree.addEntry(new meta_data_node(*p));
        }
    }
    else
    {
        m_metadata_view_tree.setPath(m_metadata_tree.getPath());
        m_metadata_view_tree.setName(m_metadata_tree.getName());
        copy_filtered_tree(m_metadata_view_tree, m_metadata_tree,
                           m_video_filter);

        sort_view_data(flat_list);

        tree_view_to_flat(m_metadata_view_tree, m_metadata_view_flat);
    }
}
void VideoListImp::buildTVList(void)
{
    metadata_list ml;
    VideoMetadataListManager::loadAllFromDatabase(ml);
    m_metadata.setList(ml);

    metadata_view_list mlist;
    mlist.reserve(m_metadata.getList().size());

    back_insert_iterator<metadata_view_list> mli(mlist);
    transform(m_metadata.getList().begin(), m_metadata.getList().end(),
              mli, to_metadata_ptr());

    metadata_path_sort mps(true);
    sort(mlist.begin(), mlist.end(), mps);

    typedef map<QString, meta_dir_node *> group_to_node_map;
    group_to_node_map gtnm;

    meta_dir_node *video_root = &m_metadata_tree;

    smart_dir_node sdn = video_root->addSubDir(QObject::tr("Television"));
    meta_dir_node* television_node = sdn.get();

    smart_dir_node vdn = video_root->addSubDir(QObject::tr("Movies"));
    meta_dir_node* movie_node = vdn.get();

    for (metadata_view_list::iterator p = mlist.begin(); p != mlist.end(); ++p)
    {
        VideoMetadata *data = *p;

        if (((*p)->GetSeason() > 0) || ((*p)->GetEpisode() > 0))
        {
            smart_dir_node sdn = television_node->addSubDir((*p)->GetTitle());
            meta_dir_node* title_node = sdn.get();

            smart_dir_node ssdn = title_node->addSubDir(
                QObject::tr("Season %1").arg((*p)->GetSeason()));
            meta_dir_node* season_node = ssdn.get();

            season_node->addEntry(smart_meta_node(new meta_data_node(data)));
        }
        else
            movie_node->addEntry(smart_meta_node(new meta_data_node(data)));
    }
}
void VideoListImp::buildDbList()
{
    metadata_list ml;
    VideoMetadataListManager::loadAllFromDatabase(ml);
    m_metadata.setList(ml);

    metadata_view_list mlist;
    mlist.reserve(m_metadata.getList().size());

    back_insert_iterator<metadata_view_list> mli(mlist);
    transform(m_metadata.getList().begin(), m_metadata.getList().end(),
              mli, to_metadata_ptr());

//    print_meta_list(mlist);

    metadata_path_sort mps(true);
    sort(mlist.begin(), mlist.end(), mps);

    // TODO: break out the prefix in the DB so this isn't needed
    typedef map<QString, meta_dir_node *> prefix_to_node_map;
    prefix_to_node_map ptnm;

    QStringList dirs = GetVideoDirs();

    if (dirs.isEmpty())
        return;

    QString test_prefix(dirs[0]);

    meta_dir_node *video_root = &m_metadata_tree;
    if (dirs.size() == 1)
    {
        video_root->setPathRoot();
        video_root->setPath(test_prefix);
        video_root->setName("videos");
        ptnm.insert(prefix_to_node_map::value_type(test_prefix, video_root));
    }

    for (metadata_view_list::iterator p = mlist.begin(); p != mlist.end(); ++p)
    {
        AddMetadataToDir(*p, video_root);
    }

//    print_dir_tree(m_metadata_tree); // AEW DEBUG
}
void VideoListImp::buildGroupList(metadata_list_type whence)
{
    metadata_list ml;
    VideoMetadataListManager::loadAllFromDatabase(ml);
    m_metadata.setList(ml);

    metadata_view_list mlist;
    mlist.reserve(m_metadata.getList().size());

    back_insert_iterator<metadata_view_list> mli(mlist);
    transform(m_metadata.getList().begin(), m_metadata.getList().end(),
              mli, to_metadata_ptr());

    metadata_path_sort mps(true);
    sort(mlist.begin(), mlist.end(), mps);

    typedef map<QString, meta_dir_node *> group_to_node_map;
    group_to_node_map gtnm;

    meta_dir_node *video_root = &m_metadata_tree;

    smart_dir_node sdn = video_root->addSubDir("All");
    meta_dir_node* all_group_node = sdn.get();

    for (metadata_view_list::iterator p = mlist.begin(); p != mlist.end(); ++p)
    {
        VideoMetadata *data = *p;

        all_group_node->addEntry(smart_meta_node(new meta_data_node(data)));

        vector<QString> groups;

        switch (whence)
        {
            case ltDBGenreGroup:
            {
                vector<pair <int, QString> > genres =
                    data->GetGenres();

                for (vector<pair <int, QString> >::iterator i =
                         genres.begin(); i != genres.end(); ++i)
                {
                    pair<int, QString> item = *i;
                    groups.push_back(item.second);
                }
                break;
            }
            case ltDBCategoryGroup:
            {
                groups.push_back(data->GetCategory());
                break;
            }
            case ltDBYearGroup:
            {
                groups.push_back(QString::number(data->GetYear()));
                break;
            }
            case ltDBDirectorGroup:
            {
                groups.push_back(data->GetDirector());
                break;
            }
            case ltDBStudioGroup:
            {
                groups.push_back(data->GetStudio());
                break;
            }
            case ltDBCastGroup:
            {
                vector<pair<int, QString> > cast = data->GetCast();

                for (vector<pair<int, QString> >::iterator i =
                         cast.begin(); i != cast.end(); ++i)
                {
                    pair<int, QString> item = *i;
                    groups.push_back(item.second);
                }
                break;
            }
            case ltDBUserRatingGroup:
            {
                int i = data->GetUserRating();
                groups.push_back(QString::number(i));
                break;
            }
            case ltDBInsertDateGroup:
            {
                QDate date = data->GetInsertdate();
                QString tmp = MythDate::toString(
                    date, MythDate::kDateFull | MythDate::kSimplify);
                groups.push_back(tmp);
                break;
            }
            default:
            {
                LOG(VB_GENERAL, LOG_ERR, "Invalid type of grouping");
                break;
            }
        }

        if (groups.empty())
        {
            meta_dir_node *group_node = gtnm["Unknown"];

            if (group_node == NULL)
            {
                smart_dir_node sdn = video_root->addSubDir("Unknown");
                group_node = sdn.get();
                gtnm["Unknown"] = group_node;
            }

            group_node->addEntry(smart_meta_node(new meta_data_node(data)));
        }

        for (vector<QString>::iterator i = groups.begin();
             i != groups.end(); ++i)
        {
            QString item = *i;

            meta_dir_node *group_node = gtnm[item];

            if (group_node == NULL)
            {
                smart_dir_node sdn = video_root->addSubDir(item);
                group_node = sdn.get();
                gtnm[item] = group_node;
            }

            group_node->addEntry(smart_meta_node(new meta_data_node(data)));
        }
    }
}