1/*
2 * Copyright 2012, Gerasim Troeglazov (3dEyes**), 3dEyes@gmail.com.
3 * All rights reserved.
4 * Distributed under the terms of the MIT License.
5 */
6
7#include <Entry.h>
8#include <Directory.h>
9#include <FindDirectory.h>
10#include <PathFinder.h>
11#include <StringList.h>
12
13#include "VSTNode.h"
14#include "VSTAddOn.h"
15
16extern "C" _EXPORT BMediaAddOn* make_media_addon(image_id image)
17{
18	return new VSTAddOn(image);
19}
20
21VSTAddOn::VSTAddOn(image_id image)
22	:
23	BMediaAddOn(image)
24{
25	fPluginsList.MakeEmpty();
26
27	BStringList folders;
28
29	BPathFinder::FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY,
30		"media/vstplugins/", B_FIND_PATH_EXISTING_ONLY, folders);
31
32	for (int32 i = 0; i < folders.CountStrings(); i++)
33		ScanPluginsFolder(folders.StringAt(i).String());
34}
35
36VSTAddOn::~VSTAddOn()
37{
38
39}
40
41status_t
42VSTAddOn::InitCheck(const char** text)
43{
44	return B_OK;
45}
46
47int32
48VSTAddOn::CountFlavors()
49{
50	return fPluginsList.CountItems();
51}
52
53status_t
54VSTAddOn::GetFlavorAt(int32 idx, const flavor_info** info)
55{
56	if (idx < 0 || idx >= fPluginsList.CountItems())
57		return B_ERROR;
58
59	VSTPlugin *plugin = (VSTPlugin*)fPluginsList.ItemAt(idx);
60
61	flavor_info *f_info = new flavor_info;
62	f_info->internal_id = idx;
63	f_info->kinds = B_BUFFER_CONSUMER | B_BUFFER_PRODUCER | B_CONTROLLABLE;
64	f_info->possible_count = 0;
65	f_info->flavor_flags = 0;
66	f_info->name = plugin->ModuleName();
67	f_info->info = plugin->Product();
68
69	media_format *format = new media_format;
70	format->type = B_MEDIA_RAW_AUDIO;
71	format->u.raw_audio = media_raw_audio_format::wildcard;
72	format->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
73
74	f_info->in_format_count = 1;
75	f_info->in_formats = format;
76
77	format = new media_format;
78	format->type = B_MEDIA_RAW_AUDIO;
79	format->u.raw_audio = media_raw_audio_format::wildcard;
80	format->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
81
82	f_info->out_format_count = 1;
83	f_info->out_formats = format;
84
85	*info = f_info;
86
87	return B_OK;
88}
89
90BMediaNode*
91VSTAddOn::InstantiateNodeFor(const flavor_info* info, BMessage* config,
92								  status_t* err)
93{
94	VSTPlugin* plugin = (VSTPlugin*)fPluginsList.ItemAt(info->internal_id);
95	VSTNode* node = new VSTNode(this, plugin->ModuleName(), plugin->Path());
96	return node;
97}
98
99int
100VSTAddOn::ScanPluginsFolder(const char* path, bool make_dir)
101{
102	BEntry ent;
103
104	BDirectory dir(path);
105	if (dir.InitCheck() != B_OK) {
106		if (make_dir == true)
107			create_directory(path, 0755);
108		return 0;
109	}
110
111	while(dir.GetNextEntry(&ent) == B_OK) {
112		BPath p(&ent);
113		if (ent.IsDirectory()) {
114			ScanPluginsFolder(p.Path());
115		} else {
116			VSTPlugin* plugin = new VSTPlugin();
117			int ret = plugin->LoadModule(p.Path());
118			if (ret == B_OK) {
119				plugin->UnLoadModule();
120				fPluginsList.AddItem(plugin);
121			} else
122				delete plugin;
123		}
124	}
125	return 0;
126}
127
128status_t
129VSTAddOn::GetConfigurationFor(BMediaNode* node, BMessage* message)
130{
131	return B_OK;
132}
133
134bool
135VSTAddOn::WantsAutoStart()
136{
137	return false;
138}
139
140status_t
141VSTAddOn::AutoStart(int count, BMediaNode** node, int32* id, bool* more)
142{
143	return B_OK;
144}
145